Python Redis如何執(zhí)行Lua腳本
問題描述
Python Redis 執(zhí)行 Lua 腳本可實(shí)現(xiàn)原子性
官方文檔表示,Redis 使用相同的 Lua 解釋器來運(yùn)行所有命令,Redis 保證腳本以原子方式執(zhí)行:
- 在執(zhí)行腳本時不會執(zhí)行其他腳本或 Redis 命令。
- 這種語義類似于
MULTI
/EXEC
的語義,從所有其他客戶的角度來看,腳本的效果要么仍然不可見,要么已經(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è)過期時間 SET lock_resource_name $uuid NX PX $expire_time
,同時啟動守護(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)來占用 uuid = str(uuid4()) # 上鎖 if redis.set(name=name, value=uuid, nx=True, ex=25): # 鎖不存在才能上鎖成功,過期時間應(yīng)為業(yè)務(wù)時間的五倍,此處故意寫小,模擬過期釋放 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
- 手動迅速刪掉這個鎖
- 運(yùn)行程序2
效果:
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Caffeine實(shí)現(xiàn)類似redis的動態(tài)過期時間設(shè)置示例
這篇文章主要為大家介紹了Caffeine實(shí)現(xiàn)類似redis的動態(tài)過期時間示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(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)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-09-09Redis7.2.x主從復(fù)制的實(shí)現(xiàn)示例
本文主要介紹了Redis7.2.x主從復(fù)制的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-06-06為何Redis使用跳表而非紅黑樹實(shí)現(xiàn)SortedSet
本篇文章主要介紹了為何Redis使用跳表而非紅黑樹實(shí)現(xiàn)SortedSet,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09在CentOS 7環(huán)境下安裝Redis數(shù)據(jù)庫詳解
Redis是一個開源的、基于BSD許可證的,基于內(nèi)存的、鍵值存儲NoSQL數(shù)據(jù)本篇文章主要介紹了在CentOS 7環(huán)境下安裝Redis數(shù)據(jù)庫詳解,有興趣的可以了解一下。2016-11-11Web-ssrfme:redis 未授權(quán)訪問攻擊的問題解決
本文主要介紹了Web-ssrfme:redis 未授權(quán)訪問攻擊的問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-04-04