Pular para conteúdo

memc: Versão estendida do módulo padrão memcached do NGINX

Instalação

Você pode instalar este módulo em qualquer distribuição baseada em RHEL, incluindo, mas não se limitando a:

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

Ative o módulo adicionando o seguinte no topo de /etc/nginx/nginx.conf:

load_module modules/ngx_http_memc_module.so;

Este documento descreve o nginx-module-memc v0.20 lançado em 27 de dezembro de 2023.


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

     # $memc_cmd padrão é get para GET,
     #   add para POST, set para PUT, e
     #   delete para o método de requisição DELETE.

     memc_pass 127.0.0.1:11211;
 }
 # GET /bar?cmd=get&key=cat
 #
 # POST /bar?cmd=set&key=dog
 # Meu valor para a chave "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; # padrão é 0
     set $memc_exptime $arg_exptime; # padrão é 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; # padrão é 0
     set $memc_exptime $arg_exptime; # padrão é 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;
         }
         ...
     }
   }
   ...
 # lê os flags do memcached no cabeçalho Last-Modified
 # para responder 304 a um 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;

     # acessa o socket de domínio unix escutado pelo memcached
     memc_pass unix:/tmp/memcached.sock;
 }

Descrição

Este módulo estende o módulo padrão memcached para suportar quase todo o protocolo ascii do memcached.

Ele permite que você defina uma interface REST personalizada para seus servidores memcached ou acesse o memcached de maneira muito eficiente dentro do servidor nginx por meio de subrequisições ou requisições falsas independentes.

Este módulo não deve ser mesclado ao núcleo do Nginx porque eu usei Ragel para gerar os analisadores de resposta do memcached (em C) para alegria :)

Se você vai usar este módulo para armazenar em cache as respostas de localização prontamente, experimente o srcache-nginx-module com este módulo para alcançar isso.

Quando usado em conjunto com o lua-nginx-module, é recomendado usar a biblioteca lua-resty-memcached em vez deste módulo, pois a primeira é muito mais flexível e eficiente em termos de memória.

Conexões keep-alive para servidores memcached

Você precisa do HttpUpstreamKeepaliveModule junto com este módulo para conexões TCP keep-alive com seus servidores memcached de backend.

Aqui está uma configuração de exemplo:

   http {
     upstream backend {
       server 127.0.0.1:11211;

       # um pool com no máximo 1024 conexões
       # e não distingue os servidores:
       keepalive 1024;
     }

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

Como funciona

Ele implementa o protocolo TCP do memcached por conta própria, com base no mecanismo upstream. Tudo que envolve I/O é não bloqueante.

O módulo em si não mantém conexões TCP com os servidores memcached upstream entre requisições, assim como outros módulos upstream. Para uma solução funcional, veja a seção Conexões keep-alive para servidores memcached.

Comandos memcached suportados

Os comandos de armazenamento do memcached set, add, replace, prepend e append usam o $memc_key como a chave, $memc_exptime como o tempo de expiração (ou atraso) (padrão é 0), $memc_flags como os flags (padrão é 0), para construir as consultas correspondentes do memcached.

Se $memc_value não estiver definido, o corpo da requisição será usado como o valor de $memc_value, exceto para os comandos incr e decr. Note que se $memc_value for definido como uma string vazia (""), essa string vazia ainda será usada como o valor.

Os seguintes comandos do memcached foram implementados e testados (com seus parâmetros marcados pelas variáveis nginx correspondentes definidas por este módulo):

get $memc_key

Recupera o valor usando uma chave.

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

Retorna 200 OK com o valor colocado no corpo da resposta se a chave for encontrada, ou 404 Not Found caso contrário. O número flags será definido na variável $memc_flags, então é frequentemente desejável colocar essa informação nos cabeçalhos de resposta por meio da diretiva padrão add_header.

Retorna 502 para ERROR, CLIENT_ERROR ou SERVER_ERROR.

set $memc_key $memc_flags $memc_exptime $memc_value

Para usar o corpo da requisição como o valor do memcached, basta evitar definir a variável $memc_value:

   # POST /foo
   # meu 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;
   }

Ou deixe o $memc_value conter o 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;
   }

Retorna 201 Created se o servidor memcached upstream responder STORED, 200 para NOT_STORED, 404 para NOT_FOUND, 502 para ERROR, CLIENT_ERROR ou SERVER_ERROR.

As respostas originais do memcached são retornadas como o corpo da resposta, exceto para 404 NOT FOUND.

add $memc_key $memc_flags $memc_exptime $memc_value

Semelhante ao comando set.

replace $memc_key $memc_flags $memc_exptime $memc_value

Semelhante ao comando set.

append $memc_key $memc_flags $memc_exptime $memc_value

Semelhante ao comando set.

Note que pelo menos a versão 1.2.2 do memcached não suporta os comandos "append" e "prepend". Pelo menos as versões 1.2.4 e posteriores parecem suportar esses dois comandos.

prepend $memc_key $memc_flags $memc_exptime $memc_value

Semelhante ao comando append.

delete $memc_key

Deleta a entrada do memcached usando uma chave.

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

       memc_pass 127.0.0.1:11211;
   }

Retorna 200 OK se deletado com sucesso, 404 Not Found para NOT_FOUND, ou 502 para ERROR, CLIENT_ERROR ou SERVER_ERROR.

As respostas originais do memcached são retornadas como o corpo da resposta, exceto para 404 NOT FOUND.

delete $memc_key $memc_exptime

Semelhante ao comando delete $memc_key, exceto que aceita um tempo de expiração opcional especificado pela variável $memc_exptime.

Este comando não está mais disponível na versão mais recente do memcached 1.4.4.

incr $memc_key $memc_value

Incrementa o valor existente de $memc_key pela quantidade 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;
   }

No exemplo anterior, cada vez que acessamos /foo, o valor de my_key é incrementado em 2.

Retorna 200 OK com o novo valor associado a essa chave como corpo da resposta se bem-sucedido, ou 404 Not Found se a chave não for encontrada.

Retorna 502 para ERROR, CLIENT_ERROR ou SERVER_ERROR.

decr $memc_key $memc_value

Semelhante ao incr $memc_key $memc_value.

flush_all

Marca todas as chaves no servidor memcached como expiradas:

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

flush_all $memc_exptime

Assim como flush_all, mas também aceita um tempo de expiração especificado pela variável $memc_exptime.

stats

Faz com que o servidor memcached exiba estatísticas e configurações de uso geral.

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

Retorna 200 OK se a requisição for bem-sucedida, ou 502 para ERROR, CLIENT_ERROR ou SERVER_ERROR.

A saída bruta do comando stats do servidor memcached upstream será colocada no corpo da resposta.

Diretivas

Todas as diretivas padrão do módulo memcached no nginx 0.8.28 são herdadas diretamente, com os prefixos memcached_ substituídos por memc_. Por exemplo, a diretiva memcached_pass é escrita como memc_pass.

Aqui documentamos apenas as duas diretivas mais importantes (a última é uma nova diretiva introduzida por este módulo).

memc_pass

syntax: memc_pass <endereço IP do servidor memcached>:<porta do servidor memcached>

syntax: memc_pass <nome do servidor memcached>:<porta do servidor memcached>

syntax: memc_pass <nome_do_backend_upstream>

syntax: memc_pass unix:<caminho_para_socket_de_dominio_unix>

default: nenhum

context: http, server, location, if

phase: content

Especifica o backend do servidor memcached.

memc_cmds_allowed

syntax: memc_cmds_allowed <cmd>...

default: nenhum

context: http, server, location, if

Lista os comandos do memcached que são permitidos para acesso. Por padrão, todos os comandos do memcached suportados por este módulo são acessíveis. Um exemplo é:

    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

Lê os flags do memcached como segundos desde a época e os define como o valor do cabeçalho Last-Modified. Para GET condicional, isso sinaliza ao nginx para retornar a resposta 304 Not Modified para economizar largura de banda.

memc_connect_timeout

syntax: memc_connect_timeout <tempo>

default: 60s

context: http, server, location

O tempo limite para conectar ao servidor memcached, em segundos por padrão.

É prudente sempre especificar explicitamente a unidade de tempo para evitar confusões. As unidades de tempo suportadas são "s" (segundos), "ms" (milissegundos), "y" (anos), "M" (meses), "w" (semanas), "d" (dias), "h" (horas) e "m" (minutos).

Esse tempo deve ser inferior a 597 horas.

memc_send_timeout

syntax: memc_send_timeout <tempo>

default: 60s

context: http, server, location

O tempo limite para enviar requisições TCP ao servidor memcached, em segundos por padrão.

É prudente sempre especificar explicitamente a unidade de tempo para evitar confusões. As unidades de tempo suportadas são "s" (segundos), "ms" (milissegundos), "y" (anos), "M" (meses), "w" (semanas), "d" (dias), "h" (horas) e "m" (minutos).

Esse tempo deve ser inferior a 597 horas.

memc_read_timeout

syntax: memc_read_timeout <tempo>

default: 60s

context: http, server, location

O tempo limite para ler respostas TCP do servidor memcached, em segundos por padrão.

É prudente sempre especificar explicitamente a unidade de tempo para evitar confusões. As unidades de tempo suportadas são "s" (segundos), "ms" (milissegundos), "y" (anos), "M" (meses), "w" (semanas), "d" (dias), "h" (horas) e "m" (minutos).

Esse tempo deve ser inferior a 597 horas.

memc_buffer_size

syntax: memc_buffer_size <tamanho>

default: 4k/8k

context: http, server, location

Este tamanho de buffer é usado para o buffer de memória para armazenar

  • a resposta completa para comandos do memcached diferentes de get,
  • o cabeçalho de resposta completo (ou seja, a primeira linha da resposta) para o comando get do memcached.

Esse tamanho padrão é o tamanho da página, podendo ser 4k ou 8k.

memc_ignore_client_abort

syntax: memc_ignore_client_abort on|off

default: off

context: location

Determina se a conexão com um servidor memcached deve ser fechada quando um cliente fecha uma conexão sem esperar por uma resposta.

Esta diretiva foi adicionada pela primeira vez na versão v0.14.

Mudanças

As mudanças de cada lançamento deste módulo podem ser obtidas nos logs de mudanças do pacote OpenResty:

http://openresty.org/#Changes

Conjunto de Testes

Este módulo vem com um conjunto de testes dirigido por Perl. Os casos de teste também são declarativos. Graças ao módulo Test::Base no mundo Perl.

Para executá-lo do seu lado:

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

Você precisa encerrar qualquer processo Nginx antes de executar o conjunto de testes se você tiver alterado o binário do servidor Nginx.

Ou LWP::UserAgent ou IO::Socket é usado pelo test scaffold.

Como um único servidor nginx (por padrão, localhost:1984) é usado em todos os scripts de teste (.t files), é sem sentido executar o conjunto de testes em paralelo especificando -jN ao invocar a utilidade prove.

Você também deve manter um servidor memcached escutando na porta 11211 em localhost antes de executar o conjunto de testes.

Algumas partes do conjunto de testes requerem que os módulos rewrite e echo estejam habilitados também ao construir o Nginx.

Veja Também

GitHub

Você pode encontrar dicas adicionais de configuração e documentação para este módulo no repositório GitHub do nginx-module-memc.