Saltar a contenido

redis-util: Nginx-module-lua-resty-redis herramienta de encapsulación

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-redis-util

CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023

dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-redis-util

Para usar esta biblioteca Lua con NGINX, asegúrate de que nginx-module-lua esté instalado.

Este documento describe lua-resty-redis-util v0.7 lanzado el 15 de diciembre de 2021.


Introducción

Este proyecto se basa en [openresty/lua-resty-redis][] y es una biblioteca para operar Redis en OpenResty desarrollada por [章亦春(agentzh)][agentzh]. Es una herramienta de encapsulación secundaria. La funcionalidad central sigue siendo proporcionada por [openresty/lua-resty-redis][].

Este documento asume que ya tienes conocimientos sobre nginx+lua o cómo usar scripts Lua en OpenResty (por ejemplo, configuración de lua_package_path, *_by_lua_file), conocimientos básicos sobre Redis, así como el método básico de uso de [openresty/lua-resty-redis][] ([openresty/lua-resty-redis#README.md][README.md]).

Instalación

opm get anjia0532/lua-resty-redis-util

Comparación

A continuación se muestra un fragmento de código oficial para ilustrar:

    local redis = require "resty.redis"
    local red = redis:new()

    red:set_timeout(1000) -- 1 seg -- establece el tiempo de espera

    local ok, err = red:connect("127.0.0.1", 6379) -- establece el host y el puerto de Redis
    if not ok then -- verifica si la conexión falló
        ngx.say("falló al conectar: ", err)
        return
    end

    ok, err = red:set("dog", "un animal") -- inserta la clave (similar a mysql insert)
    if not ok then -- verifica si la operación fue exitosa
        ngx.say("falló al establecer dog: ", err)
        return
    end

    ngx.say("resultado de la configuración: ", ok) -- salida del resultado en la página
    -- colócalo en el grupo de conexiones de tamaño 100,
    -- con un tiempo máximo de inactividad de 10 segundos
    local ok, err = red:set_keepalive(10000, 100) -- coloca la conexión en el grupo de conexiones, 100 conexiones, tiempo máximo de inactividad de 10 segundos
    if not ok then -- verifica el resultado de la colocación
        ngx.say("falló al establecer keepalive: ", err)
        return
    end
    -- si no se coloca en el grupo, ciérralo inmediatamente después de usarlo:
    -- local ok, err = red:close()
    -- if not ok then
    --     ngx.say("falló al cerrar: ", err)
    --     return
    -- end

Si has utilizado Java, C# u otros lenguajes orientados a objetos, sentirás que escribir así es demasiado... debe ser reestructurado, expone demasiados detalles irrelevantes, lo que resulta en una gran cantidad de código repetido.

El mismo contenido, utilizando mi código encapsulado. Se ocultan las operaciones de configuración del grupo de conexiones, obtención de conexiones, y devolución de conexiones al grupo.

    -- biblioteca dependiente
    local redis = require "resty.redis-util"
    -- inicialización
    local red = redis:new();
    -- inserta la clave
    local ok, err = red:set("dog", "un animal")
    -- verifica el resultado
    if not ok then
      ngx.say("falló al establecer dog:", err)
      return
    end
    -- salida del resultado en la página
    ngx.say("resultado de la configuración: ", ok) -- salida del resultado en la página

Consideraciones

Valores predeterminados

local red = redis:new();
-- se utilizaron valores predeterminados, equivalente a
local red2 = redis:new({
                            host='127.0.0.1',
                            port=6379,
                            db_index=0,
                            password=nil,
                            timeout=1000,
                            keepalive=60000,
                            pool_size=100
                        });
  • host: host de redis, predeterminado: 127.0.0.1
  • port: puerto de redis, predeterminado: 6379
  • db_index: índice de la base de datos de redis (predeterminado 0-15, un total de 16 bases de datos), la predeterminada es la base de datos 0 (se recomienda usar diferentes puertos para diferentes instancias o usar diferentes prefijos, ya que cambiar de base de datos requiere usar el comando select), predeterminado: 0
  • password: contraseña de autenticación de redis
  • timeout: tiempo de espera de conexión a redis, predeterminado: 1000 (1s)
  • keepalive: tiempo máximo de inactividad de la conexión a redis, predeterminado: 60000 (1m)
  • pool_size: tamaño del grupo de conexiones de redis, predeterminado: 100

subscribe

Dado que no se utilizó pub/sub, solo se implementó de manera simple (un)subscribe, sin continuar con (un)psubscribe (suscripción por patrón), consulta [Redis 接口的二次封装(发布订阅)][linkRedis接口的二次封装(发布订阅)]

    local cjson = require "cjson"
    local red = redis:new();

    -- suscribirse al canal dog
    local func  = red:subscribe("dog")

    -- verifica si la suscripción fue exitosa
    if not func then
      return nil
    end

    -- obtener valor
    local res, err = func() -- func()=func(true)
    -- si falla, cancelar suscripción
    if err then
        func(false)
    end

    -- si se obtiene un resultado, realizar salida en la página
    if res then
        ngx.say("1: recibir: ", cjson.encode(res))
    end

    -- obtener nuevamente
    res, err = func()

    -- después de obtener con éxito, cancelar suscripción func(false)
    if res then
        ngx.say("2: recibir: ", cjson.encode(res))
        func(false)
    end

pipeline

Consulta [openresty/lua-resty-redis#Synopsis][]

    local cjson = require "cjson"
    local red = redis:new();

    red:init_pipeline()

    red:set("cat", "Marry")
    red:set("horse", "Bob")
    red:get("cat")
    red:get("horse")

    local results, err = red:commit_pipeline()

    if not results then
        ngx.say("falló al comprometer las solicitudes en pipeline: ", err)
        return
    else
        ngx.say("pipeline", cjson.encode(results))
    end
    -- salida pipeline["OK","OK","Marry","Bob"]

script

Consulta [script 压缩复杂请求][linkScript压缩复杂请求]

    local red = redis:new();

    local id = 1
    local res, err = red:eval([[
        -- Ten en cuenta que al ejecutar scripts en Redis, los valores extraídos de KEYS/ARGV son de tipo string
        local info = redis.call('get', KEYS[1])
        info = cjson.decode(info)
        local g_id = info.gid

        local g_info = redis.call('get', g_id)
        return g_info
        ]], 1, id)

    if not res then
       ngx.say("falló al obtener la información del grupo: ", err)
       return
    end

    ngx.say("script", res)

Agradecimientos

Esta herramienta se basa en el código de [lua-resty-redis/lib/resty/redis.lua][] y [Redis 接口的二次封装][linkRedis接口的二次封装].

Retroalimentación

Si tienes problemas, no dudes en presentar [issues][].

GitHub

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