memc: Расширенная версия стандартного модуля memcached для NGINX
Установка
Вы можете установить этот модуль в любой дистрибутив на основе RHEL, включая, но не ограничиваясь:
- RedHat Enterprise Linux 7, 8, 9 и 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 и Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-memc
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-memc
Активируйте модуль, добавив следующее в начало файла /etc/nginx/nginx.conf:
load_module modules/ngx_http_memc_module.so;
Этот документ описывает nginx-module-memc v0.20, выпущенный 27 декабря 2023 года.
# GET /foo?key=dog
#
# POST /foo?key=cat
# Значение для кошки...
#
# PUT /foo?key=bird
# Значение для птицы...
#
# DELETE /foo?key=Tiger
location /foo {
set $memc_key $arg_key;
# $memc_cmd по умолчанию равен get для GET,
# add для POST, set для PUT и
# delete для метода DELETE.
memc_pass 127.0.0.1:11211;
}
# GET /bar?cmd=get&key=cat
#
# POST /bar?cmd=set&key=dog
# Моё значение для ключа "dog"...
#
# DELETE /bar?cmd=delete&key=dog
# GET /bar?cmd=delete&key=dog
location /bar {
set $memc_cmd $arg_cmd;
set $memc_key $arg_key;
set $memc_flags $arg_flags; # по умолчанию 0
set $memc_exptime $arg_exptime; # по умолчанию 0
memc_pass 127.0.0.1:11211;
}
# GET /bar?cmd=get&key=cat
# GET /bar?cmd=set&key=dog&val=animal&flags=1234&exptime=2
# GET /bar?cmd=delete&key=dog
# GET /bar?cmd=flush_all
location /bar {
set $memc_cmd $arg_cmd;
set $memc_key $arg_key;
set $memc_value $arg_val;
set $memc_flags $arg_flags; # по умолчанию 0
set $memc_exptime $arg_exptime; # по умолчанию 0
memc_cmds_allowed get set add delete flush_all;
memc_pass 127.0.0.1:11211;
}
http {
...
upstream backend {
server 127.0.0.1:11984;
server 127.0.0.1:11985;
}
server {
location /stats {
set $memc_cmd stats;
memc_pass backend;
}
...
}
}
...
# считывание флагов memcached в заголовок Last-Modified
# для ответа 304 на условный GET
location /memc {
set $memc_key $arg_key;
memc_pass 127.0.0.1:11984;
memc_flags_to_last_modified on;
}
location /memc {
set $memc_key foo;
set $memc_cmd get;
# доступ к сокету unix, на который слушает memcached
memc_pass unix:/tmp/memcached.sock;
}
Описание
Этот модуль расширяет стандартный memcached module, чтобы поддерживать почти весь ascii протокол memcached.
Он позволяет вам определить пользовательский REST интерфейс для ваших серверов memcached или получить доступ к memcached очень эффективно изнутри сервера nginx с помощью подзапросов или независимых фиктивных запросов.
Этот модуль не предполагается объединять с ядром Nginx, потому что я использовал Ragel для генерации парсеров ответов memcached (на C) для удовольствия :)
Если вы собираетесь использовать этот модуль для кэширования ответов по умолчанию, попробуйте srcache-nginx-module с этим модулем, чтобы достичь этого.
При использовании вместе с lua-nginx-module рекомендуется использовать библиотеку lua-resty-memcached вместо этого модуля, потому что первая гораздо более гибкая и экономичная по памяти.
Подключения keep-alive к серверам memcached
Вам нужен HttpUpstreamKeepaliveModule вместе с этим модулем для поддержания TCP-соединений keep-alive с вашими серверами memcached.
Вот пример конфигурации:
http {
upstream backend {
server 127.0.0.1:11211;
# пул с максимум 1024 соединениями
# и не различает серверы:
keepalive 1024;
}
server {
...
location /memc {
set $memc_cmd get;
set $memc_key $arg_key;
memc_pass backend;
}
}
}
Как это работает
Он реализует протокол TCP memcached самостоятельно, основываясь на механизме upstream. Все операции ввода-вывода являются неблокирующими.
Сам модуль не поддерживает TCP-соединения с серверами memcached между запросами, так же как и другие модули upstream. Для рабочего решения смотрите раздел Подключения keep-alive к серверам memcached.
Поддерживаемые команды Memcached
Команды хранения memcached set, add, replace, prepend и append используют $memc_key в качестве ключа, $memc_exptime в качестве времени истечения (или задержки) (по умолчанию 0), $memc_flags в качестве флагов (по умолчанию 0), чтобы построить соответствующие запросы memcached.
Если $memc_value вообще не определен, то тело запроса будет использоваться как значение для $memc_value, за исключением команд incr и decr. Обратите внимание, что если $memc_value определен как пустая строка (""), эта пустая строка все равно будет использоваться как значение.
Следующие команды memcached были реализованы и протестированы (с их параметрами, отмеченными соответствующими переменными nginx, определенными этим модулем):
get $memc_key
Извлекает значение по ключу.
location /foo {
set $memc_cmd 'get';
set $memc_key 'my_key';
memc_pass 127.0.0.1:11211;
add_header X-Memc-Flags $memc_flags;
}
Возвращает 200 OK с значением, помещенным в тело ответа, если ключ найден, или 404 Not Found в противном случае. Число flags будет установлено в переменную $memc_flags, поэтому часто желательно поместить эту информацию в заголовки ответа с помощью стандартной add_header directive.
Возвращает 502 для ERROR, CLIENT_ERROR или SERVER_ERROR.
set $memc_key $memc_flags $memc_exptime $memc_value
Чтобы использовать тело запроса в качестве значения memcached, просто избегайте установки переменной $memc_value:
# POST /foo
# моё значение...
location /foo {
set $memc_cmd 'set';
set $memc_key 'my_key';
set $memc_flags 12345;
set $memc_exptime 24;
memc_pass 127.0.0.1:11211;
}
Или позвольте переменной $memc_value содержать значение:
location /foo {
set $memc_cmd 'set';
set $memc_key 'my_key';
set $memc_flags 12345;
set $memc_exptime 24;
set $memc_value 'my_value';
memc_pass 127.0.0.1:11211;
}
Возвращает 201 Created, если сервер memcached отвечает STORED, 200 для NOT_STORED, 404 для NOT_FOUND, 502 для ERROR, CLIENT_ERROR или SERVER_ERROR.
Оригинальные ответы memcached возвращаются как тело ответа, за исключением 404 NOT FOUND.
add $memc_key $memc_flags $memc_exptime $memc_value
Похоже на команду set.
replace $memc_key $memc_flags $memc_exptime $memc_value
Похоже на команду set.
append $memc_key $memc_flags $memc_exptime $memc_value
Похоже на команду set.
Обратите внимание, что по крайней мере версия memcached 1.2.2 не поддерживает команды "append" и "prepend". По крайней мере версии 1.2.4 и более поздние версии, похоже, поддерживают эти две команды.
prepend $memc_key $memc_flags $memc_exptime $memc_value
Похоже на команду append.
delete $memc_key
Удаляет запись memcached по ключу.
location /foo {
set $memc_cmd delete;
set $memc_key my_key;
memc_pass 127.0.0.1:11211;
}
Возвращает 200 OK, если удаление прошло успешно, 404 Not Found для NOT_FOUND, или 502 для ERROR, CLIENT_ERROR или SERVER_ERROR.
Оригинальные ответы memcached возвращаются как тело ответа, за исключением 404 NOT FOUND.
delete $memc_key $memc_exptime
Похоже на delete $memc_key, за исключением того, что принимает необязательное время expiration, указанное переменной $memc_exptime.
Эта команда больше не доступна в последней версии memcached 1.4.4.
incr $memc_key $memc_value
Увеличивает существующее значение $memc_key на величину, указанную $memc_value:
location /foo {
set $memc_cmd incr;
set $memc_key my_key;
set $memc_value 2;
memc_pass 127.0.0.1:11211;
}
В предыдущем примере каждый раз, когда мы обращаемся к /foo, значение my_key увеличивается на 2.
Возвращает 200 OK с новым значением, связанным с этим ключом, в теле ответа, если успешно, или 404 Not Found, если ключ не найден.
Возвращает 502 для ERROR, CLIENT_ERROR или SERVER_ERROR.
decr $memc_key $memc_value
Похоже на incr $memc_key $memc_value.
flush_all
Помечает все ключи на сервере memcached как истекшие:
location /foo {
set $memc_cmd flush_all;
memc_pass 127.0.0.1:11211;
}
flush_all $memc_exptime
Точно так же, как flush_all, но также принимает время истечения, указанное переменной $memc_exptime.
stats
Вызывает сервер memcached выводить общие статистические данные и настройки.
location /foo {
set $memc_cmd stats;
memc_pass 127.0.0.1:11211;
}
Возвращает 200 OK, если запрос успешен, или 502 для ERROR, CLIENT_ERROR или SERVER_ERROR.
Сырой вывод команды stats от сервера memcached будет помещен в тело ответа.
Директивы
Все стандартные memcached module директивы в nginx 0.8.28 напрямую наследуются, с заменой префиксов memcached_ на memc_. Например, директива memcached_pass пишется как memc_pass.
Здесь мы документируем только две самые важные директивы (последняя — новая директива, введенная этим модулем).
memc_pass
синтаксис: memc_pass <IP-адрес сервера memcached>:<порт сервера memcached>
синтаксис: memc_pass <имя хоста сервера memcached>:<порт сервера memcached>
синтаксис: memc_pass <имя_upstream_backend>
синтаксис: memc_pass unix:<путь_к_сокету_unix>
по умолчанию: нет
контекст: http, server, location, if
фаза: content
Укажите бэкенд сервера memcached.
memc_cmds_allowed
синтаксис: memc_cmds_allowed <cmd>...
по умолчанию: нет
контекст: http, server, location, if
Перечисляет команды memcached, которые разрешены для доступа. По умолчанию все команды memcached, поддерживаемые этим модулем, доступны. Пример:
location /foo {
set $memc_cmd $arg_cmd;
set $memc_key $arg_key;
set $memc_value $arg_val;
memc_pass 127.0.0.1:11211;
memc_cmds_allowed get;
}
memc_flags_to_last_modified
синтаксис: memc_flags_to_last_modified on|off
по умолчанию: off
контекст: http, server, location, if
Считывает флаги memcached как секунды эпохи и устанавливает их как значение заголовка Last-Modified. Для условного GET это будет сигнализировать nginx вернуть ответ 304 Not Modified, чтобы сэкономить трафик.
memc_connect_timeout
синтаксис: memc_connect_timeout <время>
по умолчанию: 60s
контекст: http, server, location
Тайм-аут для подключения к серверу memcached, по умолчанию в секундах.
Рекомендуется всегда явно указывать единицу времени, чтобы избежать путаницы. Поддерживаемые единицы времени: "s"(секунды), "ms"(миллисекунды), "y"(годы), "M"(месяцы), "w"(недели), "d"(дни), "h"(часы) и "m"(минуты).
Это время должно быть меньше 597 часов.
memc_send_timeout
синтаксис: memc_send_timeout <время>
по умолчанию: 60s
контекст: http, server, location
Тайм-аут для отправки TCP-запросов на сервер memcached, по умолчанию в секундах.
Рекомендуется всегда явно указывать единицу времени, чтобы избежать путаницы. Поддерживаемые единицы времени: "s"(секунды), "ms"(миллисекунды), "y"(годы), "M"(месяцы), "w"(недели), "d"(дни), "h"(часы) и "m"(минуты).
Это время должно быть меньше 597 часов.
memc_read_timeout
синтаксис: memc_read_timeout <время>
по умолчанию: 60s
контекст: http, server, location
Тайм-аут для чтения TCP-ответов от сервера memcached, по умолчанию в секундах.
Рекомендуется всегда явно указывать единицу времени, чтобы избежать путаницы. Поддерживаемые единицы времени: "s"(секунды), "ms"(миллисекунды), "y"(годы), "M"(месяцы), "w"(недели), "d"(дни), "h"(часы) и "m"(минуты).
Это время должно быть меньше 597 часов.
memc_buffer_size
синтаксис: memc_buffer_size <размер>
по умолчанию: 4k/8k
контекст: http, server, location
Этот размер буфера используется для памяти, чтобы удерживать
- полный ответ для команд memcached, кроме
get, - полный заголовок ответа (т.е. первая строка ответа) для команды
getmemcached.
Этот размер по умолчанию равен размеру страницы, может быть 4k или 8k.
memc_ignore_client_abort
синтаксис: memc_ignore_client_abort on|off
по умолчанию: off
контекст: location
Определяет, следует ли закрывать соединение с сервером memcached, когда клиент закрывает соединение, не дожидаясь ответа.
Эта директива была впервые добавлена в релиз v0.14.
Изменения
Изменения каждой версии этого модуля можно получить из журналов изменений пакета OpenResty:
Тестовый набор
Этот модуль поставляется с тестовым набором на основе Perl. Тестовые случаи также являются декларативными. Спасибо модулю Test::Base в мире Perl.
Чтобы запустить его у себя:
$ PATH=/path/to/your/nginx-with-memc-module:$PATH prove -r t
Вам нужно завершить любые процессы Nginx перед запуском тестового набора, если вы изменили двоичный файл сервера Nginx.
Либо LWP::UserAgent, либо IO::Socket используется тестовой основой.
Поскольку один сервер nginx (по умолчанию, localhost:1984) используется во всех тестовых скриптах (.t файлы), бессмысленно запускать тестовый набор параллельно, указывая -jN при вызове утилиты prove.
Вам также следует поддерживать сервер memcached, слушающий на порту 11211 на localhost перед запуском тестового набора.
Некоторые части тестового набора требуют, чтобы модули rewrite и echo были включены при сборке Nginx.
См. также
- Оригинальное объявление по электронной почте в списке рассылки nginx: ngx_memc: "расширенная версия ngx_memcached, которая поддерживает set, add, delete и многие другие команды"
- Мои слайды, демонстрирующие различные способы использования ngx_memc: http://agentzh.org/misc/slides/nginx-conf-scripting/nginx-conf-scripting.html#34 (используйте стрелки или клавиши pageup/pagedown на клавиатуре для переключения страниц)
- Последний TCP-протокол memcached.
- Модуль ngx_srcache
- Библиотека lua-resty-memcached, основанная на API cosocket lua-nginx-module.
- Стандартный memcached модуль.
- Модуль echo module для автоматического тестирования модулей Nginx.
- Стандартный headers модуль и сторонний модуль headers-more.
GitHub
Вы можете найти дополнительные советы по конфигурации и документацию для этого модуля в репозитории GitHub для nginx-module-memc.