Redis高併發的問題
Redis緩存的高性能有目共睹,應用的場景也是非常廣泛,但是在高併發的場景下,也會出現問題:
高併發架構系列:Redis緩存和MySQL數據一致性方案詳解
以及今天要談到的Redis併發競爭問題,這裏的併發指的是多個redis的client同時set key引起的併發問題。
比如:多客戶端同時併發寫一個key,一個key的值是1,本來按順序修改爲2,3,4,最後是4,但是由於併發設置的原因,最後順序變成了4,3,2,最後變成的key值成了2。
如何解決Redis的併發競爭key問題
第一種方案:分佈式鎖
1.整體技術方案
這種情況,主要是準備一個分佈式鎖,大家去搶鎖,搶到鎖就做set操作。
2.爲什麼是分佈式鎖
因爲傳統的加鎖的做法(如java的synchronized和Lock)這裏沒用,只適合單點。因爲這是分佈式環境,需要的是分佈式鎖。
當然,分佈式鎖可以基於很多種方式實現,比如zookeeper、redis等,不管哪種方式實現,基本原理是不變的:用一個狀態值表示鎖,對鎖的佔用和釋放通過狀態值來標識。
3.分佈式鎖的要求
- 互斥性:在任意一個時刻,只有一個客戶端持有鎖。
- 無死鎖:即便持有鎖的客戶端崩潰或者其他意外事件,鎖仍然可以被獲取。
- 容錯:只要大部分Redis節點都活着,客戶端就可以獲取和釋放鎖
4.分佈式鎖的實現方式
- 數據庫
- Memcached(add命令)
- Redis(setnx命令)
- Zookeeper(臨時節點)
具體的分佈式鎖實現,請參考:阿里P8架構師談:分佈式鎖的3種實現(數據庫、緩存、Zookeeper)
第二種方案:利用消息隊列
在併發量過大的情況下,可以通過消息中間件進行處理,把並行讀寫進行串行化。
把Redis.set操作放在隊列中使其串行化,必須的一個一個執行。
這種方式在一些高併發的場景中算是一種通用的解決方案。
原文鏈接:http://youzhixueyuan.com/redis-concurrent-competition-solution.html