lua-resty-redis-fast
版本相容性
本文保留舊實現的安裝和使用說明,並補充面向 Nginx 1.31.8 的新版配置說明。
| 實現 | 適用版本 | 狀態與使用說明 |
|---|---|---|
| 新版獨立動態模組 | 僅面向 Nginx 1.31.8,對應 OpenResty 1.31.8.x | 載入 ngx_redis_fast_module.so;Lua 介面差異見“新版使用”。 |
| 舊實現 | 與 OpenResty 1.21.4.x、1.25.3.x、1.27.1.x 或 1.31.8.x 匹配的舊版軟體包 | 保留以下安裝步驟和“舊版使用”說明。 |
舊版 OpenResty 使用者應繼續使用匹配的舊版私有庫。本文的新介面說明依據新版原始碼;安裝時請選擇與 OpenResty 匹配的軟體包,並根據所安裝的實現選擇配置。
與開源庫的效能比較
在一個典型的併發讀取應用場景中,lua-resty-redis-fast 的吞吐量達到開源 lua-resty-redis v0.34 的 3.47 倍,提升 246.9%。
| 指標 | lua-resty-redis-fast | lua-resty-redis v0.34 |
|---|---|---|
| GET 吞吐量中位數 | 214,314 次/秒 | 61,778 次/秒 |
| GET p99 延遲中位數 | 0.785 毫秒 | 1.793 毫秒 |
效能比較採用相同 Lua 併發的共享連線模式,物理連線數不同。測試中 Fast 的連線上限為 6,當前預設上限為 3。實際提升取決於業務負載、連線配置和部署環境。
前提條件
安裝軟體包要求使用者具有 root 許可權
機器必須能夠訪問以下的域名以下載軟體包和 GPG 秘鑰:
你可以通過執行以下命令驗證域名可訪問性:
curl https://openresty.org/package/pubkey.gpg curl https://pkg2.openresty.com/xray-priv-libs/
配置軟體包倉庫
將 CLIENT_TOKEN 替換為訂閱郵件中的有效 Token。先下載倉庫配置指令碼,再按照所用實現選擇以下步驟。這些命令只配置倉庫,不會安裝私有庫軟體包。
curl -o get-xray-priv-lib-repo.sh https://pkg2.openresty.com.cn/scripts/get-xray-priv-lib-repo.sh
新舊實現都需要配置 OpenResty 開源軟體倉庫,以便安裝 OpenResty 及其依賴。
OpenResty 1.31.8.x 新版實現的倉庫
新版只需配置 lua-resty-redis-fast 私有倉庫:
sudo bash get-xray-priv-lib-repo.sh -l lua-resty-redis-fast -t CLIENT_TOKEN
新版不需要安裝 coro-nginx-module 或 coro-hiredis-nginx-module 軟體包,也不需要載入它們的 Nginx 動態模組。
舊版實現的倉庫
使用匹配的舊版軟體包時,需要配置以下兩個私有倉庫:
sudo bash get-xray-priv-lib-repo.sh -l coro-nginx-module -t CLIENT_TOKEN
sudo bash get-xray-priv-lib-repo.sh -l lua-resty-redis-fast -t CLIENT_TOKEN
安裝
針對 OpenResty-1.21.4.x
使用 yum 的系統,執行以下命令安裝私有庫:
sudo yum install --disablerepo="*" --enablerepo="coro-nginx-module,lua-resty-redis-fast" -y lua-resty-redis-fast-1.21.4
使用 dnf 的系統,執行以下命令安裝私有庫:
sudo dnf install --disablerepo="*" --enablerepo="coro-nginx-module,lua-resty-redis-fast" -y lua-resty-redis-fast-1.21.4
使用 apt 的系統,執行以下命令安裝私有庫:
sudo apt-get install -y lua-resty-redis-fast-1.21.4
針對 OpenResty 1.25.3.x
使用 yum 的系統,執行以下命令安裝私有庫:
sudo yum install --disablerepo="*" --enablerepo="coro-nginx-module,lua-resty-redis-fast" -y lua-resty-redis-fast-1.25.3
使用 dnf 的系統,執行以下命令安裝私有庫:
sudo dnf install --disablerepo="*" --enablerepo="coro-nginx-module,lua-resty-redis-fast" -y lua-resty-redis-fast-1.25.3
使用 apt 的系統,執行以下命令安裝私有庫:
sudo apt-get install -y lua-resty-redis-fast-1.25.3
針對 OpenResty 1.27.1.x
使用 yum 的系統,執行以下命令安裝私有庫:
sudo yum install --disablerepo="*" --enablerepo="coro-nginx-module,lua-resty-redis-fast" -y lua-resty-redis-fast-1.27.1
使用 dnf 的系統,執行以下命令安裝私有庫:
sudo dnf install --disablerepo="*" --enablerepo="coro-nginx-module,lua-resty-redis-fast" -y lua-resty-redis-fast-1.27.1
使用 apt 的系統,執行以下命令安裝私有庫:
sudo apt-get install -y lua-resty-redis-fast-1.27.1
針對 OpenResty 1.31.8.x
軟體包名為 lua-resty-redis-fast-1.31.8,提供 RPM 和 DEB 軟體包。新版需要 OpenResty 1.31.8.1 或更新的同系列版本。安裝前應配置 OpenResty 開源軟體倉庫,以便包管理器解析依賴。軟體包名稱中的 1.31.8 只標識匹配的 Nginx 系列;升級後請確認載入的是新版獨立動態模組。
使用 yum、dnf 或 apt 的系統,分別執行對應命令:
sudo yum install -y lua-resty-redis-fast-1.31.8
sudo dnf install -y lua-resty-redis-fast-1.31.8
sudo apt-get install -y lua-resty-redis-fast-1.31.8
安裝 OpenResty
新版選擇 OpenResty 1.31.8.x,使用舊版私有庫時則選擇匹配的 OpenResty 系列。安裝或升級前,先查詢軟體倉庫中的完整版本號,避免動態模組與 OpenResty 不相容。
| 包管理器 | 查詢可用版本 | 安裝指定版本 |
|---|---|---|
yum | yum list --showduplicates openresty | sudo yum install openresty-VERSION |
dnf | dnf list --showduplicates openresty | sudo dnf install openresty-VERSION |
apt | apt-cache madison openresty | sudo apt-get install openresty=VERSION |
將 VERSION 替換為查詢結果中與所選私有庫匹配的完整版本號。
使用
請區分新版獨立動態模組與舊版 coro 實現。
新版使用
Nginx 配置
在 nginx.conf 的 main 上下文中載入新版軟體包提供的動態模組:
load_module /usr/local/openresty/nginx/modules/ngx_redis_fast_module.so;
自定義安裝目錄時,應替換為實際模組路徑。新版不再需要本庫的 coro_preload、coro_stack_size 或兩個 coro 動態模組;其他私有庫仍需要的配置應予以保留。RPM 和 DEB 軟體包使用相同的配置方式。軟體包將 Lua 位元組碼模組安裝到 /usr/local/openresty/site/lualib;自定義 lua_package_path 時應保留預設路徑(;;),或包含 /usr/local/openresty/site/lualib/?.ljbc。Nginx worker 需要能夠讀取模組和所需證書、私鑰檔案。
本次 Lua 介面與行為差異
入口仍為 require "resty.redis.fast",常用命令和流水線方法繼續可用,但連線所有權、連線池和會話操作需要按新版語義使用:
| 介面或配置 | 新版行為與遷移要求 |
|---|---|
connect(host, port, options) | 支援 TCP、TLS 和 Unix domain socket;埠可為數字或數字字串。主機名需要 Nginx resolver。重新連線會清除原有流水線和訂閱狀態,失敗後物件保持關閉。 |
db、select(db) | 可在連線時選擇資料庫,支援數字或數字字串。select() 只改變當前 Lua 例項的資料庫繫結,不改變其他例項;事務、WATCH、訂閱或不可遷移的會話狀態中不能切換資料庫。 |
max_connections | 預設 3,限制每個 worker、服務端地址和資料庫的普通共享連線總數,跨自定義池名、認證和 TLS/RESP 設定計數;每個資料庫獨立計數,獨佔連線不受此限制。該地址和資料庫的首個連線在連線池仍被使用期間確定上限。 |
pending_threshold | 預設 32,為每條連線上的待回覆命令數軟閾值。普通命令選擇相容連線中待回覆最少的連線;全部達到閾值時,在連線預算允許的情況下擴容,否則繼續共享最空閒的連線。 |
pool_size、backlog | 空閒連線數預設 128;設定 backlog 後,pool_size 還限制該池的普通物理連線數,backlog 限制等待建連的佇列長度。它們與 max_connections 的限制範圍不同。 |
set_keepalive(timeout, size) | 新版實際使用兩個引數,更新空閒策略並關閉當前邏輯客戶端;預設 60000 毫秒和 128 條空閒連線,超時為 0 時不自動過期。升級時需檢查現有呼叫的超時和容量引數。 |
close() | 釋放當前邏輯客戶端;乾淨的普通物理連線可以繼續快取複用,獨佔或被修改的會話連線會關閉,不保證立即斷開共享物理連線。 |
get_reused_times() | 返回最近借用的物理連線的複用計數,關閉時返回 0;後續操作可能使用另一條連線。 |
exclusive = true | 需要 WAIT 或 WAITAOF 時,必須在寫入前以此選項連線,將寫入和確認固定在同一條連線上;共享模式會拒絕這兩個命令。 |
| TLS 與認證 | TLS 證書鏈驗證預設開啟;ssl_ca_cert 指定 CA,ssl_verify_name 單獨校驗證書 DNS 名或 IP,SNI 不代替身份驗證。可在 connect() 中提供 password、username。 |
| RESP3 | 在 connect() 中設定 resp3 = true;受保護的伺服器還需同時提供認證資訊。手動認證時,先以預設 RESP2 連線,AUTH 成功後再呼叫 hello(3)。 |
| 錯誤返回 | Redis 命令錯誤仍返回 false, err,傳輸錯誤返回 nil, err;陣列或流水線錯誤項為 {false, err}。RESP3 的 false, nil 是有效結果,應檢查 err ~= nil。 |
普通命令完成、讀取超時或協程取消後會歸還物理連線;當前 Lua 例項仍可繼續執行普通命令,遲到回覆會被丟棄,不會交給後續呼叫。改變會話狀態的請求超時或取消後,需先執行 RESET,再執行其他命令或歸還連線。超時不代表寫入沒有執行,不能無條件重試寫操作。不要在併發操作間共享同一個 Lua 客戶端物件。
AUTH、HELLO、RESET、事務、WATCH、訂閱和阻塞命令使用獨佔連線。SELECT 在普通流水線中形成分段邊界;事務或 WATCH 中的 SELECT 返回 nil, "SELECT cannot switch connections in a transaction",含此類切換的流水線會在傳送任何命令前被拒絕。訂閱和 MONITOR 命令不能放入流水線。
Lua 示例
以下程式碼可放入 content_by_lua_block 中:
local redis = require "resty.redis.fast"
local red = redis:new()
red:set_timeouts(1000, 1000, 1000)
local ok, err = red:connect("127.0.0.1", 6379, {
db = 0,
max_connections = 3,
pending_threshold = 32,
})
if not ok then
ngx.say("failed to connect: ", err)
return
end
local res
res, err = red:set("dog", "an animal")
if err ~= nil then
red:close()
ngx.say("failed to set dog: ", err)
return
end
res, err = red:get("dog")
if err ~= nil then
red:close()
ngx.say("failed to get dog: ", err)
return
end
ngx.say("dog: ", res == ngx.null and "not found" or res)
ok, err = red:set_keepalive(60000, 128)
if not ok then
red:close()
ngx.say("failed to set keepalive: ", err)
end
完整引數和會話規則見API 手冊。本庫僅支援 HTTP 子系統,不提供 Redis Cluster 路由;訪問 Redis Cluster 應使用 lua-resty-redis-cluster-fast。
舊版使用
以下保留舊實現的 Nginx 配置和 Lua 示例;新版請使用上面的配置並核對介面差異。
Nginx 配置
在使用前需要在配置檔案 nginx.conf 中需要新增以下這些配置項,用以載入 lua-resty-redis-fast 相關的動態模組。
...
load_module "/usr/local/openresty-coro-nginx-module/lib/ngx_http_coro_module.so";
load_module "/usr/local/openresty-coro-nginx-module/lib/ngx_http_coro_hiredis_module.so";
http {
coro_preload /usr/local/openresty-plus/hiredis/lib/libhiredis.so;
coro_stack_size 32768;
...
}
Lua 介面
除了 set_keepalive 介面發生了變化,該庫的其他介面和開源的 lua-resty-redis 保持一致,以下是一個簡單的例子:
load_module "/usr/local/openresty-coro-nginx-module/lib/ngx_http_coro_module.so";
load_module "/usr/local/openresty-coro-nginx-module/lib/ngx_http_coro_hiredis_module.so";
http {
coro_preload /usr/local/openresty-plus/hiredis/lib/libhiredis.so;
coro_stack_size 32768;
server {
location /test {
# need to specify the resolver to resolve the hostname
resolver 8.8.8.8;
content_by_lua_block {
local redis = require "resty.redis.fast"
local red = redis:new()
red:set_timeout(1000) -- 1 sec
local ok, err = red:connect("127.0.0.1", $TEST_NGINX_REDIS_PORT)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ok, err = red:select(1)
if not ok then
ngx.say("failed to select: ", err)
return
end
local res, err = red:set("dog", "an animal")
if not res then
ngx.say("failed to set dog: ", err)
return
end
local ok, err = red:set_keepalive()
if not ok then
ngx.say("failed to set keepalive: ", err)
return
end
}
}
}
}