線(xiàn)程池是Mysql5.6的一個(gè)核心功能,對(duì)于服務(wù)器應(yīng)用而言,無(wú)論是web應(yīng)用服務(wù)還是DB服務(wù),高并發(fā)請(qǐng)求始終是一個(gè)繞不開(kāi)的話(huà)題。當(dāng)有大量請(qǐng)求并發(fā)訪(fǎng)問(wèn)時(shí),一定伴隨著資源的不斷創(chuàng)建和釋放,導(dǎo)致資源利用率低,降低了服務(wù)質(zhì)量。線(xiàn)程池是一種通用的技術(shù),通過(guò)預(yù)先創(chuàng)建一定數(shù)量的線(xiàn)程,當(dāng)有請(qǐng)求達(dá)到時(shí),線(xiàn)程池分配一個(gè)線(xiàn)程提供服務(wù),請(qǐng)求結(jié)束后,該線(xiàn)程又去服務(wù)其他請(qǐng)求。 通過(guò)這種方式,避免了線(xiàn)程和內(nèi)存對(duì)象的頻繁創(chuàng)建和釋放,降低了服務(wù)端的并發(fā)度,減少了上下文切換和資源的競(jìng)爭(zhēng),提高資源利用效率。所有服務(wù)的線(xiàn)程池本質(zhì)都是位了提高資源利用效率,并且實(shí)現(xiàn)方式也大體相同。本文主要說(shuō)明Mysql線(xiàn)程池的實(shí)現(xiàn)原理。
在Mysql5.6出現(xiàn)以前,Mysql處理連接的方式是One-Connection-Per-Thread,即對(duì)于每一個(gè)數(shù)據(jù)庫(kù)連接,Mysql-Server都會(huì)創(chuàng)建一個(gè)獨(dú)立的線(xiàn)程服務(wù),請(qǐng)求結(jié)束后,銷(xiāo)毀線(xiàn)程。再來(lái)一個(gè)連接請(qǐng)求,則再創(chuàng)建一個(gè)連接,結(jié)束后再進(jìn)行銷(xiāo)毀。這種方式在高并發(fā)情況下,會(huì)導(dǎo)致線(xiàn)程的頻繁創(chuàng)建和釋放。當(dāng)然,通過(guò)thread-cache,我們可以將線(xiàn)程緩存起來(lái),以供下次使用,避免頻繁創(chuàng)建和釋放的問(wèn)題,但是無(wú)法解決高連接數(shù)的問(wèn)題。One-Connection-Per-Thread方式隨著連接數(shù)暴增,導(dǎo)致需要?jiǎng)?chuàng)建同樣多的服務(wù)線(xiàn)程,高并發(fā)線(xiàn)程意味著高的內(nèi)存消耗,更多的上下文切換(cpu cache命中率降低)以及更多的資源競(jìng)爭(zhēng),導(dǎo)致服務(wù)出現(xiàn)抖動(dòng)。相對(duì)于One-Thread-Per-Connection方式,一個(gè)線(xiàn)程對(duì)應(yīng)一個(gè)連接,Thread-Pool實(shí)現(xiàn)方式中,線(xiàn)程處理的最小單位是statement(語(yǔ)句),一個(gè)線(xiàn)程可以處理多個(gè)連接的請(qǐng)求。這樣,在保證充分利用硬件資源情況下(合理設(shè)置線(xiàn)程池大小),可以避免瞬間連接數(shù)暴增導(dǎo)致的服務(wù)器抖動(dòng)。
調(diào)度方式實(shí)現(xiàn)
Mysql-Server同時(shí)支持3種連接管理方式,包括No-Threads,One-Thread-Per-Connection和Pool-Threads。No-Threads表示處理連接使用主線(xiàn)程處理,不額外創(chuàng)建線(xiàn)程,這種方式主要用于調(diào)試;One-Thread-Per-Connection是線(xiàn)程池出現(xiàn)以前最常用的方式,為每一個(gè)連接創(chuàng)建一個(gè)線(xiàn)程服務(wù);Pool-Threads則是本文所討論的線(xiàn)程池方式。Mysql-Server通過(guò)一組函數(shù)指針來(lái)同時(shí)支持3種連接管理方式,對(duì)于特定的方式,將函數(shù)指針設(shè)置成特定的回調(diào)函數(shù),連接管理方式通過(guò)thread_handling參數(shù)控制,代碼如下:
| if (thread_handling <= SCHEDULER_ONE_THREAD_PER_CONNECTION) one_thread_per_connection_scheduler(thread_scheduler, &max_connections, &connection_count);else if (thread_handling == SCHEDULER_NO_THREADS) one_thread_scheduler(thread_scheduler);else pool_of_threads_scheduler(thread_scheduler, &max_connections,&connection_count); |
連接管理流程
新聞熱點(diǎn)
疑難解答
圖片精選