Search code examples
nginxredislua

How to make my redis connection Singleton in Lua?


I am trying to handle incoming HTTP requests by Nginx and Lua. I need to read a blue from Redis in each request and currently, I open a Redis connection in every request by this code:

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

local ok, err = red:connect("redis", 6379)
if not ok then
    ngx.say("failed to connect: ", err)
    return
end

local res, err = red:auth("abcd")
if not res then
    ngx.log(ngx.ERR, err)
    return
end 

Is there any way to make this connection static or singleton to increase my request handler performance?


Solution

  • It is impossible to share a cosocket object (and, therefore, a redis object, check this answer for details) between different requests:

    The cosocket object created by this API function has exactly the same lifetime as the Lua handler creating it. So never pass the cosocket object to any other Lua handler (including ngx.timer callback functions) and never share the cosocket object between different Nginx requests.

    However, nginx/ngx_lua uses a connection pool internally:

    Before actually resolving the host name and connecting to the remote backend, this method will always look up the connection pool for matched idle connections created by previous calls of this method

    That being said, you just need to use sock:setkeepalive() instead of sock:close() for persistent connections. The redis object interface has a corresponding method: red:set_keepalive().

    You'll still need to create a redis object on a per request basis, but this will help to avoid a connection overhead.