通過多執行緒處理提高Redis效能
Redis通常被稱為單程序單執行緒模型。
這不是真的!
Redis還執行多個後端執行緒來執行後端清理工作,例如清理髒資料和關閉檔案描述符。在Redis中,主執行緒負責主要任務,包括但不限於:接收來自客戶端的連線,處理連線讀/寫事件,解析請求,處理命令,處理定時器事件和同步資料。只有一個CPU核心執行單個程序和單個執行緒。
對於小資料包,Redis伺服器可以處理80,000到100,000 QPS。更大的QPS超出了Redis伺服器的處理能力。常見的解決方案是在分散式架構中對資料進行分割槽並採用多個伺服器。
然而,該解決方案也具有許多缺點。例如,要管理的Redis伺服器太多; 某些適用於單個Redis伺服器的命令不適用於資料分割槽; 資料分割槽無法解決熱點讀/寫問題; 資料偏斜,重新分配和放大/縮小變得更加複雜。由於單程序和單執行緒的限制,我們希望可以重構多執行緒以充分利用SMP多核架構的優勢,從而提高單個Redis伺服器的吞吐量。
要使Redis成為多執行緒,最簡單的思考方式是每個執行緒都執行I / O和命令處理。但是,由於Redis處理的資料結構很複雜,多執行緒需要使用鎖來確保執行緒安全。鎖定粒度的不正確處理可能會降低效能。
我們建議增加I / O執行緒的數量,以使獨立的I / O執行緒能夠讀取/寫入連線,解析命令和回覆資料包中的資料,並且仍讓單個執行緒處理命令並執行計時器事件。這樣,可以增加單個Redis伺服器的吞吐量。
單程序和單執行緒模型
好處
-
由於單程序和單執行緒模型的限制,耗時的操作(例如dict rehash和過期的金鑰刪除)被分解為多個步驟並在Redis實現中逐個執行。這防止了操作長時間執行,因此避免了操作對系統的長時間阻塞。單程序和單執行緒程式碼易於編譯,這減少了由多程序和多執行緒引起的上下文切換和鎖定佔用。
缺點
-
只能使用一個CPU核心,無法利用多核優勢。
-
對於繁重的I / O應用程式,網路I / O操作會消耗大量CPU容量。使用Redis作為快取的應用程式通常是繁重的I / O應用程式。這些應用程式基本上具有高QPS,使用相對簡單的命令(例如get,set和incr),但是對RT敏感。它們通常具有高頻寬使用率,甚至可能達到數百兆位元。由於10 GB和25 GB網路介面卡的普及,網路頻寬不再是瓶頸。因此,我們需要考慮的是如何利用多核的優勢和網路介面卡的效能。
多執行緒模型與實現
執行緒模型
有三種執行緒型別,即:
-
主執行緒
-
I / O執行緒
-
工人執行緒
-
-
主執行緒:接收連線,建立客戶端,並轉發到I / O執行緒的連線。
-
I / O執行緒:處理連線讀/寫事件,解析命令,將完整解析的命令轉發到工作執行緒進行處理,傳送響應資料包並刪除連線。
-
工作執行緒:處理命令,生成客戶端響應資料包,並執行計時器事件。
-
主執行緒,I / O執行緒和工作執行緒分別由事件驅動。
-
執行緒通過無鎖佇列交換資料,並通過隧道傳送通知。
多執行緒模型的好處
提高讀/寫效能
壓力測試結果表明,在小資料包場景中,讀/寫效能可提高約三倍。
-
-
提高主/從同步速度
當主裝置將同步資料傳送到從裝置時,資料將在I / O執行緒中傳送。從主站讀取資料時,從站從工作執行緒讀取完整資料,從I / O執行緒讀取增量資料。這可以有效地提高同步速度。
後續任務
第一項任務是增加I / O執行緒數並優化I / O讀/寫功能。接下來,我們可以分解工作執行緒,以便每個執行緒完成I / O讀取,以及工作執行緒的工作。
設定I / O執行緒數
-
測試結果表明I / O執行緒的數量不應超過6.否則,工作執行緒將成為簡單操作的瓶頸。
-
在啟動程序時,必須設定I / O執行緒的數量。程序執行時,無法修改I / O執行緒數。根據當前的連線分配策略,修改I / O執行緒的數量涉及重新分配連線,這非常複雜。
注意事項
-
隨著10 GB和25 GB網路介面卡的普及,必須仔細考慮如何充分利用硬體效能。我們可以使用技術,例如用於networkI / O的多執行緒和核心繞過使用者模式協議棧。
-
I / O執行緒可用於實現無阻塞資料遷移。I / O執行緒對資料程序進行編碼或轉發命令,而目標節點對資料進行解碼或執行命令。
————————————————————
推薦閱讀:
-