Мем кэш что это
Этим постом хочу открыть небольшую серию постов по материалам доклада на HighLoad++-2008. Впоследствии весь текст будет опубликован в виде одной большой PDF-ки.
5 последних уроков рубрики "PHP"
Фильтрация данных с помощью zend-filter
Когда речь идёт о безопасности веб-сайта, то фраза "фильтруйте всё, экранируйте всё" всегда будет актуальна. Сегодня поговорим о фильтрации данных.
Контекстное экранирование с помощью zend-escaper
Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак. В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.
Подключение Zend модулей к Expressive
Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение. В этой статье мы расскажем как улучшили процесс подключение нескольких модулей.
Совет: отправка информации в Google Analytics через API
Подборка PHP песочниц
Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.
Как настроить memcached с помощью плагина Cachify
Введите в строку поиска плагинов: «Cachify» и нажмите Установить:
Нажмите Активировать:
Готово, в блоке Настройки ― Cachify можно сделать все необходимые настройки:
Перейдите в раздел Общие настройки во вкладку «Система»:
Пролистайте страницу до блока «Настройки кэша» и установите следующие настройки:
- Обработчик кэширования: Memcache;
- Защита Memcache(d): Да;
- Сжатие Memcache: Нет;
- Сервер Memcache(d): localhost;
- Порт Memcache(d)-сервера: ваш уникальный порт, полученный в панели управления;
- Срок кэширования: 15;
- Специфическое кэширование для платформы: Нет;
- Системный кэш: Стандартное кэширование.
Нажмите Сохранить в левом верхнем углу экрана.
В панели управления хостингом в корневой папке сайта откройте файл «bitrix/php_interface/dbconn.php» и со второй строки добавьте:
Сегодня я представлю вам небольшой фрагмент кода, который научит вас взаимодействовать с Memcache. Для того чтобы установить Mediatemple на хостинге вам необходимы данные для SSH.
Как включить memcached
Чтобы включить memcached:
Перейдите в раздел «Memcached». При первой настройке нажмите Ok и вы получите ваш уникальный порт memcached-сервера:
Отмеченный порт (в примере: 11217) нужно указывать в настройках подключения к memcached-серверу. В качестве адреса сервера используйте 127.0.0.1. (localhost).
Готово, вы настроили memcached для вашей услуги хостинга и можете его использовать в ваших проектах.
What it Does
memcached allows you to take memory from parts of your system where you have more than you need and make it accessible to areas where you have less than you need.
memcached also allows you to make better use of your memory. If you consider the diagram to the right, you can see two deployment scenarios:
- Each node is completely independent (top).
- Each node can make use of memory from other nodes (bottom).
The first scenario illustrates the classic deployment strategy, however you'll find that it's both wasteful in the sense that the total cache size is a fraction of the actual capacity of your web farm, but also in the amount of effort required to keep the cache consistent across all of those nodes.
With memcached, you can see that all of the servers are looking into the same virtual pool of memory. This means that a given item is always stored and always retrieved from the same location in your entire web cluster.
Also, as the demand for your application grows to the point where you need to have more servers, it generally also grows in terms of the data that must be regularly accessed. A deployment strategy where these two aspects of your system scale together just makes sense.
The illustration to the right only shows two web servers for simplicity, but the property remains the same as the number increases. If you had fifty web servers, you'd still have a usable cache size of 64MB in the first example, but in the second, you'd have 3.2GB of usable cache.
Of course, you aren't required to use your web server's memory for cache. Many memcached users have dedicated machines that are built to only be memcached servers.
Общая схема кэширования
В общем случае схема кэширования выглядит следующим образом: frontend’у (той части проекта, которая формирует ответ пользователю) требуется получить данные какой-то выборки. Frontend обращается к быстрому как гепард серверу memcached за кэшом выборки (get-запрос). Если соответствующий ключ будет обнаружен, работа на этом заканчивается. В противном случае следует обращение к тяжелому, неповоротливому, но мощному (как слон) backend’у, в роли которого чаще всего выступает база данных. Полученный результат сразу же записывается в memcached в качестве кэша (set-запрос). При этом обычно для ключа задается максимальное время жизни (срок годности), который соответствует моменту сброса кэша.
Такая стандартная схема кэширования реализуется всегда. Вместо memcached в некоторых проектах могут использоваться локальные файлы, иные способы хранения (другая БД, кэш PHP-акселератора и т.п.) Однако, как будет показано далее, в высоконагруженном проекте данная схема может работать не самым эффективным образом. Тем не менее, в нашем дальнейшем рассказе мы будем опираться именно на эту схему.
Установка и настройка
В качестве рассматриваемого дистрибутива я решил использовать Debian, потому как он наиболее часто используется при создании web-серверов. Модуль Memcached для PHP доступен в репозитории уже скомпилированным (php5-memcached), но я опишу процесс установки из исходного кода, так как не все репозитории настолько богаты, как дебиановский.
Устанавливаем сервер Memcached
Проверяем
Компилируем и устанавливаем модуль для PHP
apt-get install php5-dev libmemcache-dev
pecl download memcache
tar xzvf memcache-2.2.6.tgz
cd memcache-2.2.6 /
phpize && . / configure --enable-memcache && make
cp modules / memcache.so / usr / lib / php5 / 20060613 /
echo 'extension=memcache.so' >> / etc / php5 / apache2 / php.ini
/ etc / init.d / apache2 restart
Что такое Memcache?
Ну что, интересно стало? Memcache является универсальной системой распределения кэшированных элементов. Если в кэше ничего нет, то делается запрос к базе и результаты записываются в Memcache:
Memcache предоставляет 5 функций:
- get() – извлекает значение по ключу
- set() – устанавливает значение
- add() – добавляет кэш, если его не существует
- replace() – заменяет кэш
- flush() – удаляет все закэшированные данные
Если вы установили у себя Memcache, то вы можете начать им пользоваться. Существует мнение, что много кэша это плохо. Я с этим абсолютно не согласен! Чем быстрее грузится ваш сайт – тем лучше!
- Первые две строки производят подключение к Memcache.
- Далее следует скрипт подключения к базе данных.
- Потом создаём ключ. Когда мы хотим поместить данные в Memcache, то нам необходимо передать 3 элемента для вставки: ключ, значение и время жизни кэша. Ключ необходим для получения доступа к данным. В этом примере вы можете увидеть, что я использую в качестве ключа MD5 хэш запроса.
- Дальше мы проверяем существует ли кэш. Проверка вернёт нам true или false. Если он есть, получаем к нему доступ.
- Если кэша нет, то мы подключаемся к базе и достаём значения. Для создания кэша используем следующее выражение: $memcache->set($key, $row, TRUE, 20); $row хранит массив того, что мы достали из базы. 20 это время жизни в кэша в секундах.
Это самый простой пример использования memcache, но я надеюсь, это был хороший старт для вас.
Как настроить memcached с помощью плагина WP-FFPC
В строку поиска плагинов введите «WP-FFPC» и нажмите Установить:
Перейдите во вкладку Backend settings и в поле «Hosts» введите: 127.0.0.1:ваш уникальный порт, полученный в панели управления. Затем нажмите Save Changes:
В панели управления хостингом в корневой папке сайта откройте файл «wp-config.php». Добавьте строку в указанном на скриншоте месте:
define ( 'WP_CACHE', true );
Нажмите Сохранить:
Принцип локальности
Кэш или подход кэширования мы встречаем повсюду в электронных устройствах, архитектуре программного обеспечения: кэш ЦП (первого и второго уровня), буферы жесткого диска, кэш операционной системы, буфер в автомагнитоле. Чем же определяется такой успех кэширования? Ответ лежит в принципе локальности: программе, устройству свойственно в определенный промежуток времени работать с некоторым подмножеством данных из общего набора. В случае оперативной памяти это означает, что если программа работает с данными, находящимися по адресу 100, то с большей степенью вероятности следующее обращение будет по адресу 101, 102 и т.п., а не по адресу 10000, например. То же самое с жестким диском: его буфер наполняется данными из областей, соседних по отношению к последним прочитанным секторам, если бы наши программы работали в один момент времени не с некоторым относительно небольшим набором файлов, а со всем содержимым жесткого диска, буферы были бы бессмысленны. Буфер автомагнитолы совершает упреждающее чтение с диска следующих минут музыки, потому что мы, скорее всего, будем слушать музыкальный файл последовательно, чем перескакивать по набору музыки и т.п.
В случае web-проектов успех кэширования определяется тем, что на сайте есть всегда наиболее популярные страницы, некоторые данные используются на всех или почти на всех страницах, то есть существуют некоторые выборки, которые оказываются затребованы гораздо чаще других. Мы заменяем несколько обращений к backend’у на одно обращения для построения кэша, а затем все последующие обращения будет делать через быстро работающий кэш.
Кэш всегда лучше, чем исходный источник данных: кэш ЦП на порядки быстрее оперативной памяти, однако мы не можем сделать оперативную память такой же быстрой, как кэш – это экономически неэффективно и технически сложно. Буфер жесткого диска удовлетворяет запросы за данными на порядки быстрее самого жесткого диска, однако буфер не обладает свойством запоминать данные при отключении питания – в этом смысле он хуже самого устройства. Аналогичная ситуация и с кэшированием в Web’е: кэш быстрее и эффективнее, чем backend, однако он обычно в случае перезапуска или падения сервера не может сохранить данные, а также не обладает логикой по вычислению каких-либо результатов: он умеет возвращать лишь то, что мы ранее в него положили.
Memcached
Memcached представляет собой огромную хэш-таблицу в оперативной памяти, доступную по сетевому протоколу. Он обеспечивает сервис по хранению значений, ассоциированных с ключами. Доступ к хэшу мы получаем через простой сетевой протокол, клиентом может выступать программа, написанная на произвольном языке программирования (существуют клиенты для C/C++, PHP, Perl, Java и т.п.).
Самые простые операции – получить значение указанного ключа (get), установить значение ключа (set) и удалить ключ (del). Для реализации цепочки атомарных операций (при условии конкурентного доступа к memcached со стороны параллельных процессов) используются дополнительные операции: инкремент/декремент значения ключа (incr/decr), дописать данные к значению ключа в начало или в конец (append/prepend), атомарная связка получения/установки значения (gets/cas) и другие.
Memcached был реализован Брэдом Фитцпатриком (Brad Fitzpatrick) в рамках работы над проектом ЖЖ (LiveJournal). Он использовался для разгрузки базы данных от запросов при отдаче контента страниц. Сегодня memcached нашел своё применение в ядре многих крупных проектов, например, Wikipedia, YouTube, Facebook и другие.
Кто использует Memcache?
Архитектура memcached
Каким же образом устроен memcached? Как ему удаётся работать настолько быстро, что даже десятки запросов к memcached, необходимых для обработки одной страницы сайта, не приводят к существенной задержке. При этом memcached крайне нетребователен к вычислительным ресурсам: на нагруженной инсталляции процессорное время, использованное им, редко превышает 10%.
Во-первых, memcached спроектирован так, чтобы все его операции имели алгоритмическую сложность O(1), т.е. время выполнения любой операции не зависит от количества ключей, которые хранит memcached. Это означает, что некоторые операции (или возможности) будут отсутствовать в нём, если их реализация требует всего лишь линейного (O(n)) времени. Так, в memcached отсутствуют возможность объединения ключей «в папки», т.е. какой-либо группировки ключей, также мы не найдем групповых операций над ключами или их значениями.
Основными оптимизированными операциями является выделение/освобождение блоков памяти под хранение ключей, определение политики самых неиспользуемых ключей (LRU) для очистки кэша при нехватке памяти. Поиск ключей происходит через хэширование, поэтому имеет сложность O(1).
Используется асинхронный ввод-вывод, не используются нити, что обеспечивает дополнительный прирост производительности и меньшие требования к ресурсам. На самом деле memcached может использовать нити, но это необходимо лишь для использования всех доступных на сервере ядер или процессоров в случае слишком большой нагрузки – на каждое соединение нить не создается в любом случае.
По сути, можно сказать, что время отклика сервера memcached определяется только сетевыми издержками и практически равно времени передачи пакета от frontend’а до сервера memcached (RTT). Такие характеристики позволяют использовать memcached в высоконагруженных web-проектов для решения различных задач, в том числе и для кэширования данных.
Потеря ключей
Memcached не является надежным хранилищем – возможна ситуация, когда ключ будет удален из кэша раньше окончания его срока жизни. Архитектура проекта должна быть готова к такой ситуации и должна гибко реагировать на потерю ключей. Можно выделить три основных причины потери ключей:
- Ключ был удален раньше окончания его срока годности в силу нехватки памяти под хранение значений других ключей. Memcached использует политику LRU, поэтому такая потеря означает, что данный ключ редко использовался и память кэша освобождается для хранения более популярных ключей.
- Ключ был удален, так как истекло его время жизни. Такая ситуация строго говоря не является потерей, так как мы сами ограничили время жизни ключа, но для клиентского по отношению к memcached кода такая потеря неотличима от других случаев – при обращении к memcached мы получаем ответ «такого ключа нет».
- Самой неприятной ситуацией является крах процесса memcached или сервера, на котором он расположен. В этой ситуации мы теряем все ключи, которые хранились в кэше. Несколько сгладить последствия позволяет кластерная организация: множество серверов memcached, по которым «размазаны» ключи проекта: так последствия краха одного кэша будут менее заметны.
Все описанные ситуации необходимо иметь в виду при разработке программного обеспечения, работающего с memcached. Можно разделить данные, которые мы храним в memcached, по степени критичности их потери.
«Можно потерять». К этой категории относятся кэши выборок из базы данных. Потеря таких ключей не так страшна, потому что мы можем легко восстановить их значения, обратившись заново к backend’у. Однако частые потери кэшей приводят к излишним обращениям к БД.
«Совсем не должны терять». Memcached удобен для хранения сессий пользователей – все сессии равнодоступны со всех серверов, входящих в кластер frontend’ов. Так вот содержимое сессий не хотелось бы терять никогда – иначе пользователей на сайте будет «разлогинивать». Как попытаться избежать? Можно дублировать ключи сессий на нескольких серверах memcached из кластера, так вероятность потери снижается.
Memcache разработан для кэширования данных, генерация которых требует большого количества ресурсов. Такого рода данные могут содержать что угодно, начиная с результатов запроса к базе данных и заканчивая тяжеловесным куском шаблона. Memcached не входит в базовый набор модулей, поставляемых с PHP, однако он доступен в репозитории pecl.
About Memcached
memcached is a high-performance, distributed memory object caching system, generic in nature, but originally intended for use in speeding up dynamic web applications by alleviating database load.
You can think of it as a short-term memory for your applications.
Введение
Для начала, о названии серии постов: посты будут и о кэшировании в Web’е (в высоконагруженных Web-проектах), и о применении memcached для кэширования, и о других применениях memcached в Web-проектах. То есть все три составляющие названия в различных комбинациях будут освещены в этой серии постов.
Кэширование сегодня является неотъемлемой частью любого Web-проекта, не обязательно высоконагруженного. Для каждого ресурса критичной для пользователя является такая характеристика, как время отклика сервера. Увеличение времени отклика сервера приводит к оттоку посетителей. Следовательно, необходимо минимизировать время отклика: для этого необходимо уменьшать время, требуемое на формирование ответа пользователю, а ответ пользователю требует получить данные из каких-то внешних ресурсов (backend). Этими ресурсами могут быть как базы данных, так и любые другие относительно медленные источники данных (например, удаленный файловый сервер, на котором мы уточняем количество свободного места). Для генерации одной страницы достаточно сложного ресурса нам может потребоваться совершить десятки подобных обращений. Многие из них будут быстрыми: 20 мс и меньше, однако всегда существует некоторое небольшое количество запросов, время вычисления которых может исчисляться секундами или минутами (даже в самой оптимизированной системе один могут быть, хотя их количество должно быть минимально). Если сложить всё то время, которое мы затратим на ожидание результатов запросов (если же мы будем выполнять запросы параллельно, то возьмем время вычисления самого долгого запроса), мы получим неудовлетворительное время отклика.
Решением этой задачи является кэширование: мы помещаем результат вычислений в некоторое хранилище (например, memcached), которое обладает отличными характеристиками по времени доступа к информации. Теперь вместо обращений к медленным, сложным и тяжелым backend’ам нам достаточно выполнить запрос к быстрому кэшу.
Contributors
Memcached — сервер, который позволяет хранить в оперативной памяти кэш CMS. Подключив CMS к memcached-серверу, вы ускорите работу вашего сайта. Более подробно кэширование memcached освещено на официальном сайте.
Мощные VIP-тарифы хостинга
Высокая скорость работы, надёжность и быстрые SSD — подберите подходящий VIP-тариф и оцените все его преимущества. В течение 14 дней вы можете протестировать любой из них бесплатно!
Origin
Memcached was originally developed by Brad Fitzpatrick for LiveJournal in 2003.
Использование memcached на примере популярных CMS
Рассмотрим настройку memcached в трёх популярных CMS (WordPress, Joomla и Bitrix).
Memcached на WordPress можно настроить с помощью плагинов. В этой статье мы рассмотрим плагины WP-FFPC и Cachify.
Memcached и кэширование
Примеры использования
1. Базовые операции
- //Создаём новый объект. Также можно писать и в процедурном стиле
- $memcache_obj = new Memcache ;
- //Соединяемся с нашим сервером
- $memcache_obj -> connect ( '127.0.0.1' , 11211 ) or die ( «Could not connect» ) ;
- //Попытаемся получить объект с ключом our_var
- $var_key = @ $memcache_obj -> get ( 'our_var' ) ;
- if ( ! empty ( $var_key ) )
- //Если объект закэширован, выводим его значение
- echo $var_key ;
- >
- else
- //Если в кэше нет объекта с ключом our_var, создадим его
- //Объект our_var будет храниться 5 секунд и не будет сжат
- $memcache_obj -> set ( 'our_var' , date ( 'G:i:s' ) , false , 5 ) ;
- //Выведем закэшированные данные
- echo $memcache_obj -> get ( 'our_var' ) ;
- >
- //Закрываем соединение с сервером Memcached
- $memcache_obj -> close ( ) ;
- ?>
В результате выполнения этого кода каждый раз будет выводиться время с точностью до секунд. Однако обновляться оно будет раз в 5 секунд, пока не очистится кэш. В данном примере проиллюстрированы самые простые операции, но в производительности мы скорее потеряем, чем выиграем. Ведь нам каждый раз придётся подключаться к серверу…
2. Повышаем производительность
2.1 С кэшированием
- < ? php
- function LoadCPU ( )
- //Функция, которая должна зугрузить процессор
- //Создадим изображение 800x600
- $image = imagecreate ( 800 , 600 ) ;
- //Белый фоновый цвет
- $color = imagecolorallocate ( $image, 255 , 255 , 255 ) ;
- //Чёрный
- $color2 = imagecolorallocate ( $image, 0 , 0 , 0 ) ;
- for ( $i = 0 ; $i < 10000 ; $i ++ )
- //Расставим 10 000 точек в случайном порядке
- imagesetpixel ( $image, rand ( 0 , 800 ) , rand ( 0 , 600 ) , $color2 ) ;
- >
- //Выбрасываем указатель
- return $image ;
- >
- //Создаём новый объект Memcache
- $memcache_obj = new Memcache ;
- //Соединяемся с нашим сервером
- $memcache_obj - > connect ( '127.0.0.1' , 11211 ) or die ( "Could not connect" ) ;
- //Попытаемся получить объект с ключом image
- $image_bin = @$memcache_obj - > get ( 'image' ) ;
- if ( empty ( $image_bin ) )
- //Если в кэше нет картинки, сгенерируем её и закэшируем
- imagepng ( LoadCPU ( ) ,getcwd ( ) . '/tmp.jpg' , 9 ) ;
- $image_bin = file_get_contents ( getcwd ( ) . '/tmp.jpg' ) ;
- unlink ( getcwd ( ) . '/tmp.jpg' ) ;
- $memcache_obj - > set ( 'image' , $image_bin, false , 30 ) ;
- >
- //Выведем картинку из кэша
- header ( 'Content-type: image/png' ) ;
- echo $image_bin ;
- //Закрываем соединение с сервером Memcached
- $memcache_obj - > close ( ) ;
- ? >
В данном примере приведена функция, которая создаёт изображение размером 800x600 и расставляет на нём 10 000 точек. Один раз, сгенерировав такое изображение, в дальнейшем мы лишь выводим его на экран, не генерируя заново.
2.2 Без кэширования
- function LoadCPU ( )
- //Функция, которая должна загрузить процессор
- //Создадим изображение 800x600
- $image = imagecreate ( 800 , 600 ) ;
- //Белый фоновый цвет
- $color = imagecolorallocate ( $image , 255 , 255 , 255 ) ;
- //Чёрный
- $color2 = imagecolorallocate ( $image , 0 , 0 , 0 ) ;
- for ( $i = 0 ; $i < 10000 ; $i ++ )
- //Расставим 10 000 точек в случайном порядке
- imagesetpixel ( $image , rand ( 0 , 800 ) , rand ( 0 , 600 ) , $color2 ) ;
- >
- //Выбрасываем указатель
- return $image ;
- >
- //Выводим изображение, не кэшируя
- header ( 'Content-type: image/png' ) ;
- imagepng ( LoadCPU ( ) , '' , 9 ) ;
- ?>
Тут всё гораздо проще и привычней: генерируем изображение каждый раз заново.
Результаты
Ещё несколько полезных функций
addServer — в случае, если у вас в распоряжении несколько кэширующих серверов, вы можете создать некий кластер, добавляя сервера в пул. Следует обратить внимание на параметр weight. Он указывает на то, сколько памяти вам будет доступно на конкретном сервере.
delete — из названия понятно, что данный метод удаляет из кэша объект с заданным ключом.
replace — заменяет значение объекта с заданным ключом. Используйте в случае, если Вам понадобится изменить содержимое объекта, раньше чем истечёт время его жизни.
С моей точки зрения, применять кэширование стоит только на высоконагруженных ресурсах. Ведь каждый раз, подключаясь к серверу Memcached, вы тратите драгоценное время, что скорее всего не будет оправданным. Что касается больших проектов, лучше сразу написать больше строк кода, чем потом делать это в попыхах, с мыслью о том, что ваш сервис лежит. Также не стоит забывать о расходовании памяти! Учтите, что положив 300 мегабайт в кэш, вы отняли у себя 300 мегабайт ОЗУ.
В завершение хочу сказать, что данная статья не раскрывает все прелести технологии, однако я надеюсь, что она стимулирует Вас к самосовершенствованию. Спасибо за прочтение, многоуважаемый %username%!
UPD: Ещё один интересный момент. Memcached, есть PHP API к libmemcached. А Memcache, библиотека для php, не использующая libmemcached.
Читайте также: