Перейти к содержанию

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,
  • полный заголовок ответа (т.е. первая строка ответа) для команды get memcached.

Этот размер по умолчанию равен размеру страницы, может быть 4k или 8k.

memc_ignore_client_abort

синтаксис: memc_ignore_client_abort on|off

по умолчанию: off

контекст: location

Определяет, следует ли закрывать соединение с сервером memcached, когда клиент закрывает соединение, не дожидаясь ответа.

Эта директива была впервые добавлена в релиз v0.14.

Изменения

Изменения каждой версии этого модуля можно получить из журналов изменений пакета OpenResty:

http://openresty.org/#Changes

Тестовый набор

Этот модуль поставляется с тестовым набором на основе 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.

См. также

GitHub

Вы можете найти дополнительные советы по конфигурации и документацию для этого модуля в репозитории GitHub для nginx-module-memc.