memcached: controlador cliente de Lua memcached para nginx-module-lua basado en la API de cosocket
Instalación
Si no has configurado la suscripción al repositorio RPM, regístrate. Luego puedes proceder con los siguientes pasos.
CentOS/RHEL 7 o 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 de Lua con NGINX, asegúrate de que nginx-module-lua esté instalado.
Este documento describe lua-resty-memcached v0.17 lanzado el 19 de enero de 2023.
Esta biblioteca de Lua es un controlador cliente de memcached para el módulo ngx_lua de nginx:
http://wiki.nginx.org/HttpLuaModule
Esta biblioteca de Lua aprovecha la API de cosocket de ngx_lua, que garantiza un comportamiento 100% no bloqueante.
Ten en cuenta que se requiere al menos ngx_lua 0.5.0rc29 o OpenResty 1.0.15.7.
Sinopsis
server {
location /test {
content_by_lua '
local memcached = require "resty.memcached"
local memc, err = memcached:new()
if not memc then
ngx.say("failed to instantiate memc: ", err)
return
end
memc:set_timeout(1000) -- 1 sec
-- o conectarse a un archivo de socket de dominio unix escuchado
-- por un servidor memcached:
-- local ok, err = memc:connect("unix:/path/to/memc.sock")
local ok, err = memc:connect("127.0.0.1", 11211)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local ok, err = memc:flush_all()
if not ok then
ngx.say("failed to flush all: ", err)
return
end
local ok, err = memc:set("dog", 32)
if not ok then
ngx.say("failed to set dog: ", err)
return
end
local res, flags, err = memc:get("dog")
if err then
ngx.say("failed to get dog: ", err)
return
end
if not res then
ngx.say("dog not found")
return
end
ngx.say("dog: ", res)
-- ponerlo en el pool de conexiones de tamaño 100,
-- con un tiempo máximo de inactividad de 10 segundos
local ok, err = memc:set_keepalive(10000, 100)
if not ok then
ngx.say("cannot set keepalive: ", err)
return
end
-- o simplemente cerrar la conexión de inmediato:
-- local ok, err = memc:close()
-- if not ok then
-- ngx.say("failed to close: ", err)
-- return
-- end
';
}
}
Métodos
El argumento key proporcionado en los siguientes métodos será automáticamente escapado de acuerdo con las reglas de escape de URI antes de enviarlo al servidor memcached.
new
syntax: memc, err = memcached:new(opts?)
Crea un objeto memcached. En caso de fallos, devuelve nil y una cadena que describe el error.
Acepta un argumento opcional de tabla opts. Las siguientes opciones son compatibles:
-
key_transformuna tabla de arreglo que contiene dos funciones para escapar y desescapar las claves de memcached, respectivamente. Por defecto, las claves de memcached serán escapadas y desescapadas como componentes de URI, es decir
memached:new{
key_transform = { ngx.escape_uri, ngx.unescape_uri }
}
connect
syntax: ok, err = memc:connect(host, port)
syntax: ok, err = memc:connect("unix:/path/to/unix.sock")
Intenta conectarse al host remoto y puerto al que el servidor memcached está escuchando o a un archivo de socket de dominio unix local escuchado por el servidor memcached.
Antes de resolver realmente el nombre del host y conectarse al backend remoto, este método siempre buscará en el pool de conexiones conexiones inactivas coincidentes creadas por llamadas anteriores a este método.
sslhandshake
syntax: session, err = memc:sslhandshake(reused_session?, server_name?, ssl_verify?, send_status_req?)
Realiza el apretón de manos SSL/TLS en la conexión actualmente establecida. Consulta la tcpsock.sslhandshake API de OpenResty para más detalles.
set
syntax: ok, err = memc:set(key, value, exptime, flags)
Inserta una entrada en memcached incondicionalmente. Si la clave ya existe, la sobrescribe.
El argumento value también podría ser una tabla de Lua que contenga múltiples cadenas de Lua que se supone deben ser concatenadas como un todo
(sin ningún delimitador). Por ejemplo,
memc:set("dog", {"a ", {"kind of"}, " animal"})
es funcionalmente equivalente a
memc:set("dog", "a kind of animal")
El parámetro exptime es opcional y por defecto es 0 (lo que significa que nunca expira). El tiempo de expiración está en segundos.
El parámetro flags es opcional y por defecto es 0.
set_timeout
syntax: ok, err = memc:set_timeout(timeout)
Establece la protección de tiempo de espera (en ms) para las operaciones subsiguientes, incluyendo el método connect.
Devuelve 1 cuando tiene éxito y nil más una cadena que describe el error en caso contrario.
set_timeouts
syntax: ok, err = memc:set_timeouts(connect_timeout, send_timeout, read_timeout)
Establece los tiempos de espera (en ms) para las operaciones de conexión, envío y lectura respectivamente.
Devuelve 1 cuando tiene éxito y nil más una cadena que describe el error en caso contrario.
set_keepalive
syntax: ok, err = memc:set_keepalive(max_idle_timeout, pool_size)
Coloca la conexión memcached actual inmediatamente en el pool de conexiones de cosocket de ngx_lua.
Puedes especificar el tiempo máximo de inactividad (en ms) cuando la conexión está en el pool y el tamaño máximo del pool para cada proceso de trabajo de nginx.
En caso de éxito, devuelve 1. En caso de errores, devuelve nil con una cadena que describe el error.
Solo llama a este método en el lugar donde habrías llamado al método close en su lugar. Llamar a este método convertirá inmediatamente el objeto memcached actual en el estado closed. Cualquier operación subsiguiente distinta de connect() en el objeto actual devolverá el error closed.
get_reused_times
syntax: times, err = memc:get_reused_times()
Este método devuelve las veces (exitosamente) reutilizadas para la conexión actual. En caso de error, devuelve nil y una cadena que describe el error.
Si la conexión actual no proviene del pool de conexiones incorporado, entonces este método siempre devuelve 0, es decir, la conexión nunca ha sido reutilizada (aún). Si la conexión proviene del pool de conexiones, entonces el valor de retorno siempre es distinto de cero. Así que este método también se puede usar para determinar si la conexión actual proviene del pool.
close
syntax: ok, err = memc:close()
Cierra la conexión memcached actual y devuelve el estado.
En caso de éxito, devuelve 1. En caso de errores, devuelve nil con una cadena que describe el error.
add
syntax: ok, err = memc:add(key, value, exptime, flags)
Inserta una entrada en memcached si y solo si la clave no existe.
El argumento value también podría ser una tabla de Lua que contenga múltiples cadenas de Lua que se supone deben ser concatenadas como un todo
(sin ningún delimitador). Por ejemplo,
memc:add("dog", {"a ", {"kind of"}, " animal"})
es funcionalmente equivalente a
memc:add("dog", "a kind of animal")
El parámetro exptime es opcional y por defecto es 0 (lo que significa que nunca expira). El tiempo de expiración está en segundos.
El parámetro flags es opcional, por defecto es 0.
En caso de éxito, devuelve 1. En caso de errores, devuelve nil con una cadena que describe el error.
replace
syntax: ok, err = memc:replace(key, value, exptime, flags)
Inserta una entrada en memcached si y solo si la clave ya existe.
El argumento value también podría ser una tabla de Lua que contenga múltiples cadenas de Lua que se supone deben ser concatenadas como un todo
(sin ningún delimitador). Por ejemplo,
memc:replace("dog", {"a ", {"kind of"}, " animal"})
es funcionalmente equivalente a
memc:replace("dog", "a kind of animal")
El parámetro exptime es opcional y por defecto es 0 (lo que significa que nunca expira). El tiempo de expiración está en segundos.
El parámetro flags es opcional, por defecto es 0.
En caso de éxito, devuelve 1. En caso de errores, devuelve nil con una cadena que describe el error.
append
syntax: ok, err = memc:append(key, value, exptime, flags)
Adjunta el valor a una entrada con la misma clave que ya existe en memcached.
El argumento value también podría ser una tabla de Lua que contenga múltiples cadenas de Lua que se supone deben ser concatenadas como un todo
(sin ningún delimitador). Por ejemplo,
memc:append("dog", {"a ", {"kind of"}, " animal"})
es funcionalmente equivalente a
memc:append("dog", "a kind of animal")
El parámetro exptime es opcional y por defecto es 0 (lo que significa que nunca expira). El tiempo de expiración está en segundos.
El parámetro flags es opcional, por defecto es 0.
En caso de éxito, devuelve 1. En caso de errores, devuelve nil con una cadena que describe el error.
prepend
syntax: ok, err = memc:prepend(key, value, exptime, flags)
Antepone el valor a una entrada con la misma clave que ya existe en memcached.
El argumento value también podría ser una tabla de Lua que contenga múltiples cadenas de Lua que se supone deben ser concatenadas como un todo
(sin ningún delimitador). Por ejemplo,
memc:prepend("dog", {"a ", {"kind of"}, " animal"})
es funcionalmente equivalente a
memc:prepend("dog", "a kind of animal")
El parámetro exptime es opcional y por defecto es 0 (lo que significa que nunca expira). El tiempo de expiración está en segundos.
El parámetro flags es opcional y por defecto es 0.
En caso de éxito, devuelve 1. En caso de errores, devuelve nil con una cadena que describe el error.
get
syntax: value, flags, err = memc:get(key)
syntax: results, err = memc:get(keys)
Obtiene una sola entrada o múltiples entradas en el servidor memcached a través de una sola clave o una tabla de claves.
Primero discutamos el caso cuando la clave es una sola cadena.
El valor de la clave y el valor de las banderas asociadas se devolverán si la entrada se encuentra y no ocurre ningún error.
En caso de errores, los valores nil se devolverán para value y flags y también se devolverá un tercer valor (cadena) para describir el error.
Si la entrada no se encuentra, entonces se devolverán tres valores nil.
Luego discutamos el caso cuando se proporciona una tabla de Lua con múltiples claves.
En este caso, siempre se devolverá una tabla de Lua que contiene los pares clave-resultado en caso de éxito. Cada valor correspondiente a cada clave en la tabla también es una tabla que contiene dos valores, el valor de la clave y las banderas de la clave. Si una clave no existe, entonces no hay entradas correspondientes en la tabla results.
En caso de errores, se devolverá nil, y el segundo valor de retorno será una cadena que describe el error.
gets
syntax: value, flags, cas_unique, err = memc:gets(key)
syntax: results, err = memc:gets(keys)
Al igual que el método get, pero también devolverá el valor único CAS asociado con la entrada además del valor de la clave y las banderas.
Este método se utiliza generalmente junto con el método cas.
cas
syntax: ok, err = memc:cas(key, value, cas_unique, exptime?, flags?)
Al igual que el método set pero realiza una operación de verificación y establecimiento, lo que significa "almacena estos datos pero
solo si nadie más ha actualizado desde la última vez que los obtuve."
El argumento cas_unique se puede obtener del método gets.
touch
syntax: ok, err = memc:touch(key, exptime)
Actualiza el tiempo de expiración de una clave existente.
Devuelve 1 en caso de éxito o nil con una cadena que describe el error en caso contrario.
Este método se introdujo por primera vez en la versión v0.11.
flush_all
syntax: ok, err = memc:flush_all(time?)
Vacía (o invalida) todas las entradas existentes en el servidor memcached inmediatamente (por defecto) o después de la expiración
especificada por el argumento time (en segundos).
En caso de éxito, devuelve 1. En caso de errores, devuelve nil con una cadena que describe el error.
delete
syntax: ok, err = memc:delete(key)
Elimina la clave de memcached inmediatamente.
La clave a eliminar debe existir ya en memcached.
En caso de éxito, devuelve 1. En caso de errores, devuelve nil con una cadena que describe el error.
incr
syntax: new_value, err = memc:incr(key, delta)
Incrementa el valor de la clave especificada por el valor entero especificado en el argumento delta.
Devuelve el nuevo valor después de la incremetación en caso de éxito, y nil con una cadena que describe el error en caso de fallos.
decr
syntax: new_value, err = memc:decr(key, value)
Decrementa el valor de la clave especificada por el valor entero especificado en el argumento delta.
Devuelve el nuevo valor después de la decrementación en caso de éxito, y nil con una cadena que describe el error en caso de fallos.
stats
syntax: lines, err = memc:stats(args?)
Devuelve información de estadísticas del servidor memcached con un argumento opcional args.
En caso de éxito, este método devuelve una tabla de lua que contiene todas las líneas de la salida; en caso de fallos, devuelve nil con una cadena que describe el error.
Si se omite el argumento args, se devuelven estadísticas generales del servidor. Los posibles valores del argumento args son items, sizes, slabs, entre otros.
quit
syntax: ok, err = memc:quit()
Indica al servidor que cierre la conexión memcached actual.
Devuelve 1 en caso de éxito y nil en caso contrario. En caso de fallos, también se devolverá otro valor de cadena para describir el error.
Generalmente puedes simplemente llamar directamente al método close para lograr el mismo efecto.
verbosity
syntax: ok, err = memc:verbosity(level)
Establece el nivel de verbosidad utilizado por el servidor memcached. El argumento level debe ser dado solo como enteros.
Devuelve 1 en caso de éxito y nil en caso contrario. En caso de fallos, también se devolverá otro valor de cadena para describir el error.
init_pipeline
syntax: err = memc:init_pipeline(n?)
Habilita el modo de canalización de Memcache. Todas las llamadas subsiguientes a los métodos de comando de Memcache se almacenarán automáticamente en el búfer y se enviarán al servidor en una sola ejecución cuando se llame al método commit_pipeline o se cancelen llamando al método cancel_pipeline.
El parámetro opcional n es el tamaño de las tablas de búfer. valor por defecto 4
commit_pipeline
syntax: results, err = memc:commit_pipeline()
Sale del modo de canalización comprometiendo todas las consultas de Memcache almacenadas en el servidor remoto en una sola ejecución. Todas las respuestas para estas consultas se recopilarán automáticamente y se devolverán como si fueran una gran respuesta de múltiples partes en el nivel más alto.
Este método devuelve con éxito una tabla de lua. falla devuelve una cadena de lua que describe el error en caso de fallos.
cancel_pipeline
syntax: memc:cancel_pipeline()
Sale del modo de canalización descartando todos los comandos de Memcache en búfer existentes desde la última llamada al método init_pipeline.
el método no devuelve. siempre tiene éxito.
Registro Automático de Errores
Por defecto, el módulo subyacente ngx_lua realiza el registro de errores cuando ocurren errores de socket. Si ya estás haciendo un manejo de errores adecuado en tu propio código Lua, se recomienda desactivar este registro automático de errores desactivando la directiva lua_socket_log_errors de ngx_lua, es decir,
lua_socket_log_errors off;
Limitaciones
- Esta biblioteca no puede ser utilizada en contextos de código como
set_by_lua*,log_by_lua*, yheader_filter_by_lua*donde la API de cosocket de ngx_lua no está disponible. - La instancia del objeto
resty.memcachedno puede ser almacenada en una variable de Lua a nivel de módulo de Lua, porque entonces será compartida por todas las solicitudes concurrentes manejadas por el mismo proceso de trabajo de nginx (ver http://wiki.nginx.org/HttpLuaModule#Data_Sharing_within_an_Nginx_Worker) y resultará en malas condiciones de carrera cuando las solicitudes concurrentes intentan usar la misma instancia deresty.memcached. Siempre debes iniciar objetosresty.memcacheden variables locales de función o en la tablangx.ctx. Estos lugares tienen sus propias copias de datos para cada solicitud.
Ver También
- el módulo ngx_lua: http://wiki.nginx.org/HttpLuaModule
- la especificación del protocolo cableado de memcached: http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt
- la biblioteca lua-resty-redis.
- la biblioteca lua-resty-mysql.
GitHub
Puedes encontrar consejos de configuración adicionales y documentación para este módulo en el repositorio de GitHub para nginx-module-memcached.