首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> DB2 資料庫 >> DB2 教學

Redis Lua 腳本權威指南:EVAL/EVALSHA、型別轉換、原子性、快取與最佳實踐

     編輯:DB2 教學

EVAL 與 EVALSHA 核心語法

Redis 2.6+ 內建 Lua 5.1 解釋器。EVAL script numkeys key [key ...] arg [arg ...]

  • 第 1 參數:Lua 腳本本體(無需定義函數)。
  • 第 2 參數:鍵名數量,後續對應 KEYS[1]..KEYS[n](1-based 陣列)。
  • 剩餘參數:透過 ARGV[1]..ARGV[m] 存取。
> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
1) "key1"  2) "key2"  3) "first"  4) "second"

Lua ↔ Redis 型別轉換規則

Redis → LuaLua → Redis
Integer → numbernumber → Integer (捨去小數)
Bulk Reply → stringstring → Bulk Reply
Multi Bulk → table (可巢狀)table (陣列) → Multi Bulk (遇 nil 截斷)
Status → {ok=狀態}{ok=狀態} → Status Reply
Error → {err=錯誤}{err=錯誤} → Error Reply
Nil → falsefalse → Nil Bulk Reply
true → Integer 1

輔助函數:redis.error_reply(msg)、redis.status_reply(msg)。

腳本原子性與錯誤處理

  • 原子性:執行期間阻塞所有其他命令,類似 MULTI/EXEC。
  • redis.call():命令報錯 → 拋出 Lua 錯誤 → EVAL 返回錯誤。
  • redis.pcall():捕獲錯誤 → 返回錯誤表,腳本可自行處理。

EVALSHA 與腳本快取

EVALSHA sha1 numkeys ... 避免重複傳送腳本本文,節省頻寬。Redis 永久快取已執行腳本(除非 SCRIPT FLUSH 或重啟)。

管道化場景建議:SCRIPT LOAD 預載 → 管道內直接 EVALSHA,或客戶端樂觀發送 EVALSHA 失敗再退回 EVAL。

SCRIPT 管理命令

  • SCRIPT FLUSH:清空快取(雲環境切換租戶必備)。
  • SCRIPT EXISTS sha1 ...:檢查腳本是否在快取(返回 1/0 陣列)。
  • SCRIPT LOAD script:載入腳本至快取不執行。
  • SCRIPT KILL:終止超時的唯讀腳本;已寫入數據則只能 SHUTDOWN NOSAVE。

純函數限制與隨機數技巧

腳本必須為純函數:相同輸入必產生相同寫操作。禁用 TIME、RANDOMKEY 等非確定性命令(唯讀腳本除外)。Lua math.random 種子固定,每次執行序列相同。

需隨機性時:客戶端生成種子作為參數傳入,腳本用 math.randomseed(ARGV[1]),確保主從/AOF 重放一致。

全域變數保護與可用庫

  • 禁止建立全域變數(洩露 Lua 狀態),違者報錯。請用 local 關鍵字。
  • 內建庫:base, table, string, math, debug, struct, cjson, cmsgpack, bitop, redis.sha1hex。

日誌、沙箱與執行上限

  • redis.log(level, msg) 寫入 Redis 日誌(level: DEBUG/VERBOSE/NOTICE/WARNING)。
  • 預設最大執行時間 5 秒(lua-time-limit 可調),超時不自動終止,但進入 BUSY 狀態僅接受 SCRIPT KILL/SHUTDOWN NOSAVE。

SELECT 行為變更 (2.8.12+)

腳本內 SELECT 僅影響腳本自身執行上下文,不再改變客戶端連線的資料庫號。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved