1. 程式人生 > >【轉】Redis學習---阿裏雲Redis多線程性能增強版詳解

【轉】Redis學習---阿裏雲Redis多線程性能增強版詳解

com 同步速度 驅動 tro 模型 期望 edi 用戶態 事情

【原文】https://www.toutiao.com/i6594620107123589635/

摘要

Redis做為高性能的K-V數據庫,由於其高性能,豐富的數據結構支持,易用等特性,而得到廣泛的應用。但是由於redis單進程單線程的模型限制,單Redis Server QPS最高只能達到10萬級別。本文試圖通過對Redis做多線程的優化,來達到增強性能的目的。

二、背景

眾所周知redis是單進程單線程模型(不完全是單進程單線程,還有若幹後端線程主要做刷臟數據,關閉文件描述符等後臺清理工作)。redis中負責主要工作的是主線程,主線程的工作包括但不限:接收客戶端連接,處理連接讀寫事件,解析請求,處理命令,處理定時器事件,數據同步等相關工作。單進程單線程只能跑滿一個CPU核,在小包場景下,單個redis server的QPS在8~10萬級別。如果QPS超過這個級別,單個redis server就無法滿足需求。而常用的解決辦法就是數據分片,采用多server的分布式架構予以解決。然而數據分片,多redis server方式也存在若幹問題:redis server過多,難以管理;分片之後一些在單redis server上使用的命令無法支持;分片無法解決熱點讀寫問題;分片後數據傾斜,數據重分布,數據擴縮容等也比較復雜。由於單進程單線程的局限,我們期望通過多線程的改造以期充分利用SMP多核架構的優勢,從而達到提高單redis server吞吐的目的。對redis做多線程化,最容易想到的方案是每個線程既做IO又做命令處理等工作,但由於redis處理的數據結構相對比較復雜,多線程需要鎖來保證線程安全性,而鎖粒度處理不好性能反而可能會出現下降。

我們的思路是通過增加IO線程,將連接中數據的讀寫,命令的解析和數據包的回復放到單獨的IO線程來處理,而對命令的處理,定時器事件的執行等仍讓單一的線程來處理,以此達到提高單redis server吞吐的目的。

三、單進程單線程的優點和不足

1、優點

因為單進程單線程模型的限制,redis在實現上將耗時的操作分解成多步,多次來執行(例如dict rehash, 過期key刪除等操作),盡量避免長時間執行一個操作,從而避免長時間阻塞在一個操作上。單進程單線程代碼編寫簡單,可以減少多進程多線程導致的上下文切換和鎖的爭搶。

2、不足

  • 只能使用一個CPU核,無法發揮多核優勢。
  • 對於重IO應用來說,大量的cpu耗費在網絡IO操作上。對於將redis做為緩存的應用,往往都是重IO的應用。這類應用基本上都是QPS很高,使用的命令相對比較簡單(多為get,set,incr等操作),但是對RT響應很敏感。這類應用通常帶寬占用很高,甚至會跑到百兆級別。當前由於萬兆,25G網卡的普及,網絡往往已不再是瓶頸,而如何發揮多核優勢,充分發揮網卡性能成為需要考慮的事情。

四、實現

1、線程劃分

  • 主線程(MAIN THREAD)
  • IO線程(IO THREAD)
  • WORKER線程(WORKER THREAD)

2、線程模型

技術分享圖片

  • 主線程:接受連接,創建client,將連接轉發給IO線程。
  • IO線程:處理連接的讀寫事件,解析命令,將解析的完整命令轉發給WORKER線程處理,發送response包,負責刪除連接等。
  • WORKER線程:負責命令的處理,生成客戶端回包,定時器事件的執行等。
  • 主線程,IO線程,WORKER線程都有單獨的事件驅動。
  • 線程之間通過無鎖隊列交換數據,通過管道進行消息通知。

五、收益

1、 壓測結果

技術分享圖片

  • 從壓測結果來看,小包場景下,讀寫性能差不多有三倍左右的性能提升。

2、主從同步速度提升

3、主從同步優化

Master向Slave發送同步數據時,數據在IO線程中發送,Slave從主讀取數據時,全量數據在WORKER線程中讀取,增量數據在IO線程中讀取,因此可以相對比較有效的增加同步的速度。

4、後續工作

  • 現在所做的第一部分工作是增加IO線程,優化IO讀寫能力。進一步的優化可以考慮對WORKER線程進行拆分:每個線程既負責IO讀取,也負責WORKER工作處理。

5、IO線程數設置

  • 從測試結果來看,IO線程數最大不要超過6個。超過之後對簡單操作來說,WORKER線程往往已經成為瓶頸。
  • 進程在啟動時需要設置IO線程的個數,在進程運行期間IO線程個數無法修改,按當前的連接分配策略,修改IO線程的個數涉及到連接的重新分配,處理相對比較復雜。

六、展望

  • 隨著萬兆網卡,25G網卡的普及,如何充分利用硬件的性能需要充分的考慮。多網絡IO線程,By pass內核的用戶態協議棧等都是可利用的技術。
  • 通過IO線程實現數據的遷移,可以無阻塞,IO線程對數據進程Encode,或者命令轉發,目標節點實現數據Decode,或者命令執行。

【轉】Redis學習---阿裏雲Redis多線程性能增強版詳解