memcached: driver de cliente Lua memcached para nginx-module-lua baseado na API cosocket
Instalação
Se você ainda não configurou a assinatura do repositório RPM, inscreva-se. Em seguida, você pode prosseguir com os seguintes passos.
CentOS/RHEL 7 ou Amazon Linux 2
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 lua-resty-memcached
CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-memcached
Para usar esta biblioteca Lua com o NGINX, certifique-se de que o nginx-module-lua está instalado.
Este documento descreve lua-resty-memcached v0.17 lançado em 19 de janeiro de 2023.
Esta biblioteca Lua é um driver de cliente memcached para o módulo ngx_lua do nginx:
http://wiki.nginx.org/HttpLuaModule
Esta biblioteca Lua aproveita a API cosocket do ngx_lua, que garante um comportamento 100% não bloqueante.
Observe que pelo menos ngx_lua 0.5.0rc29 ou OpenResty 1.0.15.7 é necessário.
Sinopse
server {
location /test {
content_by_lua '
local memcached = require "resty.memcached"
local memc, err = memcached:new()
if not memc then
ngx.say("falha ao instanciar memc: ", err)
return
end
memc:set_timeout(1000) -- 1 seg
-- ou conecte-se a um arquivo de socket de domínio unix escutado
-- por um servidor memcached:
-- local ok, err = memc:connect("unix:/caminho/para/memc.sock")
local ok, err = memc:connect("127.0.0.1", 11211)
if not ok then
ngx.say("falha ao conectar: ", err)
return
end
local ok, err = memc:flush_all()
if not ok then
ngx.say("falha ao limpar tudo: ", err)
return
end
local ok, err = memc:set("dog", 32)
if not ok then
ngx.say("falha ao definir dog: ", err)
return
end
local res, flags, err = memc:get("dog")
if err then
ngx.say("falha ao obter dog: ", err)
return
end
if not res then
ngx.say("dog não encontrado")
return
end
ngx.say("dog: ", res)
-- coloque-o no pool de conexões de tamanho 100,
-- com 10 segundos de tempo máximo ocioso
local ok, err = memc:set_keepalive(10000, 100)
if not ok then
ngx.say("não é possível definir keepalive: ", err)
return
end
-- ou simplesmente feche a conexão imediatamente:
-- local ok, err = memc:close()
-- if not ok then
-- ngx.say("falha ao fechar: ", err)
-- return
-- end
';
}
}
Métodos
O argumento key fornecido nos seguintes métodos será automaticamente escapado de acordo com as regras de escape de URI antes de ser enviado ao servidor memcached.
new
syntax: memc, err = memcached:new(opts?)
Cria um objeto memcached. Em caso de falhas, retorna nil e uma string descrevendo o erro.
Aceita um argumento opcional de tabela opts. As seguintes opções são suportadas:
-
key_transformuma tabela de array contendo duas funções para escapar e desescapar as chaves do memcached, respectivamente. Por padrão, as chaves do memcached serão escapadas e desescapadas como componentes de URI, ou seja,
memcached:new{
key_transform = { ngx.escape_uri, ngx.unescape_uri }
}
connect
syntax: ok, err = memc:connect(host, port)
syntax: ok, err = memc:connect("unix:/caminho/para/unix.sock")
Tenta conectar ao host remoto e à porta que o servidor memcached está escutando ou a um arquivo de socket de domínio unix local escutado pelo servidor memcached.
Antes de realmente resolver o nome do host e conectar ao backend remoto, este método sempre procurará no pool de conexões por conexões ociosas correspondentes criadas por chamadas anteriores deste método.
sslhandshake
syntax: session, err = memc:sslhandshake(reused_session?, server_name?, ssl_verify?, send_status_req?)
Realiza o handshake SSL/TLS na conexão atualmente estabelecida. Consulte a tcpsock.sslhandshake API do OpenResty para mais detalhes.
set
syntax: ok, err = memc:set(key, value, exptime, flags)
Insere uma entrada no memcached incondicionalmente. Se a chave já existir, sobrescreve-a.
O argumento value também pode ser uma tabela Lua contendo várias strings Lua que devem ser concatenadas como um todo
(sem quaisquer delimitadores). Por exemplo,
memc:set("dog", {"a ", {"kind of"}, " animal"})
é funcionalmente equivalente a
memc:set("dog", "a kind of animal")
O parâmetro exptime é opcional e tem como padrão 0 (significando que nunca expira). O tempo de expiração está em segundos.
O parâmetro flags é opcional e tem como padrão 0.
set_timeout
syntax: ok, err = memc:set_timeout(timeout)
Define o tempo limite (em ms) de proteção para operações subsequentes, incluindo o método connect.
Retorna 1 quando bem-sucedido e nil mais uma string descrevendo o erro, caso contrário.
set_timeouts
syntax: ok, err = memc:set_timeouts(connect_timeout, send_timeout, read_timeout)
Define os tempos limites (em ms) para operações de conexão, envio e leitura, respectivamente.
Retorna 1 quando bem-sucedido e nil mais uma string descrevendo o erro, caso contrário.
set_keepalive
syntax: ok, err = memc:set_keepalive(max_idle_timeout, pool_size)
Coloca a conexão memcached atual imediatamente no pool de conexões cosocket do ngx_lua.
Você pode especificar o tempo máximo ocioso (em ms) quando a conexão está no pool e o tamanho máximo do pool para cada processo trabalhador do nginx.
Em caso de sucesso, retorna 1. Em caso de erros, retorna nil com uma string descrevendo o erro.
Chame este método apenas no lugar onde você chamaria o método close. Chamar este método transformará imediatamente o objeto memcached atual no estado closed. Quaisquer operações subsequentes, além de connect() no objeto atual, retornarão o erro closed.
get_reused_times
syntax: times, err = memc:get_reused_times()
Este método retorna o número de vezes que a conexão atual foi (com sucesso) reutilizada. Em caso de erro, retorna nil e uma string descrevendo o erro.
Se a conexão atual não vier do pool de conexões embutido, então este método sempre retornará 0, ou seja, a conexão nunca foi reutilizada (ainda). Se a conexão vier do pool de conexões, então o valor de retorno será sempre diferente de zero. Portanto, este método também pode ser usado para determinar se a conexão atual vem do pool.
close
syntax: ok, err = memc:close()
Fecha a conexão memcached atual e retorna o status.
Em caso de sucesso, retorna 1. Em caso de erros, retorna nil com uma string descrevendo o erro.
add
syntax: ok, err = memc:add(key, value, exptime, flags)
Insere uma entrada no memcached se e somente se a chave não existir.
O argumento value também pode ser uma tabela Lua contendo várias strings Lua que devem ser concatenadas como um todo
(sem quaisquer delimitadores). Por exemplo,
memc:add("dog", {"a ", {"kind of"}, " animal"})
é funcionalmente equivalente a
memc:add("dog", "a kind of animal")
O parâmetro exptime é opcional e tem como padrão 0 (significando que nunca expira). O tempo de expiração está em segundos.
O parâmetro flags é opcional, com padrão 0.
Em caso de sucesso, retorna 1. Em caso de erros, retorna nil com uma string descrevendo o erro.
replace
syntax: ok, err = memc:replace(key, value, exptime, flags)
Insere uma entrada no memcached se e somente se a chave já existir.
O argumento value também pode ser uma tabela Lua contendo várias strings Lua que devem ser concatenadas como um todo
(sem quaisquer delimitadores). Por exemplo,
memc:replace("dog", {"a ", {"kind of"}, " animal"})
é funcionalmente equivalente a
memc:replace("dog", "a kind of animal")
O parâmetro exptime é opcional e tem como padrão 0 (significando que nunca expira). O tempo de expiração está em segundos.
O parâmetro flags é opcional, com padrão 0.
Em caso de sucesso, retorna 1. Em caso de erros, retorna nil com uma string descrevendo o erro.
append
syntax: ok, err = memc:append(key, value, exptime, flags)
Anexa o valor a uma entrada com a mesma chave que já existe no memcached.
O argumento value também pode ser uma tabela Lua contendo várias strings Lua que devem ser concatenadas como um todo
(sem quaisquer delimitadores). Por exemplo,
memc:append("dog", {"a ", {"kind of"}, " animal"})
é funcionalmente equivalente a
memc:append("dog", "a kind of animal")
O parâmetro exptime é opcional e tem como padrão 0 (significando que nunca expira). O tempo de expiração está em segundos.
O parâmetro flags é opcional, com padrão 0.
Em caso de sucesso, retorna 1. Em caso de erros, retorna nil com uma string descrevendo o erro.
prepend
syntax: ok, err = memc:prepend(key, value, exptime, flags)
Precede o valor a uma entrada com a mesma chave que já existe no memcached.
O argumento value também pode ser uma tabela Lua contendo várias strings Lua que devem ser concatenadas como um todo
(sem quaisquer delimitadores). Por exemplo,
memc:prepend("dog", {"a ", {"kind of"}, " animal"})
é funcionalmente equivalente a
memc:prepend("dog", "a kind of animal")
O parâmetro exptime é opcional e tem como padrão 0 (significando que nunca expira). O tempo de expiração está em segundos.
O parâmetro flags é opcional e tem como padrão 0.
Em caso de sucesso, retorna 1. Em caso de erros, retorna nil com uma string descrevendo o erro.
get
syntax: value, flags, err = memc:get(key)
syntax: results, err = memc:get(keys)
Obtém uma única entrada ou várias entradas no servidor memcached via uma única chave ou uma tabela de chaves.
Vamos primeiro discutir o caso em que a chave é uma única string.
O valor da chave e o valor de flags associados serão retornados se a entrada for encontrada e nenhum erro ocorrer.
Em caso de erros, os valores nil serão retornados para value e flags e um terceiro valor (string) também será retornado para descrever o erro.
Se a entrada não for encontrada, então três valores nil serão retornados.
Agora vamos discutir o caso em que uma tabela Lua de várias chaves é fornecida.
Neste caso, uma tabela Lua contendo os pares chave-resultado será sempre retornada em caso de sucesso. Cada valor correspondente a cada chave na tabela também é uma tabela contendo dois valores, o valor da chave e as flags da chave. Se uma chave não existir, então não haverá entradas correspondentes na tabela results.
Em caso de erros, nil será retornado e o segundo valor de retorno será uma string descrevendo o erro.
gets
syntax: value, flags, cas_unique, err = memc:gets(key)
syntax: results, err = memc:gets(keys)
Assim como o método get, mas também retornará o valor CAS único associado à entrada, além do valor da chave e das flags.
Este método é geralmente usado em conjunto com o método cas.
cas
syntax: ok, err = memc:cas(key, value, cas_unique, exptime?, flags?)
Assim como o método set, mas realiza uma operação de verificação e definição, o que significa "armazenar esses dados, mas
apenas se ninguém mais tiver atualizado desde a última vez que eu os busquei."
O argumento cas_unique pode ser obtido do método gets.
touch
syntax: ok, err = memc:touch(key, exptime)
Atualiza o tempo de expiração de uma chave existente.
Retorna 1 em caso de sucesso ou nil com uma string descrevendo o erro, caso contrário.
Este método foi introduzido pela primeira vez na versão v0.11.
flush_all
syntax: ok, err = memc:flush_all(time?)
Limpa (ou invalida) todas as entradas existentes no servidor memcached imediatamente (por padrão) ou após a expiração
especificada pelo argumento time (em segundos).
Em caso de sucesso, retorna 1. Em caso de erros, retorna nil com uma string descrevendo o erro.
delete
syntax: ok, err = memc:delete(key)
Exclui a chave do memcached imediatamente.
A chave a ser excluída deve já existir no memcached.
Em caso de sucesso, retorna 1. Em caso de erros, retorna nil com uma string descrevendo o erro.
incr
syntax: new_value, err = memc:incr(key, delta)
Incrementa o valor da chave especificada pelo valor inteiro especificado no argumento delta.
Retorna o novo valor após a incrementação em caso de sucesso, e nil com uma string descrevendo o erro em caso de falhas.
decr
syntax: new_value, err = memc:decr(key, value)
Decrementa o valor da chave especificada pelo valor inteiro especificado no argumento delta.
Retorna o novo valor após a decrementação em caso de sucesso, e nil com uma string descrevendo o erro em caso de falhas.
stats
syntax: lines, err = memc:stats(args?)
Retorna informações de estatísticas do servidor memcached com um argumento opcional args.
Em caso de sucesso, este método retorna uma tabela Lua contendo todas as linhas da saída; em caso de falhas, retorna nil com uma string descrevendo o erro.
Se o argumento args for omitido, estatísticas gerais do servidor são retornadas. Os possíveis valores do argumento args são items, sizes, slabs, entre outros.
quit
syntax: ok, err = memc:quit()
Informa ao servidor para fechar a conexão memcached atual.
Retorna 1 em caso de sucesso e nil caso contrário. Em caso de falhas, outro valor de string também será retornado para descrever o erro.
Geralmente, você pode simplesmente chamar diretamente o método close para alcançar o mesmo efeito.
verbosity
syntax: ok, err = memc:verbosity(level)
Define o nível de verbosidade usado pelo servidor memcached. O argumento level deve ser fornecido apenas como inteiros.
Retorna 1 em caso de sucesso e nil caso contrário. Em caso de falhas, outro valor de string também será retornado para descrever o erro.
init_pipeline
syntax: err = memc:init_pipeline(n?)
Habilita o modo de pipeline do Memcache. Todas as chamadas subsequentes aos métodos de comando do Memcache serão automaticamente armazenadas em buffer e enviadas ao servidor em uma única execução quando o método commit_pipeline for chamado ou canceladas chamando o método cancel_pipeline.
O parâmetro opcional n é o tamanho das tabelas de buffer. valor padrão 4
commit_pipeline
syntax: results, err = memc:commit_pipeline()
Sai do modo de pipeline comprometendo todas as consultas Memcache em cache para o servidor remoto em uma única execução. Todas as respostas para essas consultas serão coletadas automaticamente e retornadas como se fossem uma grande resposta multi-bulk no nível mais alto.
Este método retorna uma tabela Lua em caso de sucesso. Retorna uma string Lua descrevendo o erro em caso de falhas.
cancel_pipeline
syntax: memc:cancel_pipeline()
Sai do modo de pipeline descartando todos os comandos Memcache em buffer existentes desde a última chamada ao método init_pipeline.
o método não retorna. sempre tem sucesso.
Registro Automático de Erros
Por padrão, o módulo subjacente ngx_lua faz registro de erros quando ocorrem erros de socket. Se você já está fazendo um tratamento de erros adequado em seu próprio código Lua, então é recomendado desativar este registro automático de erros desativando a diretiva lua_socket_log_errors do ngx_lua, ou seja,
lua_socket_log_errors off;
Limitações
- Esta biblioteca não pode ser usada em contextos de código como
set_by_lua*,log_by_lua*, eheader_filter_by_lua*onde a API cosocket do ngx_lua não está disponível. - A instância do objeto
resty.memcachednão pode ser armazenada em uma variável Lua no nível do módulo Lua, porque então será compartilhada por todas as requisições concorrentes tratadas pelo mesmo processo trabalhador do nginx (veja http://wiki.nginx.org/HttpLuaModule#Data_Sharing_within_an_Nginx_Worker) e resultará em más condições de corrida quando requisições concorrentes tentarem usar a mesma instânciaresty.memcached. Você deve sempre iniciar objetosresty.memcachedem variáveis locais de função ou na tabelangx.ctx. Esses lugares têm suas próprias cópias de dados para cada requisição.
Veja Também
- o módulo ngx_lua: http://wiki.nginx.org/HttpLuaModule
- a especificação do protocolo wired do memcached: http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt
- a biblioteca lua-resty-redis.
- a biblioteca lua-resty-mysql.
GitHub
Você pode encontrar dicas adicionais de configuração e documentação para este módulo no repositório do GitHub para nginx-module-memcached.