Memcached и Grails. Часть 1: Установка и применение memcached

Команды memcached и оценка производительности кэша

В этой первой части статьи, посвященной memcached и Grails, Джеймс Гудвилл рассказывает об открытом решении для кэширования — memcached. В статье затрагиваются такие темы, как установка, конфигурирование, команды клиента memcached и оценка эффективности кэша. В отличие от статей об использовании memcached с клиентом, связанным со спецификой конкретного языка, в этой статье особое внимание уделяется прямому взаимодействию с сервером memcached с целью предоставить все необходимые средства для контроля своего экземпляра memcached, а также подготовить вас ко второй половине статьи, где будет описана интеграция memcached в приложение Grails.

Джеймс Гудвилл, Application Architect, Evite.com

James GoodwillДжеймс Гудвилл (James Goodwill) — хорошо известный автор и специалист по технологиям, живет в районе Скалистых гор в Соединенных Штатах. Основное внимание он уделяет масштабированию Web-приложений на Java и Grails. Среди его публикаций: Developing Java Servlets, Mastering Jakarta Struts и Mastering JSP Custom Tags and Tag Libraries.



02.11.2011

memcached— это распределенная система общего назначения для кэширования данных в памяти. Она разработана компанией Danga Interactive и распространяется под лицензией BSD.

Компания Danga Interactive разработала memcached, столкнувшись с отсутствием системы кэширования в памяти, способной справиться с большим трафиком на сайте компании — LiveJournal.com. Более 20 миллионов просмотров страниц в день представляли огромную нагрузку на базы данных LiveJournal, поэтому Брэд Фицпатрик (Brad Fitzpatrick) из Danga предложил memcached. Применение memcached снизило нагрузку на базы данных этого сайта, а теперь это решение для кэширования используется на многих web-сайтах со значительной нагрузкой по всему миру.

В этой статье сначала будет дан обзор memcached, а затем поэтапно рассмотрен процесс её установки и сборки из исходных текстов в вашей среде разработки. Также вы познакомитесь с командами клиента memcached (их всего девять) и узнаете, как их использовать для стандартных и расширенных операций memcached. В завершение приводится пара приемов для использования команд memcached для измерения производительности и эффективности кэша.

Место memcached в вашей среде

Прежде чем разбираться с установкой и использованием memcached, давайте поговорим немного о том, как memcached может вписаться в вашу среду. Хотя memcached можно использовать где и сколько угодно, я нашел ее наиболее полезной при выполнении нескольких долговременных запросов на уровне базы данных. Зачастую я устанавливаю несколько экземпляров memcached между своими серверами баз данных и серверами приложений и следую простой модели чтения и записи на каждом из этих серверов. Схема на рисунке 1 должна дать представление о настройке архитектуры приложений:

Рисунок 1. Пример архитектуры приложений с memcached
Пример архитектуры приложений с memcached

Эта архитектура очень проста. Имеется Web-слой, куда входят мои экземпляры Apache. Следующий слой — это само приложение. Чаще всего оно работает на Apache Tomcat или каком-нибудь другом сервере приложений с открытым исходным кодом. Следующий слой содержит мои настроенные экземпляры memcached между серверами приложений и серверами баз данных. При использовании конфигурации такого типа чтение и запись в базу данных выполняются немного по-разному.

Чтение

Последовательность, которой я следую при выполнении чтения, такова: берётся запрос (для которого требуется сделать опрос базы данных) с Web-уровня и кэш проверяется на ранее сохраненные результаты этого запроса. Если я нахожу значение, которое ищу, я возвращаю его. Если нет, то я выполняю запрос и сохраняю результаты в кэше, прежде чем вернуть их на Web-уровень.

Запись

При выполнении записи в базу данных сначала необходимо выполнить запись в базу данных, а затем аннулировать все ранее сохраненные результаты, которые будут затронуты этой записью. Эта процедура помогает предотвратить расхождение данных между кэшем и базой данных.

Установка memcached

memcached поддерживает несколько операционных систем, включая Linux®, Windows®, Mac OS и Solaris. В этой статье мы последовательно пройдёмся по всем этапам сборки и установки memcached из исходного кода. Мне нравится собирать из исходных кодов, главным образом потому, что при возникновении каких-то вопросов у меня есть возможность посмотреть на исходный код.

libevent

Единственная зависимость memcached — это libevent, асинхронная библиотека оповещения о событиях. Исходные тексты libevent можно найти на monkey.org. Берите самую свежую версию. В этой статье используется стабильная версия 1.4.11. Получив архив, распакуйте его в подходящее место и выполните команды, приведенные в листинге 1:

Листинг 1. Сборка и установка libevent
cd libevent-1.4.11-stable/

./configure
			
make
				
make install

memcached

Найдите исходные тексты memcached на Danga Interactive, снова выбрав самую свежую версию. На время написания этой статьи последней была версия 1.4.0. Распакуйте архив tar.gz в удобное место и выполните команды из листинга 2:

Листинг 2. Сборка и установка memcached
cd memcached-1.4.0/

./configure
			
make
				
make install

После этого у вас должна быть установлена и готова к использованию рабочая копия memcached. Давайте запустим ее и поэкспериментируем.

Использование memcached

Чтобы начать использовать memcached, необходимо, во-первых, запустить сервер memcached, а затем подключиться с помощью клиента telnet.

Для запуска memcached выполняем команду из листинга 3:

Листинг 3. Запуск memcached
./memcached -d -m 2048 -l 10.0.0.40 -p 11211

Эта команда запускает memcached в режиме демона (-d) с 2 ГБ памяти (-m 2048), который слушает localhost или порт 11211. Эти значения можно изменить в соответствии с потребностями, но для наших упражнений они хорошо подходят. Следующий шаг — подключение к memcached. Мы подключимся к серверу memcached с помощью простого клиента telnet.

В большинстве операционных систем имеются встроенные клиенты telnet, но если вы используете что-то на основе Windows, вам потребуется загрузить клиент стороннего разработчика. Я рекомендую PuTTy.

После установки клиента telnet выполните команду из листинга 4:

Листинг 4. Подключение к memcached
telnet localhost 11211

Если все прошло хорошо, вы должны получить ответ: Connected to localhost. В противном случае вернитесь назад и убедитесь, что исходные тексты для libevent и memcached были собраны без ошибок.

Теперь мы на сервере memcached. С этого момента с memcached можно общаться с помощью ряда простых команд. Девять клиентских команд memcached можно разбить на три категории:

  • Базовые
  • Расширенные
  • Управление

Базовые команды клиента memcached

Пять базовых команд memcached применяются для простейших операций. Вот эти команды и операции:

  • set
  • add
  • replace
  • get
  • delete

Первые три команды — это стандартные команды для внесения изменений, применяемые для манипулирования парами ключ/значение, хранящимися в memcached. Они довольно просты и имеют общий синтаксис, приведенный в листинге 5:

Листинг 5. Синтаксис модифицирующих команд
command <key> <flags> <expiration time> <bytes>
<value>

В таблице 1 дается определение параметров модифицирующих команд memcached и их использование.

Таблица 1. Параметры модифицирующих команд memcached
ПараметрИспользование
keyКлюч, используемый для поиска кэшированного значения
flagsЦелочисленный параметр, сопровождающий пару ключ/значение; используется клиентом для хранения дополнительной информации о паре ключ/значение
expiration timeПродолжительность времени в секундах, в течение которого пара ключ/значение должна храниться в кэше (0 — бесконечное время)
bytesКоличество байт, которое будет храниться в кэше
valueХранящееся значение (всегда на второй строке)

Теперь давайте посмотрим на эти команды в действии.

set
Команда set добавляет новую пару ключ/значение в кэш. Если этот ключ уже существует, предыдущее значение будет замещено.

Обратим внимание на следующее взаимодействие с использованием команды set:

set userId 0 0 5
12345
STORED

Если операция set для пары ключ/значение выполнена успешно, сервер ответит STORED (сохранено). В этом примере в кэш добавлена пара ключ/значение с ключом userId и значением 12345. Время окончания действия установлено в 0, это говорит memcached о том, что значение будет храниться в кэше, пока вы его не удалите.

add
Команда add добавляет в кэш новую пару ключ/значение только в случае, если ключа еще нет в кэше. Если ключ уже существует, предыдущее значение не изменится и вы получите ответ NOT_STORED(не сохранено).

Вот стандартное взаимодействие с помощью команды add:

set userId 0 0 5
12345
STORED

add userId 0 0 5
55555
NOT_STORED

add companyId 0 0 3
564
STORED

replace
Команда replace замещает пару ключ/значение в кэше только в случае, если этот ключ уже существует. Если ключа еще нет в кэше, вы получите от сервера memcached ответ NOT_STORED (не сохранено).

Вот стандартное взаимодействие с использованием команды replace:

replace accountId 0 0 5
67890
NOT_STORED

set accountId 0 0 5
67890
STORED

replace accountId 0 0 5
55555
STORED

Последними базовыми командами являются get и delete. Значение их вполне очевидно, и синтаксис также сходный:

command <key>

Давайте посмотрим на эти команды в действии.

get
Команда get используется для извлечения значения, связанного с ранее добавленной парой ключ/значение. Команда get используется для большинства операций получения данных.

Вот типичное взаимодействие с использованием команды get:

set userId 0 0 5
12345
STORED

get userId
VALUE userId 0 5
12345
END

get bob
END

Как видим, команда get довольно проста. get вызывается с ключом, и если этот ключ существует в кэше, будет возвращено значение. В противном случае ничего возвращаться не будет.

delete
Последняя базовая команда —delete. Команда delete используется для удаления любых существующих значений в memcached. Команда delete вызывается с ключом, и если этот ключ существует в кэше, значение будет удалено. В противном случае будет возвращено сообщение NOT_FOUND (не найдено).

Вот взаимодействие клиент-сервер с помощью команды delete:

set userId 0 0 5
98765
STORED

delete bob
NOT_FOUND

delete userId
DELETED

get userId
END

Расширенные команды клиента memcached

Две расширенные команды, которые можно использовать с memcached, — это gets и cas. Команды gets и cas предназначены для совместного использования. Эти команды используются вместе, чтобы гарантировать, что существующая пара имя/значение не получит нового значения, если это значение уже обновлено. Давайте взглянем на каждую из этих команд.

gets
Функции команды gets во многом схожи с функциями базовой команды get Разница между этими двумя командами состоит в том, что gets возвращает дополнительный элемент информации: 64-разрядное целое, которое выступает в качестве идентификатора "версии" пары имя/значение.

Вот клиент-серверное взаимодействие с использованием команды gets:

set userId 0 0 5
12345
STORED

get userId
VALUE userId 0 5
12345
END

gets userId
VALUE userId 0 5 4
12345
END

Рассмотрим различия между командами get и gets. Команда gets вернула дополнительное значение — в данном случае целочисленное значение 4, которое идентифицирует пару имя/значение. Если выполнить еще одну команду set на этой паре имя/значение, дополнительное значение, возвращаемое gets, изменится, что означает, что пара имя/значение была обновлена. В листинге 6 приводится пример:

Листинг 6. Команда set обновляет спецификатор версии
set userId 0 0 5
33333
STORED

gets userId
VALUE userId 0 5 5
33333
END

Посмотрите на последнее значение, возвращенное командой gets. Оно было изменено на 5. Это значение будет меняться каждый раз при изменении пары имя/значение.

cas
cas (проверить и установить) — это удобная команда memcached, которая устанавливает значение пары имя/значение только в случае, если эта пара имя/значение не обновлялась с момента последнего выполнения команды gets. У нее схожий с командой set синтаксис, но добавлено одно дополнительное значение — то же самое, которое возвращает gets.

Обратите внимание на следующее взаимодействие с использованием команды cas:

set userId 0 0 5
55555
STORED

gets userId
VALUE userId 0 5 6
55555
END

cas userId 0 0 5 6
33333
STORED

Как видите, я использовал команду gets с дополнительным целым 6, и операция отлично выполнилась. Теперь взгляните на последовательность команд в листинге 7:

Листинг 7. Команда cas со старым спецификатором версии
set userId 0 0 5
55555
STORED

gets userId
VALUE userId 0 5 8
55555
END

cas userId 0 0 5 6
33333
EXISTS

Обратите внимание, что я не использовал самое последнее целое, полученное от gets, и cas завершилась неудачно, возвратив значение EXISTS (существует). Фактически совместное использование команд gets и cas не позволяет "наступить" на пару имя/значение, которая была обновлена с момента последнего чтения.

Команды управления кэшем

Две последние команды memcached используются для контроля и очистки экземпляра memcached. Это команды stats и flush_all.

stats
Команда stats делает в точности то, что отражает её название: выдает текущую статистику экземпляра memcached, к которому вы подключились. В следующем примере выполнения команд stats показывается следующая информация о текущем экземпляре memcached:

stats
STAT pid 63
STAT uptime 101758
STAT time 1248643186
STAT version 1.4.11
STAT pointer_size 32
STAT rusage_user 1.177192
STAT rusage_system 2.365370
STAT curr_items 2
STAT total_items 8
STAT bytes 119
STAT curr_connections 6
STAT total_connections 7
STAT connection_structures 7
STAT cmd_get 12
STAT cmd_set 12
STAT get_hits 12
STAT get_misses 0
STAT evictions 0
STAT bytes_read 471
STAT bytes_written 535
STAT limit_maxbytes 67108864
STAT threads 4
END

Здесь большинство выходных данных довольно понятны. Смысл этих значений я раскрою более подробно далее в статье, во время обсуждения производительности кэша. А пока что посмотрите на выходные данные и запустите несколько команд set с новыми ключами, а затем снова запустите команду stats, обращая внимания на изменения.

flush_all
flush_all— это последняя команда memcached, которую нам нужно выучить. Эта простейшая команда просто удаляет все пары имя/значение из кэша. flush_all может быть очень полезна, если нужно очистить кэш. Вот пример применения flush_all:

set userId 0 0 5
55555
STORED

get userId
VALUE userId 0 5
55555
END

flush_all
OK

get userId
END

Производительность кэша

Мы завершим статью уроком по применению расширенных команд memcached для получения сведений о том, насколько хорошо работает кэш. Команда stats неоценима в настройке работы кэша. Две из самых важных статистических характеристик, за которыми нужно следить, — это get_hits и get_misses. Эти значения показывают, сколько раз пара имя/значение была найдена (get_hits), и сколько раз не найдена (get_misses).

Сочетание этих значений может показать, насколько эффективно используется кэш. Когда кэш только начинает работу, значение get_misses обычно растет, но после какого-то количества обращений число, возвращаемое get_misses, должно снижаться — что показывает, что кэш заполняется наиболее употребительными чтениями. Если окажется, что get_misses продолжает быстро расти, а get_hits выравнивается, нужно посмотреть на то, что вы кэшируете. Возможно, что кэшируется что-то ненужное.

Еще один метод определения эффективности кэширования состоит в том, чтобы взглянуть на коэффициент попаданий в кэш. Этот коэффициент сообщает процентное отношение числа выполнения команд get к количеству раз, когда get не находит значения. Чтобы определить это соотношение, вновь выполните команду stats, как показано в листинге 8:

Листинг 8. Вычисление коэффициента попаданий в кэш
stats
STAT pid 6825
STAT uptime 540692
STAT time 1249252262
STAT version 1.2.6
STAT pointer_size 32
STAT rusage_user 0.056003
STAT rusage_system 0.180011
STAT curr_items 595
STAT total_items 961
STAT bytes 4587415
STAT curr_connections 3
STAT total_connections 22
STAT connection_structures 4
STAT cmd_get 2688
STAT cmd_set 961
STAT get_hits 1908
STAT get_misses 780
STAT evictions 0
STAT bytes_read 5770762
STAT bytes_written 7421373
STAT limit_maxbytes 536870912
STAT threads 1
END

Теперь возьмите значение get_hits и разделите его на значение cmd_gets. В этом примере коэффициент равен примерно 71 проценту. В идеале хотелось бы иметь намного более высокий процент — чем больше, тем лучше. Наблюдение за этой статистикой и измерение этих данных с течением времени продемонстрирует эффективность вашей стратегии кэширования.

Заключение к части 1

Кэширование является неотъемлемой частью любого «тяжёлого» web-приложения, и memcached — прекрасный выбор. Я лично много раз добивался успеха, используя ее. Выбрав memcached в качестве решения для кэширования, вы наверняка убедитесь в её эффективности.

Во второй части этой статьи мы рассмотрим интеграцию memcached в Grails-приложение. Это предоставит нам возможность изучить отличный и надежный комплекс инструментов для разработки масштабируемых web-приложений и заняться действительно увлекательной работой. А пока содержимое этой статьи является отличной отправной точкой для дальнейшего освоения memcached. Я рекомендую вам установить свой собственный экземпляр memcached и поэкспериментировать.

Ресурсы

Научиться

Получить продукты и технологии

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Технология Java, Open source
ArticleID=769253
ArticleTitle=Memcached и Grails. Часть 1: Установка и применение memcached
publish-date=11022011