Mysql 線程池 ===


why

在5.6以前,mysql會對每個連接創建一個線程,請求結束后銷毀線程。在高並發的情況下,為了避免頻繁創建和釋放連接,可以通過thread-cache將線程緩存起來,請求來了先嘗試從cache中獲取,重復利用線程資源。

show global status like 'thread%'

 show variables like 'thread_cache_size';

問題

在低並發的情況下,thread_cache可以成為一個有效的優化機制,但在並發突然增加時,會產生非常嚴重的問題。比如thead_cache_size是512,突然來了3000個連接怎么辦?
mysql在5.6之前,會硬着頭皮創建3000個線程!如果是一台一般配置的機器,比如32核、128G這種看起來還不錯的配置,會因為線程上下文切換,導致整個實例無法及時響應問題,即使按主鍵查詢,也可能超過1s,因此dba可能建議你:控制連接數在300左右。
通過客戶端使用連接池技術,是可以控制總的連接個數,超過連接池最大值,客戶端直接拒絕響應。但隨着機器的擴大,在微服務還未完全的系統中,多個應用連一個庫並非不可能,再諸如一個mysql實例多庫的情況,更上雪上加霜。
通過在5.5版本上的遭遇,在3.5k的connections和threads情況下,mysql所在機器的cpu、memory不是性能陡然下降的原因,此時cpu有可能利用率很低,因為時間都花在了切換線程上下文上了,操作系統的資源也包括線程資源。
當然可以設置 max_connections,在連接過多時,拒絕信的連接請求

解決

https://dev.mysql.com/doc/refman/5.6/en/faqs-thread-pool.html
mysql 5.6引入了線程池技術,防止瞬間暴漲的連接擊垮服務。

  • 一個線程可以處理多個連接
  • 連接被thread group管理起來,group的數量和cpu核心數相當,每個group最少有一個連接,達到最大程度利用cpu的效果,按連接的性質進行重要性排序和queued

適用場景

  • Threads_running變量持續較高,如innodb引擎中,總是超過40
  • 如果你在使用innodb_thread_concurrency來限制同時執行語句的數量,他們解決了相同的問題
  • 主要是短查詢時
  • 較多的事務導致的資源競爭,導致獲取鎖的時間消耗變大,thread pool將減少這樣的競爭

經驗值

https://dev.mysql.com/doc/refman/5.6/en/thread-pool-tuning.html

thread_pool_size :線程組數量,默認16,建議16-36,最好是24-36,值的范圍1-64,否則報錯(線程組數量與cpu相當,每個線程組中有WorkerThread,ListenThread)

thread_pool_stall_limit:將一個sql打標成stall的時間的閾值,意思為這個sql占用了較長的時間,該讓個其它人了,較低的值允許線程更快的啟動起來;避免死鎖。較高的值適合於長時間運行的語句,避免當前語句執行時有太多其他語句執行

http://database.51cto.com/art/201803/569007.htm

每一個group有多個worker線程,一個worker線程可以處理多個連接的sql,可以按優先級進行隊列排序,比如默認的按事務排序

show global variables like ‘%thread_handling%‘;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM