到底多少線程算是線程數太多?

jopen 10年前發布 | 11K 次閱讀 線程

  問題:

  我寫了一個服務,并為每個請求分配一個線程來處理,我這樣做的原因是因為基本上每個請求都是一次數據庫的查詢操作。我使用了一個線程池的庫來減少線程的創建和銷毀。

  我的問題是:像這樣的I/O多線程,什么才是一個好的臨界點?我知道這需要一個粗略的估計值,但這個值應該是幾百呢還是幾千?

  更新:

  非常感謝你們所有的回答,看起來我需要去測試找出線程數上限,問題是:我怎么知道線程數已經到達了上限?我究竟該如何去測量?

  回答:

  有的人可能會說,兩個線程就算是太多的線程了。我不是特別同意這種看法。

  我的建議是:測試,而不是猜想。我建議把線程數設置為可配置的,并初始化為 100 個線程,然后運行你的軟件并對它進行監控。

  如果線程的使用峰值才為3,那說明 100 個線程就是太多了。如果一天中的大部分時間都保持在 100 個線程,那就將線程的數量提高到 200,然后再監視其運行情況。

  你確實可以讓你的代碼自動監控線程的使用,并在下次啟動的時候自動修改配置選項,但沒必要這么做。

  詳述:

  我不支持經常變動你的線程池,而是盡可能的使用某一個值,你可能會問一個線程池合適的臨界點是什么,現假定你的線程池可以限制線程池的最大線程數(這是一件非常好的事情)。

  我寫過線程池和數據庫連接池,他們擁有以下最基本的特征(我認為這些對系統的性能來說是必要的):

  • 最小活動線程數
  • 最大線程數
  • 多久關閉一個未被使用的線程

  第一條是為了確保線程池的最低性能標準(這些線程是一直可以被使用的)。第二條是為了限制活動線程的資源使用。第三條是在一定的時間內將線程數返回到基準的設置,以減少資源的使用。

  你需要去平衡線程未被完全使用(情況A)和沒有足夠的工作線程(情況B)的情況。

  A 通常指內存的使用(棧等等),因為一個不工作的線程不會占用太多的 CPU 資源。B通常會延遲處理到達請求,直到有可以使用的線程。

  這就是為什么要去測算,正如你遇到的這種情況,絕大部分線程需要等待數據庫的響應才能運行。這就有兩個主要因素影響線程的數量:

  第一個因素是數據庫的有效連接數。這是一個硬性的限制,除非你能通過數據庫管理系統增加數據庫的連接數。在這里,我假設你的數據庫管理系統能夠承擔的數據庫連接數是無限制的。(雖然,理想情況下,你也應該測量一下)

  其次,線程數量應該依賴于你系統的歷史運行情況。最小的線程數你應該設置為在歷史最低的線程數的基礎上加上A%和一個絕對的最小數值(例如,讓它也可被配置,就像A一樣)5。

  線程池的最大數應該設置為在歷史最大線程數的基礎上加上B%。

  你也應該監控你系統運行情況的變化,如果因為某些原因,在某一個非常重要的時刻,你的線程池使用率達到 100%(這將影響你客戶端的性能),這就應該增加你線程池所允許的最大線程的數量,使其再增加B%。

  對于“我究竟如何去測試”的回答:

  你應該明確測算當前運行(例如,等待數據庫調用的返回)負載下的最大線程數量。然后增加一個安全因子,如 10%(強調一下,很多人貌似把我舉得例子當做了固定的建議)

  此外,在生產環境下,這點也應該是需要去調節的。在剛開始的時候先估計一個值是沒問題的,但是,你永遠也無法預料生產環境下會產生什么情況(這就是為什么要把所有的這些都設置為運行時可配置的原因)。這就能應付各種客戶端調用時所出現的不可預期的情況。

  翻譯: ImportNew.com - paddx

  譯文鏈接: http://www.importnew.com/10911.html

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!