Redis事務
可以一次執行多個命令,本質是一組命令的集合。一個事務中的所有命令都會序列化,按順序地串行執行而不會被其他命令插入,不許加塞。
一個隊列中,一次性、順序性、排他性的執行一系列命令。
Redis事務VS數據庫事務
常用命令
情況1:正常執行
MULTI 與 EXEC
multi執行后開啟事務,把后續的每條執行命令放在隊列QUEUE中,當輸入exec執行命令后,隊列中的相關指令才開始執行。
情況2:放棄事務
MULTI與DISCARD
情況3:全體連坐
在往隊列中添加命令時,某個命令是錯誤的命令,語法編譯錯誤,那么執行exec的操作會報出異常,無法繼續完成隊列中的命令。
情況4:冤頭債主
這種是命令執行異常,不是命令編譯異常
Redis不能提供事務的回滾功能,開發者必須在事務執行出錯以后,自行恢復數據庫的狀態。
特別注意與傳統數據庫事務的區別,不一定要么一起成功,要么一起失敗。
情況5: watch監控
Redis使用Watch來提供樂觀鎖定,類似于CAS(Check-and-Set)
悲觀鎖:顧名思義,就是很悲觀,每次去拿數據的時候都認為別人會修改,所以每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會block直到它拿到鎖。
樂觀鎖:顧名思義,就是很樂觀,每次去拿數據的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此次期間別人有沒有去更新這個數據。
樂觀鎖的策略:提交的版本必須大于記錄當前版本才能執行更新。
CAS
watch操作
監控并順利的執行
監控
在 set balance 200的時候,另外一個事務執行了set balance 300
由于balance的值被另外一個事務修改了,再次執行事務的提交exec操作,執行失敗。
unwatch 可以放棄對于key的監控操作
redis事務小結
- 一旦執行了exec之前加的監控鎖都會被取消掉了。
- 當客戶端連接丟失的時候(如退出連接),所有的東西都會被取消監視。
Redis管道
如何優化頻繁的命令往返造成的性能瓶頸?
解決思路—管道
Pipeline是為了解決RTT往返時,僅僅是將命令打包成一次性發送,對整個redis的執行不造成其他任何影響。批處理命令的變種優化方式,類似redis的原生批命令(mget與mset)
redis的管道執行,將命令打包到一個txt文件中,cat讀取結果集,同時執行后續的redis-cli的命令,批量執行txt文件中的命令。類似于SQL腳本的感覺
結果查詢
管道與原生批量命令的對比
- 原生批量命令是原子性的(mget mset),pipeline是非原子性的
- 原生批量命令一次只能執行一種命令,pipeline支持批量執行不同命令
- 原生批量命令是服務端實現,pipeline需要服務端與客戶端共同完成。
Pipeline與事務的對比
- 事務具有原子性,管道不具有原子性
- 管道一次性將多條命令發送到服務器,事務是一條一條的發,事務只有在接收到exec命令后才會執行,管道不會
- 執行事務時阻塞其他命令的執行,而執行管道中的命令時不會
使用pipeline的注意點
官網地址
Redis 事務
Redis 管道