線程數設多少合適??

線程數設多少合適??

提問:工作線程數是不是設置的越大越好?
回答:肯定不是的
1)一來服務器CPU核數有限,同時併發的線程數是有限的,1核CPU設置10000個工作線程沒有意義
2)線程切換是有開銷的,如果線程切換過於頻繁,反而會使性能降低

提問:如果CPU是單核,設置多線程有意義麼,能提高併發性能麼?
回答:即使是單核,使用多線程也是有意義的
1)多線程編碼可以讓我們的服務/代碼更加清晰,有些IO線程收發包,有些Worker線程進行任務處理,有些Timeout線程進行超時檢測
2)如果有一個任務一直佔用CPU資源在進行計算,那麼此時增加線程並不能增加併發,例如這樣的一個代碼
while(1){ i++; }
該代碼一直不停的佔用CPU資源進行計算,會使CPU佔用率達到100%
3)通常來說,Worker線程一般不會一直佔用CPU進行計算,此時即使CPU是單核,增加Worker線程也能夠提高併發,因爲這個線程在休息的時候,其他的線程可以繼續工作

工作線程的工作模式

這裏寫圖片描述

上圖是一個典型的工作線程的處理過程,從開始處理start到結束處理end,該任務的處理共有7個步驟:
1)從工作隊列裏拿出任務,進行一些本地初始化計算,例如http協議分析、參數解析、參數校驗等
2)訪問cache拿一些數據
3)拿到cache裏的數據後,再進行一些本地計算,這些計算和業務邏輯相關
4)通過RPC調用下游service再拿一些數據,或者讓下游service去處理一些相關的任務
5)RPC調用結束後,再進行一些本地計算,怎麼計算和業務邏輯相關
6)訪問DB進行一些數據操作
7)操作完數據庫之後做一些收尾工作,同樣這些收尾工作也是本地計算,和業務邏輯相關

分析整個處理的時間軸,會發現:
1)其中1,3,5,7步驟中【上圖中粉色時間軸】,線程進行本地業務邏輯計算時需要佔用CPU
2)而2,4,6步驟中【上圖中橙色時間軸】,訪問cache、service、DB過程中線程處於一個等待結果的狀態,不需要佔用CPU,進一步的分解,這個“等待結果”的時間共分爲三部分:
2.1)請求在網絡上傳輸到下游的cache、service、DB
2.2)下游cache、service、DB進行任務處理
2.3)cache、service、DB將報文在網絡上傳回工作線程

量化分析併合理設置工作線程數

最後一起來回答工作線程數設置爲多少合理的問題。
通過上面的分析,Worker線程在執行的過程中,有一部計算時間需要佔用CPU,另一部分等待時間不需要佔用CPU,通過量化分析,例如打日誌進行統計,可以統計出整個Worker線程執行過程中這兩部分時間的比例,例如:
1)時間軸1,3,5,7【上圖中粉色時間軸】的計算執行時間是100ms
2)時間軸2,4,6【上圖中橙色時間軸】的等待時間也是100ms
得到的結果是,這個線程計算和等待的時間是1:1,即有50%的時間在計算(佔用CPU),50%的時間在等待(不佔用CPU):
1)假設此時是單核,則設置爲2個工作線程就可以把CPU充分利用起來,讓CPU跑到100%
2)假設此時是N核,則設置爲2N個工作線程就可以把CPU充分利用起來,讓CPU跑到N*100%

結論:

N核服務器,通過執行業務的單線程分析出本地計算時間爲x,等待時間爲y,則工作線程數(線程池線程數)設置爲 N*(x+y)/x,能讓CPU的利用率最大化。

經驗:

一般來說,非CPU密集型的業務(加解密、壓縮解壓縮、搜索排序等業務是CPU密集型的業務),瓶頸都在後端數據庫,本地CPU計算的時間很少,所以設置幾十或者幾百個工作線程也都是可能的。

發佈了125 篇原創文章 · 獲贊 36 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章