文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (美國信紙) - 39.9Mb
PDF (A4) - 40.0Mb
手冊頁 (TGZ) - 258.5Kb
手冊頁 (Zip) - 365.5Kb
資訊 (Gzip) - 4.0Mb
資訊 (Zip) - 4.0Mb


7.6.3.4 線程池調整

本節提供有關確定線程池效能最佳組態的指南,該效能以每秒交易次數等指標衡量。

最重要的因素是線程池中的線程群組數量,可以使用 --thread-pool-size 選項在伺服器啟動時設定;此設定無法在執行階段變更。此選項的建議值取決於主要使用的儲存引擎是 InnoDB 還是 MyISAM

  • 如果主要儲存引擎是 InnoDB,則線程池大小的建議值是主機上可用的實體核心數量,最多 512 個。

  • 如果主要儲存引擎是 MyISAM,則線程池大小應相當低。通常會看到 4 到 8 的值有最佳效能。較高的值往往會對效能產生輕微的負面影響,但影響不大。

線程池外掛程式可以處理的並行交易數量的上限由 thread_pool_max_transactions_limit 的值決定。此系統變數的建議初始設定值是實體核心數量乘以 32。您可能需要從這個起點調整值,以適合給定的工作負載;此值的合理上限是預期的並行連線的最大數量;Max_used_connections 狀態變數的值可以作為決定此值的指南。一個好的方法是從將 thread_pool_max_transactions_limit 設定為此值開始,然後在觀察對輸送量的影響時向下調整。

線程群組中允許的最大查詢執行緒數由 thread_pool_query_threads_per_group 的值決定,該值可以在執行階段調整。此值與線程池大小的乘積約等於可用於處理查詢的執行緒總數。要獲得最佳效能,通常意味著在 thread_pool_query_threads_per_group 和線程池大小之間為您的應用程式取得適當的平衡。thread_pool_query_threads_per_group 值較大時,當工作負載包含長和短執行查詢時,線程群組中的所有執行緒同時執行長時間執行的查詢而阻止較短的查詢的可能性較小。您應該記住,當使用較小的線程池大小和較大的 thread_pool_query_threads_per_group 值時,每個線程群組的連線輪詢操作的負擔會增加。因此,我們建議 thread_pool_query_threads_per_group 的起始值為 2;將此變數設定為較低的值通常不會提供任何效能優勢。

為了在正常情況下獲得最佳效能,我們還建議您將 thread_pool_algorithm 設定為 1 以實現高並行。

此外,thread_pool_stall_limit 系統變數的值決定了對已封鎖和長時間執行陳述式的處理方式。如果所有封鎖 MySQL 伺服器的呼叫都報告給線程池,則它會始終知道執行執行緒何時被封鎖,但這種情況不一定總是成立。例如,封鎖可能會發生在沒有使用線程池回呼進行儀器化的程式碼中。對於這種情況,線程池必須能夠識別似乎被封鎖的執行緒。這是透過由 thread_pool_stall_limit 的值確定的逾時來完成的,這確保了伺服器不會完全封鎖。thread_pool_stall_limit 的值表示 10 毫秒間隔的數量,因此 600 (最大值) 表示 6 秒。

thread_pool_stall_limit 也使線程池能夠處理長時間執行的陳述式。如果允許長時間執行的陳述式封鎖線程群組,則分配給該群組的所有其他連線都將被封鎖,並且無法開始執行,直到長時間執行的陳述式完成為止。在最壞的情況下,這可能需要數小時甚至數天。

應選擇 thread_pool_stall_limit 的值,使得執行時間超過該值的語句被視為停滯。停滯的語句會產生大量的額外開銷,因為它們涉及額外的上下文切換,在某些情況下甚至會產生額外的執行緒。另一方面,將 thread_pool_stall_limit 參數設定得太高,意味著長時間執行的語句會阻礙大量短時間執行的語句,且阻礙時間會比必要的時間長。較短的等待值允許執行緒更快啟動。較短的值也更適合避免死鎖情況。較長的等待值對於包含長時間執行語句的工作負載很有用,以避免在目前語句執行時啟動過多的新語句。

假設伺服器執行的工作負載中,即使伺服器處於負載狀態,仍有 99.9% 的語句在 100 毫秒內完成,而剩餘的語句則在 100 毫秒到 2 小時之間完成,並且分佈相當均勻。在這種情況下,將 thread_pool_stall_limit 設定為 10(10 × 10 毫秒 = 100 毫秒)會比較合理。預設值 6(60 毫秒)適用於主要執行非常簡單語句的伺服器。

可以在執行時變更 thread_pool_stall_limit 參數,以便您能夠達到適合伺服器工作負載的平衡。假設已啟用 tp_thread_group_stats 表,您可以使用以下查詢來確定已執行語句中停滯的比例

SELECT SUM(STALLED_QUERIES_EXECUTED) / SUM(QUERIES_EXECUTED)
FROM performance_schema.tp_thread_group_stats;

這個數字應該盡可能低。為了降低語句停滯的可能性,請增加 thread_pool_stall_limit 的值。

當一個語句到達時,它在實際開始執行之前最多可以延遲多久?假設適用以下條件

在最壞的情況下,10 個高優先順序語句代表 10 個持續長時間執行的事務。因此,在最壞的情況下,無法將任何語句移至高優先順序佇列,因為它總是已經包含等待執行的語句。10 秒後,新語句有資格被移至高優先順序佇列。但是,在它可以被移動之前,它之前的所有語句也必須被移動。這可能需要額外的 2 秒,因為每秒最多有 100 個語句被移至高優先順序佇列。現在,當語句到達高優先順序佇列時,前面可能有很多長時間執行的語句。在最壞的情況下,每一個都變成停滯,並且每個語句都需要 1 秒才能從高優先順序佇列中擷取下一個語句。因此,在這種情況下,新語句需要 222 秒才能開始執行。

這個例子展示了應用程式的最壞情況。如何處理它取決於應用程式。如果應用程式對回應時間有很高的要求,它很可能應該在更高的層級自行限制使用者。否則,它可以使用執行緒池組態參數來設定某種最長等待時間。