Python Redis如何執(zhí)行Lua腳本
問題描述
Python Redis 執(zhí)行 Lua 腳本可實(shí)現(xiàn)原子性
官方文檔表示,Redis 使用相同的 Lua 解釋器來(lái)運(yùn)行所有命令,Redis 保證腳本以原子方式執(zhí)行:
- 在執(zhí)行腳本時(shí)不會(huì)執(zhí)行其他腳本或 Redis 命令。
- 這種語(yǔ)義類似于
MULTI
/EXEC
的語(yǔ)義,從所有其他客戶的角度來(lái)看,腳本的效果要么仍然不可見,要么已經(jīng)完成。
解決方案
安裝
pip install redis
代碼
from redis import Redis redis = Redis() script = """ redis.call('SETEX', 'key', 100, 'value') """ redis.register_script(script)() # 執(zhí)行腳本
效果
傳遞參數(shù)
Script 類調(diào)用函數(shù)原型:
def __call__(self, keys=[], args=[], client=None)
from redis import Redis redis = Redis() script = """ local key = KEYS[1] local seconds = ARGV[1] local value = ARGV[2] redis.call('SETEX', key, seconds, value) """ cmd = redis.register_script(script) cmd(keys=['key'], args=[100, 'value']) # 執(zhí)行腳本
效果同上
分布式鎖
1.加鎖并設(shè)過期時(shí)間 SET lock_resource_name $uuid NX PX $expire_time
,同時(shí)啟動(dòng)守護(hù)線程為快要過期單還沒執(zhí)行完畢的客戶端的鎖續(xù)命;
2.客戶端執(zhí)行業(yè)務(wù)邏輯操作共享資源;
3.通過 Lua
腳本釋放鎖,先 get 判斷鎖是否是自己加的,再執(zhí)行 DEL
。
判斷+刪除
import time from uuid import uuid4 from redis import Redis redis = Redis() # 判斷是否自己創(chuàng)建的鎖,是的話則釋放 script = """ if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) else return 0 end """ def do_something(): name = 'lock' # 鎖名,此處故意寫死讓別的進(jìn)程進(jìn)來(lái)占用 uuid = str(uuid4()) # 上鎖 if redis.set(name=name, value=uuid, nx=True, ex=25): # 鎖不存在才能上鎖成功,過期時(shí)間應(yīng)為業(yè)務(wù)時(shí)間的五倍,此處故意寫小,模擬過期釋放 print('上鎖') try: print('處理業(yè)務(wù)', uuid) time.sleep(10) except Exception as e: print(e) finally: # 釋放鎖 cmd = redis.register_script(script) res = cmd(keys=[name], args=[uuid]) # 執(zhí)行腳本 if res: print('鎖已釋放') else: print('不是自己的鎖') else: print('鎖已存在') if __name__ == '__main__': do_something()
模擬過程:
- 運(yùn)行程序1
- 手動(dòng)迅速刪掉這個(gè)鎖
- 運(yùn)行程序2
效果:
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Caffeine實(shí)現(xiàn)類似redis的動(dòng)態(tài)過期時(shí)間設(shè)置示例
這篇文章主要為大家介紹了Caffeine實(shí)現(xiàn)類似redis的動(dòng)態(tài)過期時(shí)間示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08redis數(shù)據(jù)結(jié)構(gòu)之壓縮列表
這篇文章主要介紹了redis數(shù)據(jù)結(jié)構(gòu)之壓縮列表,壓縮列表是列表list和hash數(shù)據(jù)結(jié)構(gòu)的底層實(shí)現(xiàn)之一,是redis為了節(jié)約內(nèi)存而開發(fā)的,由一系列特殊編碼的連續(xù)內(nèi)存塊組成的順序型數(shù)據(jù)結(jié)構(gòu),下面詳細(xì)內(nèi)容需要的小伙伴可以參考一下2022-03-03一文詳解如何使用Redis實(shí)現(xiàn)分布式鎖
這篇文章主要介紹了一文詳解如何使用Redis實(shí)現(xiàn)分布式鎖,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09Redis7.2.x主從復(fù)制的實(shí)現(xiàn)示例
本文主要介紹了Redis7.2.x主從復(fù)制的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-06-06為何Redis使用跳表而非紅黑樹實(shí)現(xiàn)SortedSet
本篇文章主要介紹了為何Redis使用跳表而非紅黑樹實(shí)現(xiàn)SortedSet,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09在CentOS 7環(huán)境下安裝Redis數(shù)據(jù)庫(kù)詳解
Redis是一個(gè)開源的、基于BSD許可證的,基于內(nèi)存的、鍵值存儲(chǔ)NoSQL數(shù)據(jù)本篇文章主要介紹了在CentOS 7環(huán)境下安裝Redis數(shù)據(jù)庫(kù)詳解,有興趣的可以了解一下。2016-11-11Web-ssrfme:redis 未授權(quán)訪問攻擊的問題解決
本文主要介紹了Web-ssrfme:redis 未授權(quán)訪問攻擊的問題解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-04-04Redis分布式鎖如何設(shè)置超時(shí)時(shí)間
這篇文章主要介紹了Redis分布式鎖如何設(shè)置超時(shí)時(shí)間,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11