MySQL線程池只在Percona,MariaDB,Oracle MySQL企業版中提供。Oracle MySQL社區版並不提供。 在傳統方式下,MySQL線程調度方式有兩種:每個連接一個線程(one-thread-per-connection)和所有連接一個線程(no-threads)。在實際生產 ...
MySQL線程池只在Percona,MariaDB,Oracle MySQL企業版中提供。Oracle MySQL社區版並不提供。
在傳統方式下,MySQL線程調度方式有兩種:每個連接一個線程(one-thread-per-connection)和所有連接一個線程(no-threads)。在實際生產中,一般用的是前者。即每當有一個客戶端連接到MySQL伺服器,MySQL伺服器都會為該客戶端創建一個單獨的線程。連接數越多,則相應的線程會越多。
如果大部分線程處於空閑狀態,則不會對伺服器的性能造成很大的影響。但如果同時執行的線程太多,會導致操作系統頻繁的上下文切換。
引入線程池的目的,就是為了減少同時運行的線程的數量,降低上下文切換的次數。
線程池是MariaDB最先實現的,有兩種實現方式,分別對應Windows和Unix操作系統。其中,Windows系統上是直接利用操作系統的本地緩衝池功能,Unix系統上則是自己實現的。這導致兩個操作系統上的系統變數有所不同。
下麵,基於Percona 5.6.31版本看看線程池的相關參數
thread_handling
預設是one-thread-per-connection,如果要使用連接池功能,則必須設置為pool-of-threads。
thread_pool_size
用於設置線程池中線程組的個數,預設為伺服器CPU的核心數。實現分組的目的是為了把每個分組對應到每個CPU核心上,這樣在同一時間點,每個分組可調用1個線程進行執行。
thread_pool_max_threads
控制線程池的最大線程數,若該值為1000,代表線程池中所能創建的最大線程數不能超過1000。
This variable can be used to limit the maximum number of threads in the pool. Once this number is reached no new threads will be created.
thread_pool_oversubscribe
用於控制單個CPU核心在同一時間活躍的線程數。類似於一種“超頻”的概念
The higher the value of this parameter the more threads can be run at the same time, if the values is lower than 3 it could lead to more sleeps and wake-ups
thread_pool_stall_limit
線程池中無可用線程時,thread_pool_stall_limit決定等待多久後創建新線程,單位為毫秒。預設是500。
在合適範圍內,該值越大,MySQL伺服器的整體處理性能就越好,因為較少數量的線程,會降低對於系統資源的徵用。但是,並不是越大越好,因為該值越大,新線程的創建將等待更長的時間,用戶的查詢延遲就會越明顯。
The number of milliseconds before a running thread is considered stalled. When this limit is reached thread pool will wake up or create another thread. This is being used to prevent a long-running query from monopolizing the pool.
thread_pool_idle_timeout
設置空閑線程銷毀前的等待時間,單位為秒,預設是60。
用戶可以根據自己的業務場景來調整該參數的值,如果設置得太短,會導致線程頻繁的銷毀與創建,如果設置的太長,則會導致線程池中的線程數長時間不會下降。
This variable can be used to limit the time an idle thread should wait before exiting.
extra_port
用於設置MySQL服務埠之外的埠,供管理員管理伺服器。
This variable can be used to specify additional port Percona Server will listen on. This can be used in case no new connections can be established due to all worker threads being busy or being locked when pool-of-threads feature is enabled.
extra_max_connections
用於設置extra_port埠允許的最大連接數,通過extra_port埠創建的連接,採用的是one-thread-per-connection的方式
This variable can be used to specify the maximum allowed number of connections plus one extra SUPER users connection on the extra_port. This can be used with the extra_port variable to access the server in case no new connections can be established due to all worker threads being busy or being locked when pool-of-threads feature is enabled。
除此之外,Percona還新增了兩個參數用於實現優先順序隊列。
thread_pool_high_prio_mode
線程池分組內的待處理任務會放到任務隊列中,等待worker線程處理。
每個分組有兩個隊列:高優先順序隊列和普通隊列,worker線程先從高優先隊列取event處理,只有當高優先隊列為空時才從普通隊列取event處理。
通過優先順序隊列,可以讓已經開啟的事務或短事務得到優先處理,及時提交釋放鎖等資源。
該參數可設置三種模式:
transactions:預設的,只有一個已經開啟了事務的SQL,並且thread_pool_high_prio_tickets不為0,才會進入到高優先順序隊列中,每個連接在thread_pool_high_prio_tickets次被放到優先隊列中後,會移到普通隊列中。
statements:單獨的SQL總是進入高優先順序隊列
none:禁用高優先順序隊列功能,所有的連接都放到普通隊列中處理。
thread_pool_high_prio_tickets
給每個新的連接授予的tickets大小
This variable controls the high priority queue policy. Each new connection is assigned this many tickets to enter the high priority queue. Setting this variable to 0 will disable the high priority queue.預設為4294967295。
線程池的適用場景:
適用於有大量短查詢的業務場景
在該場景下,每個連接一個線程,過多的連接數很容易達到連接數的最大值,同時,過多的活躍線程會導致頻繁的上下文切換。此時,可使用線程池,因為是短查詢,不會有某個連接長時間占用線程池中的線程,所以幾乎不會影響客戶端請求的響應時間,並且,隨著連接數的增加,線程池中的線程數被控制都在一定範圍內,減輕了系統的壓力。
在有大量長查詢的業務場景下不適合使用線程池
在該場景下,長查詢可能會占據線程池的所有線程,導致線程池出現效率低效的情況,客戶端設置不能進行連接。
參考:
1. 深入理解MariaDB與MySQL
2. MariaDB原理與實現
3. http://www.tuicool.com/articles/7NveimQ
4. https://www.percona.com/blog/2013/03/16/simcity-outages-traffic-control-and-thread-pool-for-mysql/
5. http://mysql.taobao.org/monthly/2016/02/09/
6. http://www.cnblogs.com/cchust/p/4510039.html