溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

數(shù)據(jù)庫(kù)連接池的大小設(shè)置成多大比較好

發(fā)布時(shí)間:2021-08-30 09:53:33 來(lái)源:億速云 閱讀:151 作者:chen 欄目:數(shù)據(jù)庫(kù)

本篇內(nèi)容主要講解“數(shù)據(jù)庫(kù)連接池的大小設(shè)置成多大比較好”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“數(shù)據(jù)庫(kù)連接池的大小設(shè)置成多大比較好”吧!

  一、數(shù)據(jù)庫(kù)連接池的大小

  基本上來(lái)說(shuō),大部分項(xiàng)目都需要跟數(shù)據(jù)庫(kù)做交互,那么,數(shù)據(jù)庫(kù)連接池的大小設(shè)置成多大合適呢?

  一些開(kāi)發(fā)老鳥(niǎo)可能還會(huì)告訴你:沒(méi)關(guān)系,盡量設(shè)置的大些,比如設(shè)置成 200,這樣數(shù)據(jù)庫(kù)性能會(huì)高些,吞吐量也會(huì)大些!

  你也許會(huì)點(diǎn)頭稱是,真的是這樣嗎?看完這篇文章,也許會(huì)顛覆你的認(rèn)知哦!

  二、正菜開(kāi)始

  可以很直接的說(shuō),關(guān)于數(shù)據(jù)庫(kù)連接池大小的設(shè)置,每個(gè)開(kāi)發(fā)者都可能在一環(huán)節(jié)掉進(jìn)坑里,事實(shí)上呢,大部分程序員可能都會(huì)依靠自己的直覺(jué)去設(shè)置它的大小,設(shè)置成 100 ?思量許久后,自顧自想,應(yīng)該差不多吧?

  三、假設(shè)你的服務(wù)有1萬(wàn)并發(fā)的訪問(wèn)

  不妨意淫一下,你手里有個(gè)網(wǎng)站,并發(fā)壓力雖然還沒(méi)到 Facebook 那個(gè)級(jí)別,但是呢?也有個(gè)1萬(wàn)上下的并發(fā)量!也就是說(shuō)差不多2萬(wàn)左右的 TPS。

  那么問(wèn)題來(lái)了!這個(gè)網(wǎng)站的數(shù)據(jù)庫(kù)連接池應(yīng)該設(shè)置成多大合適呢?

  其實(shí)這個(gè)問(wèn)法本身就是有問(wèn)題的,我們需要反過(guò)來(lái)問(wèn),正確問(wèn)法應(yīng)該是:

  “這個(gè)網(wǎng)站的數(shù)據(jù)庫(kù)連接池應(yīng)該設(shè)置成多小合適呢?”

  口述一下,視頻中對(duì) Oracle 數(shù)據(jù)庫(kù)進(jìn)行了壓力測(cè)試,模擬 9600 個(gè)并發(fā)線程來(lái)操作數(shù)據(jù)庫(kù),每?jī)纱螖?shù)據(jù)庫(kù)操作之間 sleep 550ms,注意,視頻中剛開(kāi)始設(shè)置的線程池大小為 2048。

  讓我們來(lái)看看數(shù)據(jù)庫(kù)連接池的大小為 2048 性能測(cè)試結(jié)果的鬼樣子:

  每個(gè)請(qǐng)求要在連接池隊(duì)列里等待 33ms,獲得連接之后,執(zhí)行SQL需要耗時(shí)77ms, CPU 消耗維持在 95% 左右;

  接下來(lái),我們將連接池的大小改小點(diǎn),設(shè)置成 1024,其他測(cè)試參數(shù)不變,結(jié)果咋樣?

  "這里,獲取連接等待時(shí)長(zhǎng)基本不變,但是 SQL 的執(zhí)行耗時(shí)降低了!"

  哎呦,有長(zhǎng)進(jìn)哦!

  接下來(lái),我們?cè)僭O(shè)置小些,連接池的大小降低到 96,并發(fā)數(shù)等其他參數(shù)不變,看看結(jié)果如何:

  每個(gè)請(qǐng)求在連接池隊(duì)列中的平均等待時(shí)間為 1ms, SQL 執(zhí)行耗時(shí)為 2ms.

  我去!什么鬼?

  我們沒(méi)調(diào)整任何東西,僅僅只是將數(shù)據(jù)庫(kù)連接池的大小降低了,這樣,就能把之前平均 100ms 響應(yīng)時(shí)間縮短到了 3ms。吞吐量指數(shù)級(jí)上升啊!

  你這也太溜了!

  四、為啥有這種效果?

  我們不妨想一下,為啥 Nginx 內(nèi)部?jī)H僅使用了 4 個(gè)線程,其性能就大大超越了 100 個(gè)進(jìn)程的 Apache HTTPD 呢?追究其原因的話,回想一下計(jì)算機(jī)科學(xué)的基礎(chǔ)知識(shí),答案其實(shí)非常明顯。

  要知道,即使是單核 CPU 的計(jì)算機(jī)也能“同時(shí)”運(yùn)行著數(shù)百個(gè)線程。但我們其實(shí)都知道,這只不過(guò)是操作系統(tǒng)快速切換時(shí)間片,跟我們玩的一個(gè)小把戲罷了。

  一核 CPU同一時(shí)刻只能執(zhí)行一個(gè)線程,然后操作系統(tǒng)切換上下文,CPU 核心快速調(diào)度,執(zhí)行另一個(gè)線程的代碼,不停反復(fù),給我們?cè)斐闪怂羞M(jìn)程同時(shí)運(yùn)行假象。

  其實(shí),在一核 CPU 的機(jī)器上,順序執(zhí)行A和B永遠(yuǎn)比通過(guò)時(shí)間分片切換“同時(shí)”執(zhí)行A和B要快,其中原因,學(xué)過(guò)操作系統(tǒng)這門課程的童鞋應(yīng)該很清楚。一旦線程的數(shù)量超過(guò)了 CPU 核心的數(shù)量,再增加線程數(shù)系統(tǒng)就只會(huì)更慢,而不是更快,因?yàn)檫@里涉及到上下文切換耗費(fèi)的額外的性能。

  說(shuō)到這里,你應(yīng)該恍然大悟了

  五、其他應(yīng)該考慮到的因素

  上小節(jié)中說(shuō)到了主要原因,但其實(shí)沒(méi)有這么簡(jiǎn)單,我們還需要考慮到一些其他的因素。

  當(dāng)我們?cè)趯ふ覕?shù)據(jù)庫(kù)的性能瓶頸時(shí),大致可歸為三類:

  CPU

  磁盤 IO

  網(wǎng)絡(luò) IO

  也許你會(huì)說(shuō),還有內(nèi)存這一因素?內(nèi)存的確是需要考慮的,但是比起磁盤IO和網(wǎng)絡(luò)IO,稍顯微不足道,這里就不加了。

  假設(shè)我們不考慮磁盤 IO 和網(wǎng)絡(luò) IO,就很好定論了,在一個(gè) 8 核的服務(wù)器上,數(shù)據(jù)庫(kù)連接數(shù)/線程數(shù)設(shè)置為 8 能夠提供最優(yōu)的性能,如果再增加連接數(shù),反而會(huì)因?yàn)樯舷挛那袚Q導(dǎo)致性能下降。

  大家都知道,數(shù)據(jù)庫(kù)通常把數(shù)據(jù)存儲(chǔ)在磁盤上,而磁盤呢,通常是由一些旋轉(zhuǎn)著的金屬碟片和一個(gè)裝在步進(jìn)馬達(dá)上的讀寫頭組成的。讀/寫頭同一時(shí)刻只能出現(xiàn)在一個(gè)位置,當(dāng)它需要再次執(zhí)行讀寫操作時(shí),它必須“尋址”到另外一個(gè)位置才能完成任務(wù)。所以呢?這里就有了尋址的耗時(shí),此外還有旋轉(zhuǎn)耗時(shí),讀寫頭需要等待磁盤碟片上的目標(biāo)數(shù)據(jù)“旋轉(zhuǎn)到位”才能進(jìn)行讀寫操作。使用緩存當(dāng)然是能夠提升性能的,但上述原理仍然適用。

  在這段("I/O等待")時(shí)間內(nèi),線程是處于“阻塞”等待狀態(tài),也就是說(shuō)沒(méi)干啥正事!此時(shí)操作系統(tǒng)可以將這個(gè)空閑的CPU 核心用于服務(wù)其他線程。

  這里我們可以總結(jié)一下,當(dāng)你的線程處理的是 I/O 密集型業(yè)務(wù)時(shí),便可以讓線程/連接數(shù)設(shè)置的比 CPU核心大一些,這樣就能夠在同樣的時(shí)間內(nèi),完成更多的工作,提升吞吐量。

  那么問(wèn)題又來(lái)了?

  大小設(shè)置成多少合適呢?

  這要取決于磁盤,如果你使用的是 SSD 固態(tài)硬盤,它不需要尋址,也不需要旋轉(zhuǎn)碟片。打住打住!!!你千萬(wàn)可別理所當(dāng)然的認(rèn)為:“既然SSD速度更快,我們把線程數(shù)的大小設(shè)置的大些吧!!”

  結(jié)論正好相反!無(wú)需尋址和沒(méi)有旋回耗時(shí)的確意味著更少的阻塞,所以更少的線程(更接近于CPU核心數(shù))會(huì)發(fā)揮出更高的性能。只有當(dāng)阻塞密集時(shí),更多的線程數(shù)才能發(fā)揮出更好的性能。

  上面我們已經(jīng)說(shuō)過(guò)了磁盤 IO, 接下來(lái)我們談?wù)劸W(wǎng)絡(luò) IO!

  網(wǎng)絡(luò) IO 其實(shí)也是非常相似的。通過(guò)以太網(wǎng)接口讀寫數(shù)據(jù)時(shí)也會(huì)造成阻塞,10G帶寬會(huì)比1G帶寬的阻塞耗時(shí)少一些,而 1G 帶寬又會(huì)比 100M 帶寬的阻塞少一些。通常情況下,我們把網(wǎng)絡(luò) IO 放在第三順位來(lái)考慮,然而有些人會(huì)在性能計(jì)算中忽略網(wǎng)絡(luò) IO 帶來(lái)的影響。

  上圖是 PostgreSQL 的基準(zhǔn)性能測(cè)試數(shù)據(jù),從圖中我們可以看到,TPS 在連接數(shù)達(dá)到 50 時(shí)開(kāi)始變緩?;剡^(guò)頭來(lái)想下,在上面 Oracle 的性能測(cè)試視頻中,測(cè)試人員們將連接數(shù)從 2048 降到了 96,實(shí)際上 96 還是太高了,除非你的服務(wù)器 CPU 核心數(shù)有 16 或 32。

  六、連接數(shù)計(jì)算公式

  下面公式由 PostgreSQL 提供,不過(guò)底層原理是不變的,它適用于市面上絕大部分?jǐn)?shù)據(jù)庫(kù)產(chǎn)品。還有,你應(yīng)該模擬預(yù)期的訪問(wèn)量,并通過(guò)下面的公式先設(shè)置一個(gè)偏合理的值,然后在實(shí)際的測(cè)試中,通過(guò)微調(diào),來(lái)尋找最合適的連接數(shù)大小。

  連接數(shù) = ((核心數(shù) * 2) + 有效磁盤數(shù))

  核心數(shù)不應(yīng)包含超線程(hyper thread),即使打開(kāi)了超線程也是如此,如果熱點(diǎn)數(shù)據(jù)全被緩存了,那么有效磁盤數(shù)實(shí)際是0,隨著緩存命中率的下降,有效磁盤數(shù)也逐漸趨近于實(shí)際的磁盤數(shù)。另外需要注意,這一公式作用于SSD 的效果如何,尚未明了。

  好了,按照這個(gè)公式,如果說(shuō)你的服務(wù)器 CPU 是 4核 i7 的,連接池大小應(yīng)該為 ((4 * 2) + 1) = 9。

  取個(gè)整, 我們就設(shè)置為 10 吧。你這個(gè)行不行啊?10 也太小了吧!

  你要是覺(jué)得不太行的話,可以跑個(gè)性能測(cè)試看看,我們可以保證,它能輕松支撐 3000 用戶以 6000 TPS 的速率并發(fā)執(zhí)行簡(jiǎn)單查詢的場(chǎng)景。你還可以將連接池大小超過(guò) 10,那時(shí),你會(huì)看到響應(yīng)時(shí)長(zhǎng)開(kāi)始增加,TPS 開(kāi)始下降。

  七、結(jié)論:你需要的是一個(gè)小連接池,和一個(gè)等待連接的線程隊(duì)列

  假設(shè)說(shuō)你有 10000 個(gè)并發(fā)訪問(wèn),而你設(shè)置了連接池大小為 10000,你怕是石樂(lè)志哦。

  改成 1000,太高?改成 100?還是太多了。

  你僅僅需要一個(gè)大小為 10 數(shù)據(jù)庫(kù)連接池,然后讓剩下的業(yè)務(wù)線程都在隊(duì)列里等待就可以了。

  連接池中的連接數(shù)量大小應(yīng)該設(shè)置成:數(shù)據(jù)庫(kù)能夠有效同時(shí)進(jìn)行的查詢?nèi)蝿?wù)數(shù)(通常情況下來(lái)說(shuō)不會(huì)高于 2*CPU核心數(shù))。

  你應(yīng)該經(jīng)常會(huì)看到一些用戶量不是很大的 web 應(yīng)用中,為應(yīng)付大約十來(lái)個(gè)的并發(fā),卻將數(shù)據(jù)庫(kù)連接池設(shè)置成 100, 200 的情況。請(qǐng)不要過(guò)度配置您的數(shù)據(jù)庫(kù)連接池的大小。

  八、額外需要注意的點(diǎn)

  實(shí)際上,連接池的大小的設(shè)置還是要結(jié)合實(shí)際的業(yè)務(wù)場(chǎng)景來(lái)說(shuō)事。

  比如說(shuō),你的系統(tǒng)同時(shí)混合了長(zhǎng)事務(wù)和短事務(wù),這時(shí),根據(jù)上面的公式來(lái)計(jì)算就很難辦了。正確的做法應(yīng)該是創(chuàng)建兩個(gè)連接池,一個(gè)服務(wù)于長(zhǎng)事務(wù),一個(gè)服務(wù)于"實(shí)時(shí)"查詢,也就是短事務(wù)。

  還有一種情況,比方說(shuō)一個(gè)系統(tǒng)執(zhí)行一個(gè)任務(wù)隊(duì)列,業(yè)務(wù)上要求同一時(shí)間內(nèi)只允許執(zhí)行一定數(shù)量的任務(wù),這時(shí),我們就應(yīng)該讓并發(fā)任務(wù)數(shù)去適配連接池連接數(shù),而不是連接數(shù)大小去適配并發(fā)任務(wù)數(shù)。

到此,相信大家對(duì)“數(shù)據(jù)庫(kù)連接池的大小設(shè)置成多大比較好”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI