連接池是管理數(shù)據(jù)庫(kù)連接的軟件組件。這可以通過(guò)多種方式幫助提高資源利用率,幫助實(shí)現(xiàn)負(fù)載平衡或故障轉(zhuǎn)移,并且可以大大減少事務(wù)時(shí)間。在這篇博文中,我們將了解什么是連接池以及如何配置它。
連接池是一個(gè)軟件組件管理數(shù)據(jù)庫(kù)連接。這可以通過(guò)多種方式幫助提高資源利用率,幫助實(shí)現(xiàn)負(fù)載平衡或故障轉(zhuǎn)移,并且可以大大減少事務(wù)時(shí)間。在這篇博文中,我們將了解什么是連接池以及如何配置它。
什么是連接池以及它為何有用
打開與數(shù)據(jù)庫(kù)的連接需要許多步驟。我們需要連接到服務(wù)器并執(zhí)行初始握手,就加密和連接設(shè)置達(dá)成一致,然后在所有層(網(wǎng)絡(luò)驅(qū)動(dòng)程序、操作系統(tǒng)層、數(shù)據(jù)庫(kù)層等)中保留新的連接資源。每個(gè)連接都會(huì)消耗內(nèi)存,內(nèi)存大小取決于數(shù)據(jù)庫(kù)引擎。對(duì)于 postgresql,一個(gè)連接甚至可以使用 1.3mb 內(nèi)存。打開連接也需要時(shí)間,因?yàn)槲覀冃枰獏f(xié)商新連接的設(shè)置。
如果我們不斷為每個(gè) SQL 查詢打開新連接,可能會(huì)導(dǎo)致數(shù)據(jù)庫(kù)服務(wù)器出現(xiàn)多個(gè)問(wèn)題:
-
打開連接需要時(shí)間和資源,因此我們的交易速度較慢
-
我們可能會(huì)超出活動(dòng)連接的限制(默認(rèn)情況下可以設(shè)置為某個(gè)值)像一百個(gè)連接)
-
數(shù)據(jù)庫(kù)可能會(huì)消耗更多內(nèi)存,這可能會(huì)對(duì)緩存命中率和可用于查詢的可用內(nèi)存產(chǎn)生負(fù)面影響
而不是打開每個(gè) SQL 查詢都有一個(gè)新連接,我們可以池化連接。我們可以配置連接池來(lái)保留連接數(shù)量并為所有客戶端重用它們。這樣我們的應(yīng)用程序連接到池化器而不是直接連接數(shù)據(jù)庫(kù),然后池化器連接到數(shù)據(jù)庫(kù)。這帶來(lái)了多個(gè)優(yōu)點(diǎn):
-
連接池使連接保持打開狀態(tài)的時(shí)間更長(zhǎng),從而減少了數(shù)據(jù)庫(kù)端打開和關(guān)閉連接的開銷并減少了延遲。
-
我們可以在連接之間甚至數(shù)據(jù)庫(kù)之間實(shí)現(xiàn)負(fù)載平衡,從而提高性能。
-
池化器可以維持穩(wěn)定的連接數(shù)量,因此我們可以避免這個(gè)問(wèn)題活動(dòng)連接過(guò)多,會(huì)減少資源使用。
-
池化器可以重定向主服務(wù)器和備用服務(wù)器之間的連接,以提供故障轉(zhuǎn)移,從而提高穩(wěn)定性和可擴(kuò)展性。
-
池化器可以將密碼存儲(chǔ)到數(shù)據(jù)庫(kù)的中央位置,從而提高安全性。
-
池化器可以緩存結(jié)果以提高查詢性能。
連接池也有一些缺點(diǎn):
-
它是我們系統(tǒng)中可能成為故障點(diǎn)的另一個(gè)組件。
-
由于應(yīng)用程序和數(shù)據(jù)庫(kù)之間的另一個(gè)網(wǎng)絡(luò)躍點(diǎn),網(wǎng)絡(luò)延遲可能會(huì)略有增加。
-
低效的連接池可能會(huì)成為瓶頸。
-
我們需要調(diào)整和維護(hù)連接池,這增加了維護(hù)負(fù)擔(dān)。
不同類型的連接池
有很多實(shí)現(xiàn)連接池的方法。在本節(jié)中,我們將了解各種實(shí)現(xiàn)細(xì)節(jié)。
外部或內(nèi)部連接池
在典型情況下,我們從應(yīng)用程序連接到數(shù)據(jù)庫(kù)。我們現(xiàn)在可以將連接池放在兩個(gè)位置之一:應(yīng)用程序本身或應(yīng)用程序和數(shù)據(jù)庫(kù)之間的某個(gè)位置。
將連接池放在應(yīng)用程序中(應(yīng)用程序端連接池)可以非常容易因?yàn)樵S多 ORM 或數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序都支持開箱即用。例如,JDBC 支持 c3p0,而 ODBC 支持開箱即用。這帶來(lái)了很多好處。我們不需要安裝和維護(hù)任何額外的組件,因?yàn)槌鼗魑挥趹?yīng)用程序內(nèi)部。我們只需要部署應(yīng)用程序的新版本,然后就可以準(zhǔn)備好池化了。這也減少了網(wǎng)絡(luò)延遲,因?yàn)槲覀儧](méi)有任何額外的網(wǎng)絡(luò)躍點(diǎn)(一切都位于我們的應(yīng)用程序內(nèi)部)。
不幸的是,應(yīng)用程序端連接池有一些缺點(diǎn)。最大的一個(gè)是它僅針對(duì)一個(gè)應(yīng)用程序進(jìn)行配置。如果我們有很多應(yīng)用程序(尤其是在分布式環(huán)境中),那么我們需要在很多地方配置池化器。更不用說(shuō)我們?nèi)匀豢赡苓_(dá)到服務(wù)器端的連接計(jì)數(shù)限制,因?yàn)槌鼗鞅舜瞬涣私?。擁有許多連接池也會(huì)導(dǎo)致更高的資源使用率,并且通常性能較低。
我們還可以使用位于應(yīng)用程序和數(shù)據(jù)庫(kù)之間的外部連接池。這可以與任意數(shù)量的應(yīng)用程序一起使用,并讓我們能夠精確控制連接限制。集中式連接池還可以更好地控制資源,讓我們實(shí)現(xiàn)故障轉(zhuǎn)移或負(fù)載分配。
外部連接池也有一些缺點(diǎn)。首先也是最重要的,它是我們需要隨著時(shí)間的推移安裝、配置、調(diào)整和維護(hù)的另一個(gè)組件。我們還需要重新配置每個(gè)應(yīng)用程序以使用連接池(這應(yīng)該像更改一些連接字符串并重新部署應(yīng)用程序一樣簡(jiǎn)單)。外部池化器還會(huì)增加一些網(wǎng)絡(luò)延遲,因?yàn)樗菓?yīng)用程序和數(shù)據(jù)庫(kù)之間的另一個(gè)網(wǎng)絡(luò)組件。
外部連接池化器也可能成為故障點(diǎn)。如果池化器由于某種原因而關(guān)閉,應(yīng)用程序?qū)o(wú)法再連接到數(shù)據(jù)庫(kù)。如果池化器速度緩慢或效率低下,則會(huì)影響所有使用它的應(yīng)用程序。因此,池化器必須具有高質(zhì)量,才不會(huì)降低整體性能。
池化類型
每個(gè)池化器需要決定如何將連接分配給客戶端。通常有三種方法。
第一種是會(huì)話池。在這種方法中,連接在會(huì)話持續(xù)時(shí)間內(nèi)分配給客戶端(直到客戶端斷開連接或達(dá)到超時(shí))。這是最簡(jiǎn)單的方法,但是,這有效地限制了客戶端數(shù)量,因?yàn)橥ǔC總€(gè)客戶端消耗一個(gè)連接。
下一個(gè)解決方案是事務(wù)池。在此方法中,池程序?yàn)槊總€(gè)事務(wù)分配連接,并且僅在事務(wù)持續(xù)時(shí)間內(nèi)分配連接。如果客戶端想要運(yùn)行另一個(gè)事務(wù),他們需要獲得另一個(gè)連接(并且可能需要等待其他連接可用)。這允許池化器處理更多客戶端,并且是推薦的方法。
最后一種方法是為每個(gè) SQL 語(yǔ)句獨(dú)立分配連接。理論上,這會(huì)帶來(lái)最高的靈活性和連接利用率。但是,這會(huì)導(dǎo)致一項(xiàng)事務(wù)跨越多個(gè)連接。由于許多事務(wù)設(shè)置與連接相關(guān),這可能會(huì)成為技術(shù)限制。
連接池解決方案
根據(jù)您使用的數(shù)據(jù)庫(kù)類型,可能有一些內(nèi)置的解決方案,或者您可能需要手動(dòng)配置它們。讓我們看一些示例。
內(nèi)置解決方案
根據(jù)您的基礎(chǔ)設(shè)施提供商,您也許能夠使用內(nèi)置或近內(nèi)置解決方案:
-
Neon PostgreSQL 數(shù)據(jù)庫(kù)有一個(gè)內(nèi)置的 PgBouncer
-
Supabase 有一個(gè)內(nèi)置的 Supavisor
-
適用于 PostgreSQL 的 Azure 數(shù)據(jù)庫(kù)支持內(nèi)置 PgBouncer
-
DigitalOcean 的 PostgreSQL 包括 PgBouncer
-
Azure 數(shù)據(jù)庫(kù)可與 ProxySql
-
Azure 數(shù)據(jù)庫(kù)可與 Heimdall 數(shù)據(jù)庫(kù)代理一起使用
-
ADO.NET 支持內(nèi)置連接池
-
Oracle 支持通用連接池對(duì)于 JDBC
-
Oracle 自治數(shù)據(jù)庫(kù)支持?jǐn)?shù)據(jù)庫(kù)駐留連接池
外部解決方案
您可以使用許多外部解決方案使用:
-
Amazon RDS 代理
-
Pgpool
-
PgBouncer
-
奧德賽
-
Heimdall 數(shù)據(jù)庫(kù)代理
-
ProxySQL
-
pgcat
案例研究:配置 PgBouncer
在此示例中,我們將研究 PgBouncer。
我們首先按照文檔中的方式安裝它。
然后我們需要配置它。最重要的設(shè)置是:
-
pool_mode:如何處理連接;我們可以使用事務(wù)
-
max_client_conn:配置可以連接到連接池的客戶端數(shù)量
-
default_pool_size:配置允許多少個(gè)服務(wù)器連接對(duì)于每個(gè)用戶數(shù)據(jù)庫(kù)
-
min_pool_size:要保留多少個(gè)備用連接
配置池化器后,我們可以使用pgbench驗(yàn)證其性能:
pgbench -c 10 -p -j 2 -t 1000 database_name
登錄后復(fù)制
PgBouncer 可以輕松地將每秒事務(wù)數(shù)增加 60%,如基準(zhǔn)測(cè)試所示:
-
對(duì) PostgreSQL 連接池進(jìn)行基準(zhǔn)測(cè)試:PgBouncer、PgCat和 Supavisor
-
通過(guò)連接池提高數(shù)據(jù)庫(kù)性能
-
使用 PgBouncer 增強(qiáng) PostgreSQL
總結(jié)
連接池可以提高性能并減少資源消耗。有許多內(nèi)置解決方案可以輕松地與我們的數(shù)據(jù)庫(kù)一起使用,無(wú)論我們將它們托管在哪里以及我們使用什么數(shù)據(jù)庫(kù)引擎。我們需要記住,連接池是另一個(gè)故障點(diǎn),需要小心處理。配置良好的連接池可以使每秒的事務(wù)數(shù)量增加近一倍,從而極大地提高性能。
路由網(wǎng)(www.lu-you.com)您可以查閱其它相關(guān)文章!