Что такое memcache?
Решение кэша в среде кластера Memcache
Memcache-это высокопроизводительная система кеша объектов распределенной памяти. Поддерживая унифицированную и огромную хэш -таблицу в памяти, ее можно использовать для хранения данных в различных форматах, включая изображения, видео, файлы и результаты поиска базы данных. Проще говоря, он должен вызвать данные в память, а затем прочитать их по памяти, тем самым значительно улучшив скорость чтения.
Memcache - это проект в Данге. Впервые это служил живым джурнаном. Первоначально он был разработан, чтобы ускорить скорость доступа Live Journal. Позже это было принято многими большими сайтами.
Memcached работает на одном или нескольких серверах в режиме демона и в любое время получает клиентские подключения и операции.
Почему два имени MEMCACHE и MEMCACHED?
Фактически, Memcache является именем этого проекта, а Memcached является основным именем файла программы на его стороне сервера. Если вы понимаете, о чем я. Одним из них является имя проекта, а другое - основное имя файла программы. Я видел это в Интернете, что многие люди не понимают этого, поэтому я смешал это.
Memcached представляет собой высокопроизводительную систему кэширования объектов с распределенным объектом памяти, используемая для снижения нагрузки базы данных и улучшения скорости доступа в динамических приложениях. Memcached разработан Danga Interactive для улучшения доступа к LiveJournal.com. У LJ тысячи динамических посещений страниц в секунду и 7 миллионов пользователей. Memcached значительно уменьшает нагрузку в базе данных, лучше выделяет ресурсы и более быстрый доступ.
Эта статья будет охватывать следующее:
Memcache
Memcache-это хранилище ключевых значений в памяти для небольших кусков произвольных данных (строк, объектов) из результатов баз данных, вызовов API или рендеринга страниц.
То есть база данных кэша в памяти, которая является базой данных пары клавиш. Существует база данных для временного хранения данных, полученных от других служб в памяти, и может быть возвращена непосредственно из кэша HIT при повторных доступах. Это не только ускоряет скорость доступа, но также уменьшает нагрузку на другие услуги. Здесь будет реализована одно серверная версия Memcache и поддерживает одновременные соединения между несколькими клиентами.
Клиент установит соединение Telnet с сервером, а затем взаимодействует с кэшем сервера в соответствии с протоколом Memcache. Инструкции, реализованные здесь, Get, Set и Del. Давайте посмотрим на формат каждой инструкции
набор
Набор - это инструкция хранения. При хранении характеристик инструкции введите базовую информацию в первой строке и введите его соответствующее значение во второй строке.
SET <CEOE> <Glags> <pextime> <bytes> [noreply]/r/n
<значение>/r/n
Если хранилище будет успешным, сохранение будет возвращено, и если директива содержит атрибут noreply, сервер не вернет информацию.
Содержание каждого домена в этой директиве следующее:
Если инструкция не соответствует критериям, сервер вернет ошибку.
получать
GET - это команда GET, и характеристики этой команды следующие:
Получить <ключ>*/r/n
Он поддерживает прохождение значений нескольких ключей. Если кэш попадает в один или несколько ключей, соответствующие данные будут возвращены и заканчиваются концом. Если удара не будет сделан, возвращаемое сообщение не содержит значение, соответствующее ключу. Формат заключается в следующем:
Значение <ключ> <Glags> <bytes>/r/n <block>/r/nvalue <key> <walls> <bytes>/r/n <block>/r/nenddel
Удалить команду, формат команды заключается в следующем:
del <Key> [noreply]/r/n
Если удаление будет успешным, он вернет удаленную/r/n, в противном случае оно вернется not_found. Если есть параметр noreply, сервер не вернет ответ.
Java Docket
Все, что нужно знать Java Socket, - это протокол TCP, розетки и потоки IO. Я не буду вдаваться в подробности здесь. Вы можете обратиться к моей серии статей. Также рекомендуется прочитать программы сети Java. Книга.
Реализация кода
Здесь что -то не так с функцией карты. Вы можете перейти по адресу моего проекта в конце статьи, чтобы просмотреть диаграмму классов.
Здесь режим инструкции и заводской режим используются для реализации развязки создания и выполнения инструкций. Командная фабрика получит командную линию и вернет экземпляр команды. Каждая команда имеет метод выполнения для выполнения собственных уникальных операций. Здесь размещена только специальная реализация инструкции DEL.
/** * Различные директивы * В настоящее время поддерживает get, set, delete * * и custom * error, end */public interface Command {/** * Execute Command * @param Reader * @param writer */void execute (Reader Reader, Writer Writer); / *** Получить тип команды* @return*/ commandType getType ();} /*** Один экземпляр директивной фабрики*/public Class CommandFactory {private Static CommandFactory CommandFactory; Частный статический кеш <пункт> memcache; private CommandFactory () {} public Static CommandFactory getInstance (cache <Item> cache) {if (commandFactory == null) {commandFactory = new CommandFactory (); memcache = cache; } return CommandFactory; } / ** * Получить команду в соответствии с типом директивы * @param Commandline * @return * / public getCommand (String Commandline) {if (commandline.matches ("^set. * $")) {Return new SetCommand (commandline, memcache); } else if (commandline.matches ("^get.*$")) {return new getCommand (commandline, memcache); } else if (commandline.matches ("^del.*$")) {return new DeleteCommand (commandline, memcache); } else if (commandline.matches ("^end $")) {return new endCommand (commandline); } else {return new errorCommand (Commandline, errorCommand.errortype.error); }}} /*** Удалить директивность кэша*/public Class DeleteCommand реализует команду {Private Final String Command; Частный финальный кеш <пункт> кэш; частный ключ строки; Частный логический разрыв; public deleteCommand (команда окончательной строки, окончательный кэш <пункт> cache) {this.command = command; this.cache = cache; initCommand (); } private void initCommand () {if (this.command.contains ("noreply")) {noreply = true; } String [] info = command.split (""); key = info [1]; } @Override public void Execute (Reader Reader, Writer Writer) {BufferedWriter BFW = (BufferedWriter) Writer; Item item = cache.delete (key); if (! noreply) {try {if (item == null) {bfw.write ("not_found/r/n"); } else {bfw.write ("deleted/r/n"); } bfw.flush (); } catch (ioException e) {try {bfw.write ("error/r/n"); bfw.flush (); } catch (ioException e1) {e1.printstacktrace (); } e.printstacktrace (); }}} @Override public CommandType getType () {return CommandType.search; }}Затем реализуйте сервер памяти. Чтобы поддержать функцию первой в первой форме, в качестве основной реализации используется LinkedTriemap, а метод RemoeLodest переписывается. В то же время фоновый поток Cachemanager также используется для очистки истекших записей кеша во времени.
Общедоступный класс Memcache реализует Cache <Item> {private logger logger = logger.getLogger (memcache.class.getName ()); // Использование LinkedHashmap для реализации LRU Private Static LinkedHashmap <String, Item> Cache; Частный финал int maxsize; // коэффициент загрузки частный окончательный float default_load_factor = 0,75F; public memcache (final int maxsize) {this.maxsize = maxsize; // Убедитесь, что кэш не будет автоматически расширяться после достижения maxSize int емкость = (int) math.ceil (maxSize /default_load_factor) + 1; this.cache = new LinkedHashmap <String, item> (емкость, default_load_factor, true) {@override защищенное логическое removeeLeantrestentry (map.entry <string, item> aldest) {if (size ()> maxsize) {logger.info («номер CACH } return size ()> maxSize; }}; // реализовать Synchronized Access Collections.synchronizedMap (cache); } public synchronized boolean isfull () {return cache.size ()> = maxsize; } @Override public item get (string key) {item = cache.get (key); if (item == null) {logger.info ("Ключ в кэше:" + key + "не существует"); вернуть ноль; } else if (item! = null && item.isexpired ()) {// Если кэш истекает, удалите и возвращайте null logger.info ("Читать клавишу из кэша:" + key + "value:" + item.getValue () + "истек срок действия"); cache.remove (key); вернуть ноль; } logger.info ("Читать клавишу с cache:" + key + "value:" + item.getValue () + "Остальное действительное время" + item.remaintime ()); вернуть элемент; } @Override public void set (string клавиша, значение элемента) {logger.info ("wript work to cache:" + key + "value:" + value); cache.put (ключ, значение); } @Override public itemled (string key) {logger.info ("Удалить клавишу из cache:" + key); вернуть cache.remove (key); } @Override public int size () {return cache.size (); } @Override public intipt () {return maxSize; } @Override public iterator <map.Entry <string, item >> iterator () {return cache.EntrySet (). Iterator (); }} /*** Cache Manager* Фоновый поток* Удалить кэш истечь в кэше*/открытый класс CacheManager реализует runnable {private logger logger = logger.getlogger (cachemanager.class.getName ()); // cache public cache <Item> cache; public cachemanager (cache <Item> cache) {this.cache = cache; } @Override public void run () {while (true) {iterator <map.entry <string, item >> itemiterator = cache.iterator (); while (itemiterator.hasnext ()) {map.entry <string, item> intent = itemiterator.next (); Item item = entry.getValue (); if (item.isexpired ()) {logger.info ("key:" + entry.getKey () + "value" + item.getValue () + "Срок действия, удаленная из базы данных"); itemiterator.remove (); }} try {// запустить фоновую программу каждые 5 секунд TimeUnit.seconds.sleep (5); } catch (прерванное искусство e) {e.printstacktrace (); }}}}Наконец, реализуйте многопоточный сервер сокетов, где Serversocket связан с интерфейсом и передайте принятый сокет дополнительным потокам для обработки.
/*** Сервер*/Общедоступный класс ioserver реализует Server {Private Boolean Stop; // номер порта частный окончательный порт int; // Серверная потока Private Serversocket Serversocket; Private Final Logger logger = logger.getLogger (ioserver.class.getName ()); // Пул потоков, емкость потока является MaxConnection Private Final ExecutorService executorservice; Частный финальный кеш <пункт> кэш; public ioserver (int port, int maxconnection, cache <Item> cache) {if (maxconnection <= 0). Выбросить новое allosalargumentException («максимальное количество поддерживаемых соединений должно быть положительным целым числом»); this.port = порт; executorservice = executors.newfixedthreadpool (maxconnection); this.cache = cache; } @Override public void start () {try {serversocket = new ServerSocket (port); logger.info ("Сервер начинается с порта"+port+"); while (true) {try {socket socket = serversocketocket.accept (); logger.info (" Получил соединение "+socket.getlocaladdress ()+" "); executorservice.submit (new Sockethandler (socket, cache); e.printstacktrace (); ! serversocke.iscolode (); /*** Обработка подключений каждого клиента* Закройте соединение после получения конечной инструкции S*/Public Class Sockethandler реализует runnable {private Static Logger logger = logger.getLogger (sockethandler.class.getName ()); частная финальная розетка; Частный финальный кеш <пункт> кэш; частная логическая отделка; public sockethandler (ocket s, cache <item> cache) {this.socket = s; this.cache = cache; } @Override public void run () {try {// Get Socket входной поток Final BufferedRead Reader = new BufferedReader (New InputStreamReader (socket.getInputStream ())); // Получить выходной поток выходного потока CommandFactory CommandFactory = commandFactory.getInstance (cache); while (! finish) {final String commandline = reader.readline (); logger.info ("ip:" + socket.getlocaladdress () + "Директива:" + commandline); if (commandline == null || commandline.trim (). isempty ()) {продолжить; } // Использование заводской команды, чтобы получить экземпляр команды Команда Команда команды = commandFactory.getCommand (commandline); command.execute (читатель, писатель); if (command.getType () == commandType.end) {logger.info ("запрос на закрытие соединения"); Finish = true; }}} catch (ioException e) {e.printstacktrace (); logger.info («Закройте соединение из« + socket.getlocaladdress () + »»); } наконец {try {if (socket! = null) {socket.close (); }} catch (ioException e) {e.printstacktrace (); }}}}Пожалуйста, нажмите здесь для адреса проекта. Если вы думаете, что это довольно хорошо, я надеюсь, что вы сможете дать мне звезду.
Ссылки
Memcached Официальный сайт
Протокол MEMCACHE
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.