MySQL MySql連接數與線程池


連接數

1、  查看允許的最大並發連接數

SHOW VARIABLES LIKE 'max_connections';



 

2、  修改最大連接數

方法1:臨時生效

SET GLOBAL max_connections=200;

SET語法參考:

http://dev.mysql.com/doc/refman/5.7/en/set-statement.html

 

方法2:永久生效

查找my.ini 或 my.cnf文件,進行編輯設置:

# whereis my.cnf

my: /etc/my.cnf

 

# vim /etc/my.cnf

.....

[mysqld]

……

max_connections = 1000

 

重啟MySQL服務

 

3、  查看線程相關的狀態變量

SHOW STATUS LIKE 'Threads%';

輸出說明:

Threads_cached:緩存中的線程連接數,該變量在嵌入式服務器(libmysqld)無意義

Threads_connected:當前打開的連接數,該值和SHOW PROCESSLIST;輸出記錄總數一樣

Threads_created:為處理連接而創建的線程數。如果該值很大,可能要增加thread_cache_size。緩存未命中率=Theads_created/Connections

 

thread_cache_size:但客戶端斷開時,如果緩存中的線程連接數即Threads_cached,比thread_cache_size小,那么這個客戶端線程會被放入緩存中,如果可能,通過重用緩存中線程來滿足線程請求。如果有許多新連接,可以增加該項值來提高性能。

 

Threads_running:非睡眠狀態的連接數,通常指並發連接數

 

線程池

線程池由許多線程組構成,每個組管理一系列客戶端連接。一旦連接被建立,線程池會以輪詢調度(round-robin)的方式把其分配給線程組。

 

每個線程組可擁有的最大線程數量為4096(或4095,在一些操作系統上,其中一個線程供內部使用)

 

線程池隔離了連接和線程,所以線程和連接之間沒有固定的關系,這和缺省的線程處理模式不一樣。缺省的線程處理模式會把線程同連接關聯,這樣以便線程執行來自連接的所有語句。

 

任何時刻,線程組盡量確保每個線程組中至多只有一個執行線程,但有時候,為了最佳性能,允許多余一個臨時的執行線程。算法如下:

l  每個線程組有一個監聽線程,監聽來自分配給線程組的連接的語句。當語句到達時,線程組或者立刻開始執行,或放入隊列等待稍后執行。

n  如果僅收到語句,且當前隊列中沒有排隊等待執行的語句,或者無正在執行的語句,則立即執行

n  如果語句不能立即被執行則放入隊列。

l  如果立即執行語句,那么由監聽線程來執行(這意味着線程組中暫時沒有線程在監聽)。如果語句快速執行完,執行線程返回繼續監聽語句。否則,線程池會認為該語句執行滯后,並開啟另一個線程作為監聽線程(如果有必要的話)。為了保證沒有線程組被執行滯后的語句阻塞,線程池有個后台線程定期監控線程組狀態。

 

通過使用監聽線程來執行可立執行的語句,如果語句可以快速執行完的話,不必創建一個額外線程。這樣確保了在線程數很少的情況下,最大的執行效率。

 

當開啟線程組插件時,它會為每個線程組創建一個線程(監聽線程),外加一個后台線程。有必要的話創建額外的線程來執行語句。

l  線程池關注於限制當前短時間運行的語句數量。執行語句到達停滯時間(stall time)之前,它會阻止其它語句開始執行。如果語句超過停滯時間,則允許其繼續執行,但是不再阻止其它語句的運行。通過這種方式,線程池盡力確保每個線程組中,不多於一個短時間運行的執行語句。

 

l  如果語句遇到磁盤I/O操作或用戶級鎖(行鎖或表鎖),語句將被阻塞。這種阻塞會導致線程組變得不可用,所以會有針對線程組的回調來確保線程池可以在改組中立即開啟一個新的線程來執行其它的語句。當返回一個阻塞線程時,線程池允許立即重啟它。

l  有兩個隊列,一個高優先級(high-priority)隊列和一個低優先(low-priority)級隊列。事務中的第一條語句分配到低優先級隊列。如果事務正在進行(剛開始執行事務中的語句),接下來的其它任意語句分配到高優先級隊列,否則進入低優先級隊列。隊列分配可通過thread_pool_high_priority_connection系統變量來控制,開啟該系統變量會導致會話中所有排隊中的語句分配到高優先級隊列

 

針對非事務性存儲引擎或開啟autocommit下的事務性存儲引擎的語句,被視為低優先級語句,因為這種情況下,每條語句都是一個事務。如果給定的語句既有針對InonoDB表,也有MyISAM表的,那么線程池會為針對InnoDB表的語句安排更高的優先級,除非開啟了autocommit。如果開啟了autocommit,所有語句都是低優先級。

l  當線程組從隊列中選取語句進行執行時,它先在高優先級隊列中查找,然后低優先級隊列。如果找到語句則將其從隊列中移除並開始執行它。

l  如果語句在低優先級停留太久,線程池會把它移到高優先級隊列。thread_pool_prio_kickup_timer系統變量控制了這個“停留時間”。對每個線程組來說,語句停留的最大時間為10ms。

l  線程池重用最活躍的線程來獲取對CPU緩存更好的利用。這個小的調整對性能有重大的影響。

……

參考連接:

http://dev.mysql.com/doc/refman/5.7/en/thread-pool-operation.html

 

1、  線程池調優

thread_pool_size是控制線程池性能的最重要的參數。僅在啟動服務器時可以被設置,經驗表明如下:

l  如果主引擎(primary storage engine)為InnoDB, thread_pool_size最佳設置可能在16和36之間,最常見的優化值傾向於24到36。

 

l  如果主引擎為MyISAMthread_pool_size設置應該相當低。該值設置為4到8,傾向於獲取最優性能。更高值設置對性能傾向於有點負面但不顯著的影響。

 

查看thread_pool_size值

SHOW VARIABLES LIKE 'thread_pool_size';

 

修改thread_pool_siz值:參考修改最大連接值,通過修改my.conf來修改

 

另一個重要系統變量thread_pool_stall_limit,用處理被阻塞和長時間運行的語句,確保服務器不完全被阻塞。thread_pool_stall_limit有個6秒的上限值,防止服務器死鎖的風險。

 

thread_pool_stall_limit允許線程池處理長時間運行的語句。如果某個長時間運行的語句阻塞線程組,那么所有分配給該線程組的連接都會被阻塞,且在長時間運行的語句完成之前無法被執行。最差的情況下,這可能耗費幾個小時甚至幾天。

 

仔細考慮thread_pool_stall_limit值的選取,以便語句執行被認為停滯前,有更長的執行時間。執行停滯的語句(Stalled statment),會調用額外的上下文切換,某些情況下,甚至是額外線程的創建,因此會產生許多額外超負載。另一方面,thread_pool_stall_limit值如果設置太高,意味着長時間運行的語句會更長時間的阻塞許多短時間運行的語句。短時間等待允許線程更快的啟動,同時更有利於避免產生死鎖。長時間等待利於包含長時間運行語句的工作負載,避免當前語句執行時,開啟更多新的語句。

 

假設服務器執行一工作任務,即便是服務器處於負載的情況下,其99.9%的語句都在100ms內完成,剩余語句的執行時間相當均勻的分布在100ms和2小時之間。這種情況,把thread_pool_stall_limit設置為10會比較,即100ms(毫秒)。針對主要執行簡單語句的的服務器來說,默認值,60ms已經很ok。

 

thread_pool_stall_limit參數可以在運行時被修改,以便服務器工作負載上能取得一個適當的平衡。假設開啟了TP_THREAD_GROUP_STATS表,可以使用以下查詢來判斷停滯執行語句所占比例。

 

SELECT SUM(STALLED_QUERIES_EXECUTED) / SUM(QUERIES_EXECUTED)

FROM information_schema.TP_THREAD_GROUP_STATS;

該值應盡可能低,為了降低語句執行停滯的可能性,增加thread_pool_stall_limit的值。

 

修改thread_pool_stall_limit:同修改最大連接數“max_connections”

 

參考連接:

http://dev.mysql.com/doc/refman/5.7/en/thread-pool-tuning.html

 

 

參考連接:

http://dev.mysql.com/doc/refman/4.1/en/server-status-variables.html


免責聲明!

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



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