解密TaurusDB儲存端高併發之執行緒池

2022-01-11 02:24:45 字數 2722 閱讀 5420

摘要:為了能加快相關任務的高效執行,taurusdb採用多執行緒技術處理的方式,增加處理器單元的吞吐能力,從而提高儲存端的執行效率。
隨著雲計算進入2.0時代,資料急劇膨脹,這對實現資料庫的高可靠、高效能、高吞吐的目標產生了巨大的挑戰。如圖1 所示,taurusdb是華為自研的最新一代企業級具備橫向擴充套件、海量儲存能力的分布式資料庫,其採用了計算儲存分離,一寫多讀的分布式架構。將原本計算層的高密度儲存相關壓力下沉到儲存層,極大地釋放了計算層的算力。但同時將原來的儲存io轉移到了網路io,這也就是意味著,儲存層將面臨來自計算層風暴級的壓力。如果儲存層不能快速響應計算層的讀寫請求,會極大影響使用者的使用體驗。

圖1 taurusdb整體架構

圖2 slice功能元件

從圖2可知,taurusdb的儲存層,不單單只做儲存相關的工作,也需要大量的算力,比如consolidation生成特定資料頁、compation**舊版本資料、bufferpool快取熱點資料頁等任務。為了能加快這些任務的高效執行,我們首先能想到的就是能夠並行執行這些任務,也就是採用多執行緒技術處理的方式,增加處理器單元的吞吐能力,從而提高儲存端的執行效率。

2.1執行緒為什麼需要池化

首先,執行緒是稀缺的資源,如果頻繁建立和銷毀執行緒的開銷是可觀的,所占用的時間可能多於實際任務的執行;且當需要執行任務時,都去建立乙個對應的執行緒去處理,那麼伺服器的資源(比如位址空間和核心引數)很快就會被耗盡,導致而導致oom問題。

其次,通過事先建立好一定數量的執行緒並置於公共池之中,這樣當有任務需要執行時,只需從公共池取乙個執行緒執行當前的任務即可,待任務結束後,此執行緒又可以執行其他任務或處於休眠狀態,等待下一次被排程,達到執行緒資源重複使用的目的。

2.2執行緒池如何管理

為了能有效的管理多執行緒,taurusdb儲存端採用了如圖3的執行緒池模型。

圖3 執行緒池模型

threadpool: 主要負責控制線程池的大小、狀態變更、執行緒的建立、銷毀、排程策略的選取;

scheduler:負責具體任務的接收、被排程的順序,並觸發任務的執行;

worker:負責具體任務的執行;

monitor:負責監控執行緒執行任務時是否出現異常,以及異常告警,比如執行緒執行一次任務長時間執行未能結束。

2.3 執行緒池的排程策略

當前taurusdb儲存端線程池支援三種策略:先進先出排程(fifoscheduler)、定時排程(timescheduler)、基於容量排程(capacityscheduler)。

對於fifoscheduler和timescheduler,比較容易理解。當有任務需要執行時,只需將此任務存放在乙個佇列即可,有scheduler按照順序逐一排程即可。

對於capacityscheduler,是一種基於事先為某一型別的任務預留可執行執行緒的思想,其預留的執行緒個數由下發任務的使用者指定。具體排程過程見圖4。

圖4 capacityscheduler排程

比如:初始化執行緒大小為10,tasktype1預留執行緒數4,tasktype2:預留執行緒數5,tasktypen:預留執行緒數4

當執行緒池處於如圖4狀態時,任務型別是1和3的尚未達到預留值,任務型別n已達到閾值。此時如果threadpool中處於idle的執行緒數為1,則該執行緒將會被排程到任務型別為2的佇列中。

2.4 任務異常監控告警

我們知道,一旦任務被排程的執行緒執行過程中,可能會出現異常情況,比如執行緒死鎖,導致該任務不能按照預期推進,輕者引發系統出現cpu、io等系統資源使用率飈高的情況,嚴重者會導致系統down情形。比如taurusdb的儲存端,執行log的checkpoint的執行緒出現長時間卡頓,會導致儲存端舊的log不能正常**,導致磁碟空間逐步膨脹,進而影響儲存端其他各個模組平滑的推進。如果能夠識別出處於異常狀態的執行緒,並能夠進行告警,基於事先自定義規則進行修復,將能夠持續保證儲存端業務的連續性。

執行緒池monitor元件就是用於識別處於異常狀態的執行緒,其基本思想就是,定期巡檢執行緒池中的各執行緒處於狀態,如果發現執行緒狀態長時間未更新,則判定該執行緒處於異常狀態,上報告警,並基於相應的處理規則處理。

從2.3中可以看出,capacityscheduler策略是基於實際在執行的執行緒數,作為idle執行緒執行緒被排程的依據,尚未衡量實時任務的重要程度。考慮這樣一種場景,如果有兩種型別的任務a、b,在某一時間,用於執行a、b任務的執行緒數恰好執行緒或差值極小,但b型別任務的優先順序大於a任務,這時可能出現idle執行緒被排程執行a型別任務,b型別任務不能分配到充足的執行緒數(預留值是靜態分配),用於加快推進任務的處理。

考慮的方案:

1.限制型別任務型別佇列的長度,這樣可以均衡各型別任務的排程,不至於某一類或幾類任務數過多;

2.在系統資源有限的前提下,支援動態伸縮執行緒池大小的功能,這樣可以在工作負載過重時,擴充執行緒池大小,用於排程到急需執行的任務;

3.099進一步細化capacityscheduler策略,採用任務的重要程度和實際執行的執行緒數的規則,作為idle執行緒被排程的依據。

點選關注,第一時間了解華為雲新鮮技術~

基於Erlang高併發測試之服務端準備

上篇介紹完客戶端準備,接下來就要對服務端環境進行配置了。服務端同樣也會遇到控制代碼開啟問題。修改方式也是參考上篇,如果是同一臺機子就不用修改啦。剛開始我也只是以為都配置好了。但是在進行到10w資料量測試的時候發現,八萬多的連線久上不去。一直提示 超時 幾經周折,在dmesg指令下,我發現了一些錯誤報...

高併發之訊息佇列

比如乙個介面處理簡訊傳送,如果沒處理完就可以放入訊息佇列 然後等待介面處理,如果介面處理簡訊傳送失敗則可以再次放入訊息佇列,減少嘗試的次數和占用的執行緒,再次進行處理。舉幾個例子 業務系統觸發簡訊傳送申請,但簡訊傳送模組速度跟不上,需要將來不及處理的訊息暫存一下,緩衝壓力。就可以把簡訊傳送申請丟到訊...

java 高併發 之 鎖

synchronized 是屬於宣告式加鎖,可以修飾乙個 塊 乙個方法 乙個類,乙個靜態方法。修飾乙個 塊 public void test1 int j j,i 修飾乙個方法 public synchronized void test2 int j j,i 修飾乙個類 public static ...