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.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
Boost Nginx Performance with lua‑resty‑redis: A Non‑Blocking Redis Integration Guide

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     : yes

Basic 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
end

The 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 : Tinywan

If the password is incorrect, the response will be:

failed to authenticate: ERR invalid password

Transaction 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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Backend DevelopmentRedisNon-blocking I/O
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.