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

EVAL、EVALSHA命令

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

腳本性能

  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模式的時候,可能會出現一些問題:

  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所在的節點壓力就會變大(不均衡),如果解決?歡迎留言討論~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章