redis使用lua腳本實現原子性執行多個命令


1、場景

使用 redis 作為延遲隊列時,在 zrangebyscorezrem 之間會存在 context switch 的情況,造成其他的消費者空轉
在其他場景下可能會發生更嚴重的情況
在掘金小冊《Redis 深度歷險:核心原理與應用實踐》第四章講的比較清楚,最后作者留了一個思考題
使用 Lua Scripting 來優化延時隊列的邏輯。
於是,我就用 redis 試了一下

2、編寫腳本

local value = redis.call("zrangebyscore", "delay-queue", 0, ARGV[1], "LIMIT", "0", "1")
if not value or not value[1] then
    return nil
end
redis.log(redis.LOG_DEBUG, cjson.encode(value))
redis.call("zrem", "delay-queue", value[1])
return value[1]
  1. 腳本中執行 redis 命令可以使用 call 和 pcall ,區別是 call 遇見錯誤會拋出,pcall 會返回出來一個帶錯誤的 err

  2. 腳本的返回值會轉換成 redis 的回復返回給客戶端

  3. 腳本的參數會傳到 ARGV table 中

  4. lua 的 index 從 1 開始

3、加載腳本

腳本我寫在了文件里面 popzset.lua

redis-cli -x script load < popzset.lua

加載腳本之后會返回一個摘要值

image-20200621194900496

4、執行腳本

evalsha "520a9dd32adf29721b0d925e0fb338aa3c32ea66" {程序生成的時間}

image-20200621195734194

5、參考資料

https://redisbook.readthedocs.io/en/latest/feature/scripting.html

http://redis.io/commands/eval

http://redis.io/commands/evalsha

http://redis.io/commands/script-load


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM