Redis Lua指令碼實現復合操作原子化

2021-10-02 21:53:07 字數 2328 閱讀 9124

redis是高效能的key-value資料庫,在很大程度克服了memcached這類key/value儲存的不足,在部分場景下,是對關聯式資料庫的良好補充。得益於超高效能和豐富的資料結構,redis已成為當前架構設計中的首選key-value儲存系統。

雖然redis官網上提供了200多個命令,但做程式設計時還是避免不了為了實現一小步業務邏輯而多次呼叫redis的情況。

分布式redis計算,要滿足實現redis操作在同乙個應用,redis多不操作一次性呼叫完成,這種分散操作無法利用redis的原子特性,占用多次網路io。要滿足redis多步操作原子化,需要使用redis+lua指令碼的方式實現,。這種分散操作無法利用redis的原子特性,占用多次網路io。

流量控制/配額管控最關鍵的是要將限流服務做成原子化,而解決方案可以使使用redis+lua進行實現,通過這種技術可以實現的高併發和高效能。

lua 是乙個小巧的指令碼語言,幾乎可以執行在所有作業系統和平台上。我們一般不會用lua處理特別複雜的事務,因此只需了解一些lua的基本語法即可。

redis問世之後,其開發者也意識到了開篇提到的問題,因此redis從2.6版本開始支援lua指令碼。新版本的redis還支援lua script debug,感興趣的小夥伴可以去官網的documentation中找到對應介紹和quickstart。

有了lua指令碼之後,使用redis程式時便能夠在以下方面實現顯著提公升:

redis 127.0.0.1:6379> eval script  numkeys key [key ...] arg [arg ...]
如果只能在命令列中寫指令碼執行,遇到複雜的指令碼程式豈不是會抓狂?

下面我們來看一下,如何讓redis執行lua指令碼檔案,同時也驗證一下lua指令碼的復用特性(以後我們再也不需要定期批量刪除某些符合特定規則的key了)。

redis 127.0.0.1:6379> script load  script

redis 127.0.0.1:6379> evalsha sha1 numkeys key [key ...] arg [arg ...]

redis提供了乙個scriptload命令,命令後面的script即為lua指令碼。命令將指令碼script新增到指令碼快取中,但並不立即執行這個指令碼。執行命令後,redis會返回乙個sha1串,第二個evalsha命令即可執行。

需要注意的是,指令碼可以在快取中保留無限長的時間,直到執行完script flush。

public object eval(final string script, final int keycount, final string... params) 

public object eval(final string script, string samplekey)

public object eval(final string script, final listkeys, final listargs)

public long limitrate(string key,string timeout)

public long quotarate(string key,string threshold,string timeout)

lua指令碼:

limitscript:

local times = redis.call('incr',keys[1])

if times == 1 then

redis.call('expire',keys[1], ar**[1])

end

return times

quotascript:

if redis.call('exists',keys[1]) == 1 then

local valuestr = redis.call('get',keys[1])

local value = tonumber(valuestr)

local maxcount = tonumber(ar**[2])

if value > maxcount then

return value

endlocal times = redis.call('incr',keys[1])

return times

else

local times = redis.call('incr',keys[1])

if times == 1 then

redis.call('expire',keys[1], ar**[1])

endreturn times

end

居於redis lua指令碼實現的滑動視窗

我們常常使用滑動視窗實現限流操作,在單機時我們經常放在記憶體中實現,而在做全域性介面限流時,我們除了可以通過查詢介面呼叫記錄外,還可以通過依賴redis實現的滑動視窗進行,比如限制1分鐘可呼叫1000次,一小時可呼叫10000次。1 乙個固定長度的迴圈佇列 2 每個時間片的時長,可以是按秒 分 時。...

REDIS LUA指令碼使用經驗分享

redis lua指令碼出現之前redis是沒有伺服器端運算能力的,主要是用來儲存,用做快取用,運算是在客戶端進行,這樣帶來了很大的頻寬流量。lua出現之後這一問題得到了充分的解決,非常棒!redis lua指令碼api介紹 eval 在redis伺服器端執行lur指令碼 evalsha 在redi...

Redis Lua指令碼編寫快速指南

您應該在系統上安裝redis才能執行本文中的例子。閱讀本文時對照redis命令參考可能會更有幫助。簡而言之 效能提公升。您在redis中執行的大多數任務都涉及許多步驟。您可以使用lua在redis內部進行操作,而不必使用應用程式語言來執行這些步驟。例如,我使用lua指令碼改變儲存在redis的jso...