Boost Nginx Performance with lua‑resty‑redis: A Non‑Blocking Redis Integration Guide
This article introduces lua‑resty‑redis, explains its non‑blocking I/O model, outlines typical use cases, details installation via OPM, provides step‑by‑step Lua code for basic operations and transactions, and demonstrates testing with curl, helping developers build high‑performance OpenResty services.
Introduction
lua‑resty‑redis, created by OpenResty community member Agent Zhang, is a Lua module that integrates Redis operations directly into an Nginx environment. It leverages OpenResty’s asynchronous, non‑blocking API built on ngx.socket.tcp() and LuaJIT, enabling high‑concurrency applications without blocking Nginx worker threads.
Application Scenarios
Cache management – use Redis as a fast cache layer to reduce database load.
Distributed sessions – share user session state across multiple servers.
Message queues – implement simple asynchronous task processing via Pub/Sub.
Real‑time analytics – employ Redis data structures for live statistics.
Main Features
Non‑blocking I/O based on OpenResty’s async TCP socket interface.
Comprehensive Redis command support, covering strings, hashes, sets, sorted sets, and Pub/Sub.
Robust error handling for easier debugging.
Extensible connection‑pool strategies.
Clear and concise API that accelerates development.
Installation
Install the module using the OPM package manager: opm get openresty/lua-resty-redis Version information:
# opm info openresty/lua-resty-redis
Name : lua-resty-redis
Version : 0.27
Abstract : Lua redis client driver for the ngx_lua based on the cosocket API
Author : Yichun "agentzh" Zhang (agentzh)
Account : openresty
Code Repo : https://github.com/openresty/lua-resty-redis
License : BSD 2-Clause "Simplified" or "FreeBSD" license
Original Work : yesBasic Usage
The following example shows how to set and get a key‑value pair using redis_test_01.lua:
-- redis config
local redis = require "resty.redis"
local red = redis:new()
red:set_timeouts(1000, 1000, 1000) -- 1 second
local ok, err = red:connect("192.168.13.168", 6379)
if not ok then
ngx.say("[x] failed to connect: ", err)
return
end
local res, err = red:auth("123456")
if not res then
ngx.say("[x] failed to authenticate: ", err)
return
end
local count, err = red:get_reused_times()
ngx.say("[x] get_reused_times count: ", count)
if 0 == count then
res, err = red:auth("123456")
if not res then
ngx.say("[x]failed to authenticate: ", err)
return
end
elseif err then
ngx.say("[x]failed to get reused times: ", err)
return
end
ngx.say("[x] set result: ", ok)
local res, err = red:get("name")
if not res then
ngx.say("[x] failed to get name: ", err)
return
end
if res == ngx.null then
ngx.say("[x] name not found.")
return
end
ngx.say("[x] get name : ", res)
local ok, err = red:set_keepalive(10000, 100)
if not ok then
ngx.say("[x] failed to set keepalive: ", err)
return
endThe method red:get_reused_times() returns 0 for a newly created connection and a non‑zero value for connections retrieved from the internal pool, allowing developers to determine whether authentication is required.
$ curl -i http://openresty.tinywan.com/lua_redis_test
HTTP/1.1 200 OK
Server: openresty/1.17.8.2
Date: Tue, 23 Jul 2024 07:16:23 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
[x] set result: OK
[x] get name : TinywanIf the password is incorrect, the response will be:
failed to authenticate: ERR invalid passwordTransaction Support
The library also supports Redis transactions, as demonstrated in redis_transactions_test.lua:
local cjson = require "cjson"
local redis = require "resty.redis"
local red = redis:new()
red:set_timeouts(1000, 1000, 1000)
local ok, err = red:connect("192.168.13.168", 6379)
if not ok then ngx.say("[x] failed to connect: ", err) return end
local res, err = red:auth("123456")
if not res then ngx.say("[x] failed to authenticate: ", err) return end
ok, err = red:multi()
if not ok then ngx.say("failed to run multi: ", err) return end
ngx.say("[x] multi ans: ", cjson.encode(ok))
local ans, err = red:set("resty_name", "Tinywan")
if not ans then ngx.say("[x] failed to run set: ", err) return end
ngx.say("[x] set ans: ", cjson.encode(ans))
ans, err = red:lpop("resty_name")
if not ans then ngx.say("[x] failed to run lpop: ", err) return end
ngx.say("[x] lpop ans: ", cjson.encode(ans))
ans, err = red:exec()
ngx.say("[x] exec ans: ", cjson.encode(ans))
red:close() $ curl -i http://openresty.tinywan.com/lua_redis_transactions_test
HTTP/1.1 200 OK
Server: openresty/1.17.8.2
Date: Tue, 23 Jul 2024 07:29:53 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
[x] multi ans: "OK"
[x] set ans: "QUEUED"
[x] set ans: "QUEUED"
[x] exec ans: ["OK",[false,"WRONGTYPE Operation against a key holding the wrong kind of value"]]Conclusion
lua‑resty‑redis provides a powerful, non‑blocking Redis client for OpenResty, enabling developers to build high‑performance web services ranging from simple caching layers to complex distributed systems while maintaining stability and efficiency.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Tech Hub
Sharing cutting-edge internet technologies and practical AI resources.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
