Redis中使用Lua的一些優化和注意事項

EVAL、EVALSHA命令

Redis從2.6.0版本開始提供了eval命令,經過內置的Lua解釋器,可讓用戶執行一段Lua腳本並返回數據。由於Redis單線程模型的特色,能夠保證多個命令的原子性(由於最近的項目纔想到用Lua),詳細的使用方法請移步官方文檔。node

腳本性能

  1. Redis保證了腳本執行的原子性,因此在當前腳本沒執行完以前,別的命令和腳本都是等待狀態,因此必定要控制好腳本中的內容,防止出現須要消耗大量時間的內容(邏輯相對簡單)。

帶寬優化

  1. 爲了不每次執行都重複的將Lua腳本內容發送,Redis提供了evalsha命令,只須要將Lua腳本內容的SHA1校驗和發送便可(evalsha 6b1bf486c81ceb7edf3c093f4c48582e38c0e791 0)。
  2. Lua腳本中的變量(動態數據)請使用KEYSARGV獲取,若是把變量放在腳本中,必然會致使每次的腳本內容都不一樣(SHA1),Redis緩存大量無用或者一次性的腳本內容。

Redis Cluster 或 阿里雲Redis集羣版使用注意事項

Redis從3.0開始支持了Cluster功能,以前使用eval的時候可能沒什麼問題,但當切換成Cluster模式的時候,可能會出現一些問題:redis

  1. ERR Error running script (call to f_4a610f5543b3c3450220da7bd47825d3b6bffae8): @user_script:1: @user_script: 1: Lua script attempted to access a non local key in a cluster node
  2. ERR eval/evalsha command keys must be in same slot(阿里雲Redis集羣版)

上面的錯誤是由於Redis要求單個Lua腳本操做的key必須在同一個節點上,可是Cluster會將數據自動分佈到不一樣的節點(虛擬的16384個slot,具體看官方文檔),阿里雲集羣版的官網其實也有對應說明:在Redis集羣版實例中,事務、腳本等命令要求全部的key必須在同一個slot中,若是不在同一個slot中將返回如下錯誤信息(:command keys must in same slot)小程序

如何解決?

CLUSTER KEYSLOT key的文檔中提供瞭解決方法,你須要將把key中的一部分使用{}包起來,redis將經過{}中間的內容做爲計算slot的key,相似key1{mykey}key2{mykey}這樣的都會存放到同一個slot中(缺點是不能平滑的過分老業務,須要修改原來使用的key,若是以前的key是統一管理的,也沒那麼麻煩)緩存

思考

若是某個業務都經過key{mykey}去儲存獲取內容,全部的操做都會hash到同一個slot,這個slot所在的節點壓力就會變大(不均衡),若是解決?歡迎留言討論~性能

開發了一個數獨小程序「惟一數獨」,歡迎掃描玩起來~

圖片描述

相關文章
相關標籤/搜索