Saltar a contenido

memc: Versión extendida del módulo memcached estándar de NGINX

Instalación

Puedes instalar este módulo en cualquier distribución basada en RHEL, incluyendo, pero no limitado a:

  • RedHat Enterprise Linux 7, 8, 9 y 10
  • CentOS 7, 8, 9
  • AlmaLinux 8, 9
  • Rocky Linux 8, 9
  • Amazon Linux 2 y 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

Habilita el módulo añadiendo lo siguiente en la parte superior de /etc/nginx/nginx.conf:

load_module modules/ngx_http_memc_module.so;

Este documento describe nginx-module-memc v0.20 lanzado el 27 de diciembre de 2023.


 # GET /foo?key=dog
 #
 # POST /foo?key=cat
 # Valor del gato...
 #
 # PUT /foo?key=bird
 # Valor del pájaro...
 #
 # DELETE /foo?key=Tiger
 location /foo {
     set $memc_key $arg_key;

     # $memc_cmd por defecto es get para GET,
     #   add para POST, set para PUT, y
     #   delete para el método de solicitud DELETE.

     memc_pass 127.0.0.1:11211;
 }
 # GET /bar?cmd=get&key=cat
 #
 # POST /bar?cmd=set&key=dog
 # Mi valor para la clave "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; # por defecto es 0
     set $memc_exptime $arg_exptime; # por defecto es 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; # por defecto es 0
     set $memc_exptime $arg_exptime; # por defecto es 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;
         }
         ...
     }
   }
   ...
 # leer las flags de memcached en el encabezado Last-Modified
 # para responder 304 a GET condicional
 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;

     # acceder al socket de dominio unix escuchado por memcached
     memc_pass unix:/tmp/memcached.sock;
 }

Descripción

Este módulo extiende el módulo memcached estándar para soportar casi todo el protocolo ascii de memcached.

Te permite definir una interfaz REST personalizada para tus servidores memcached o acceder a memcached de una manera muy eficiente desde dentro del servidor nginx mediante subsolicitudes o solicitudes falsas independientes.

Este módulo no está destinado a ser fusionado en el núcleo de Nginx porque he utilizado Ragel para generar los analizadores de respuesta de memcached (en C) por diversión :)

Si vas a utilizar este módulo para almacenar en caché las respuestas de ubicación de forma predeterminada, prueba srcache-nginx-module junto con este módulo para lograrlo.

Cuando se utiliza en conjunto con lua-nginx-module, se recomienda utilizar la biblioteca lua-resty-memcached en lugar de este módulo, ya que la primera es mucho más flexible y eficiente en memoria.

Conexiones keep-alive a servidores memcached

Necesitas HttpUpstreamKeepaliveModule junto con este módulo para conexiones TCP keep-alive a tus servidores memcached de backend.

Aquí tienes una configuración de ejemplo:

   http {
     upstream backend {
       server 127.0.0.1:11211;

       # un grupo con un máximo de 1024 conexiones
       # y no distinguir los servidores:
       keepalive 1024;
     }

     server {
         ...
         location /memc {
             set $memc_cmd get;
             set $memc_key $arg_key;
             memc_pass backend;
         }
     }
   }

Cómo funciona

Implementa el protocolo TCP de memcached por sí mismo, basado en el mecanismo upstream. Todo lo que involucra I/O es no bloqueante.

El módulo en sí no mantiene conexiones TCP a los servidores memcached de upstream entre solicitudes, al igual que otros módulos de upstream. Para una solución funcional, consulta la sección Conexiones keep-alive a servidores memcached.

Comandos de Memcached soportados

Los comandos de almacenamiento de memcached set, add, replace, prepend, y append utilizan el $memc_key como la clave, $memc_exptime como el tiempo de expiración (o retraso) (por defecto es 0), $memc_flags como las flags (por defecto es 0), para construir las consultas correspondientes de memcached.

Si $memc_value no está definido en absoluto, entonces el cuerpo de la solicitud se utilizará como el valor de $memc_value, excepto para los comandos incr y decr. Ten en cuenta que si $memc_value se define como una cadena vacía (""), esa cadena vacía seguirá siendo utilizada como el valor tal cual.

Los siguientes comandos de memcached han sido implementados y probados (con sus parámetros marcados por las correspondientes variables nginx definidas por este módulo):

get $memc_key

Recupera el valor utilizando una clave.

   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;
   }

Devuelve 200 OK con el valor puesto en el cuerpo de la respuesta si se encuentra la clave, o 404 Not Found de lo contrario. El número de flags se establecerá en la variable $memc_flags, por lo que a menudo es deseable poner esa información en los encabezados de respuesta mediante la directiva estándar add_header.

Devuelve 502 para ERROR, CLIENT_ERROR, o SERVER_ERROR.

set $memc_key $memc_flags $memc_exptime $memc_value

Para utilizar el cuerpo de la solicitud como el valor de memcached, simplemente evita establecer la variable $memc_value:

   # POST /foo
   # mi valor...
   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;
   }

O deja que $memc_value contenga el valor:

   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;
   }

Devuelve 201 Created si el servidor memcached de upstream responde STORED, 200 para NOT_STORED, 404 para NOT_FOUND, 502 para ERROR, CLIENT_ERROR, o SERVER_ERROR.

Las respuestas originales de memcached se devuelven como el cuerpo de la respuesta, excepto para 404 NOT FOUND.

add $memc_key $memc_flags $memc_exptime $memc_value

Similar al comando set.

replace $memc_key $memc_flags $memc_exptime $memc_value

Similar al comando set.

append $memc_key $memc_flags $memc_exptime $memc_value

Similar al comando set.

Ten en cuenta que al menos la versión 1.2.2 de memcached no soporta los comandos "append" y "prepend". Al menos las versiones 1.2.4 y posteriores parecen soportar estos dos comandos.

prepend $memc_key $memc_flags $memc_exptime $memc_value

Similar al comando append.

delete $memc_key

Elimina la entrada de memcached utilizando una clave.

   location /foo {
       set $memc_cmd delete;
       set $memc_key my_key;

       memc_pass 127.0.0.1:11211;
   }

Devuelve 200 OK si se elimina correctamente, 404 Not Found para NOT_FOUND, o 502 para ERROR, CLIENT_ERROR, o SERVER_ERROR.

Las respuestas originales de memcached se devuelven como el cuerpo de la respuesta, excepto para 404 NOT FOUND.

delete $memc_key $memc_exptime

Similar al comando delete $memc_key excepto que acepta un tiempo de expiration opcional especificado por la variable $memc_exptime.

Este comando ya no está disponible en la última versión de memcached 1.4.4.

incr $memc_key $memc_value

Incrementa el valor existente de $memc_key por la cantidad especificada por $memc_value:

   location /foo {
       set $memc_cmd incr;
       set $memc_key my_key;
       set $memc_value 2;
       memc_pass 127.0.0.1:11211;
   }

En el ejemplo anterior, cada vez que accedemos a /foo, el valor de my_key se incrementará en 2.

Devuelve 200 OK con el nuevo valor asociado a esa clave como el cuerpo de la respuesta si tiene éxito, o 404 Not Found si no se encuentra la clave.

Devuelve 502 para ERROR, CLIENT_ERROR, o SERVER_ERROR.

decr $memc_key $memc_value

Similar a incr $memc_key $memc_value.

flush_all

Marca todas las claves en el servidor memcached como expiradas:

   location /foo {
       set $memc_cmd flush_all;
       memc_pass 127.0.0.1:11211;
   }

flush_all $memc_exptime

Al igual que flush_all pero también acepta un tiempo de expiración especificado por la variable $memc_exptime.

stats

Hace que el servidor memcached emita estadísticas y configuraciones de propósito general.

   location /foo {
       set $memc_cmd stats;
       memc_pass 127.0.0.1:11211;
   }

Devuelve 200 OK si la solicitud tiene éxito, o 502 para ERROR, CLIENT_ERROR, o SERVER_ERROR.

La salida cruda del comando stats del servidor memcached de upstream se pondrá en el cuerpo de la respuesta.

Directivas

Todas las directivas estándar del módulo memcached en nginx 0.8.28 se heredan directamente, con los prefijos memcached_ reemplazados por memc_. Por ejemplo, la directiva memcached_pass se escribe como memc_pass.

Aquí solo documentamos las dos directivas más importantes (la última es una nueva directiva introducida por este módulo).

memc_pass

syntax: memc_pass <dirección IP del servidor memcached>:<puerto del servidor memcached>

syntax: memc_pass <nombre del servidor memcached>:<puerto del servidor memcached>

syntax: memc_pass <nombre_backend_upstream>

syntax: memc_pass unix:<ruta_al_socket_de_dominio_unix>

default: ninguno

context: http, server, location, if

phase: content

Especifica el backend del servidor memcached.

memc_cmds_allowed

syntax: memc_cmds_allowed <cmd>...

default: ninguno

context: http, server, location, if

Lista los comandos de memcached que están permitidos para acceder. Por defecto, todos los comandos de memcached soportados por este módulo son accesibles. Un ejemplo es:

    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

syntax: memc_flags_to_last_modified on|off

default: off

context: http, server, location, if

Lee las flags de memcached como segundos desde la época y las establece como el valor del encabezado Last-Modified. Para GET condicional, señalará a nginx que devuelva la respuesta 304 Not Modified para ahorrar ancho de banda.

memc_connect_timeout

syntax: memc_connect_timeout <tiempo>

default: 60s

context: http, server, location

El tiempo de espera para conectarse al servidor memcached, en segundos por defecto.

Es prudente siempre especificar explícitamente la unidad de tiempo para evitar confusiones. Las unidades de tiempo soportadas son "s" (segundos), "ms" (milisegundos), "y" (años), "M" (meses), "w" (semanas), "d" (días), "h" (horas), y "m" (minutos).

Este tiempo debe ser menor a 597 horas.

memc_send_timeout

syntax: memc_send_timeout <tiempo>

default: 60s

context: http, server, location

El tiempo de espera para enviar solicitudes TCP al servidor memcached, en segundos por defecto.

Es prudente siempre especificar explícitamente la unidad de tiempo para evitar confusiones. Las unidades de tiempo soportadas son "s" (segundos), "ms" (milisegundos), "y" (años), "M" (meses), "w" (semanas), "d" (días), "h" (horas), y "m" (minutos).

Este tiempo debe ser menor a 597 horas.

memc_read_timeout

syntax: memc_read_timeout <tiempo>

default: 60s

context: http, server, location

El tiempo de espera para leer respuestas TCP del servidor memcached, en segundos por defecto.

Es prudente siempre especificar explícitamente la unidad de tiempo para evitar confusiones. Las unidades de tiempo soportadas son "s" (segundos), "ms" (milisegundos), "y" (años), "M" (meses), "w" (semanas), "d" (días), "h" (horas), y "m" (minutos).

Este tiempo debe ser menor a 597 horas.

memc_buffer_size

syntax: memc_buffer_size <size>

default: 4k/8k

context: http, server, location

Este tamaño de buffer se utiliza para el buffer de memoria para contener

  • la respuesta completa para comandos de memcached distintos de get,
  • el encabezado de respuesta completo (es decir, la primera línea de la respuesta) para el comando get de memcached.

Este tamaño predeterminado es el tamaño de página, puede ser 4k o 8k.

memc_ignore_client_abort

syntax: memc_ignore_client_abort on|off

default: off

context: location

Determina si la conexión con un servidor memcached debe cerrarse cuando un cliente cierra una conexión sin esperar una respuesta.

Esta directiva se agregó por primera vez en la versión v0.14.

Cambios

Los cambios de cada lanzamiento de este módulo se pueden obtener de los registros de cambios del paquete OpenResty:

http://openresty.org/#Changes

Suite de Pruebas

Este módulo viene con una suite de pruebas impulsada por Perl. Los casos de prueba son también declarativos. Gracias al módulo Test::Base en el mundo de Perl.

Para ejecutarlo en tu lado:

 $ PATH=/path/to/your/nginx-with-memc-module:$PATH prove -r t

Necesitas terminar cualquier proceso de Nginx antes de ejecutar la suite de pruebas si has cambiado el binario del servidor Nginx.

Tanto LWP::UserAgent como IO::Socket son utilizados por el esqueleto de prueba.

Debido a que un solo servidor nginx (por defecto, localhost:1984) se utiliza en todos los scripts de prueba (.t), no tiene sentido ejecutar la suite de pruebas en paralelo especificando -jN al invocar la utilidad prove.

También debes mantener un servidor memcached escuchando en el puerto 11211 en localhost antes de ejecutar la suite de pruebas.

Algunas partes de la suite de pruebas requieren que los módulos rewrite y echo estén habilitados también al construir Nginx.

Véase También

GitHub

Puedes encontrar consejos de configuración adicionales y documentación para este módulo en el repositorio de GitHub para nginx-module-memc.