作者介紹
申政,開源愛好者,唯品會高級DBA,主要負責Redis相關領域的源碼研究和研發工作。
開源項目:
_ redis cluster的C客戶端(hiredis-vip)_
_ 集群遷移工具(redis-migrate-tool)_
_ 多線程版Twemproxy(Twemproxies)_
大家好,我是deep,今天跟大家分享下我們正在開發的多線程redis。在我們的redis使用中,發現了一些痛點問題,涉及到了redis框架的設計。
我們線上有大量的redis實例在運行,規模比較龐大,有些redis集群實例規模超過100+,我們開始對redis進行了多線程版本的改造,就是我們現在正在開發的產品vire。
這是vire的一個現狀,分幾個階段進行開發,現在是0.1.0版本。
以上是vire0.1.0的一些設計思路。下面說說具體實現:
這是vire的多線程模型,借鑒于memcached,master+worker線程模型。
這個圖比較直觀的反映了線程模型的工作原理,多線程不可避免會用到鎖,以下是vire的鎖機制:
這里有個邏輯DB的概念,其實就是把多個redis db偽裝成一個DB提供給用戶。DB級別的鎖,會不會性能很差呢?后續會有測試報告給出。
用戶使用的所有key,是通過key的hash值被分散到了各個物理db上,目的就是降低DB鎖的競爭提升qps,可以通過info 命令看到物理db中key的分布:
下面來看下成功執行一個redis命令要走的流程:
我們的db鎖是在哪一步使用呢?
有可能用到db鎖的步驟就是紅框中的兩步,但像ping這樣命令,在整個過程中是用不到db鎖的,可以看出,Worker線程在一部分時間是完全并行執行的,關于vire中的后臺線程:
Worker線程專注于處理客戶端的請求,雜活累活有backend線程來做,backend線程在vire后續版本中,會發揮更重要的作用。
這里是Vire代碼內部對object的處理,這里會有些性能退化。
這是vire對多key命令的一些特殊處理,死鎖的問題,導致個別redis命令在vire中暫時無法實現。
Vire中增加了一些權限管理,vire增加了管理員的角色,保證了一些危險命令不被開發執行。
下面說說vire的測試:
這里著重說說abtest和性能測試
為了保證vire的命令執行起來與redis一模一樣,我們開發了abtest測試框架。詳細說說abtest框架中各模塊的作用:
這個測試框架有效的幫我們發現了一些bug,以下是性能測試:
我們的目標就是性能接近或跟mc一樣,以下是hotkey測試:
hotkey的效果還不錯。
加入Redis中國用戶組
QQ群: 374538650, 521503946
微信群:Redis中國用戶組
Q&A:
- Q: 客戶端需要換嗎?
A:客戶端兼容,無需更換,使用起來跟原生redis一樣- Q: worker和db的關系是什么?
A: worker和db沒有關系, client是數據worker線程的, DB是完全獨立的- Q: 后期主備會支持嗎?
A: 以后會支持主備,集群和腳本等高級功能- Q: 有沒有想過把鎖降低至key級別?
A: 沒必要key級別的鎖- Q: 死鎖問題為何不通過順序鎖定相關db來解決呢,我們的redis是分布式鎖,通過按統一的順序鎖定,就可以避免死鎖
A: 鎖的數量會太多,你說的這個死鎖問題很好,有這樣的想法,但還沒有時間去驗證可不可行,以后可以嘗試。- Q: vire和redis-cluster比起來哪個性能更好?
A: redis-cluster是集群模式,vire是單實例,沒辦法比較性能,vire最后一個版本希望能支持到集群- Q: 給我的理解vire的多個邏輯db的設計原理和redis-cluster里多個分片原理是一樣吧?
A: 非常類似, 只不過redis-cluster里的slot是海量的,16384- Q: 現在redis-cluster的解決方案是客戶端自己計算slot的位置,可以通過根據操作的讀寫類型,實現負載均衡,vire采取的多db+多worker的方案,他這樣的優勢在哪里?
A: 主要是提升單個實例的qps能力- Q: 現在的設計是全部基于內存上的?服務器宕機是不是數據全都會消失
A: vire0.1.0版本數據全部在內存,只適合于做緩存, vire后續版本會做持久化和復制,甚至是集群