一文了解PG空閑連接對性能的影響
PG空閑連接對性能的影響
該系列的第一篇為:PG空閑連接的資源消耗討論PG如何管理連接以及空閑連接如何消耗內存和CPU。本文討論空閑連接對PG性能的影響。
事務率影響
PG獲取數(shù)據的時候,首先看請求頁在沒在共享內存。如果共享內存沒有請求頁,則從操作系統(tǒng)緩存取,如果也沒有,則需要請求磁盤上的數(shù)據頁。共享內存最快,操作系統(tǒng)緩存次之,磁盤最慢。隨著PG連接的增長,操作系統(tǒng)緩存的可用內存就會減小,從而從操作系統(tǒng)緩存中移除數(shù)據頁。下次再進行數(shù)據頁查詢時就會從磁盤上請求,因此性能變得更慢。
如果PG實例的空閑內存處于低水位,就會使用swap。這也是位于磁盤上,因此也很慢。使用swap空間可幫助釋放一些內存,但是如果swapped 頁再次被OS請求時,會被讀回,導致IO的增加。更多信息請查看swap管理:https://www.kernel.org/doc/gorman/html/understand/understand014.html
可用內存對性能的影響取決于工作負載、數(shù)據集、總共的可用內存。如果數(shù)據集比總可用內存小,空閑內存的減少不會有明顯影響,若數(shù)據集比總可用內存還大,就會產生巨大影響。
性能測試
下面小節(jié)顯示了通過pgbench進行的性能測試。測試中Amazon RDS for PG實例為db.m5.large,2vCPU,8GB內存。1個EBS的IO為3000IOPS。
每個測試都有兩個階段,第一階段pgbench執(zhí)行1個小時,沒有其他工作負載。這個提供了一個基準事務率。
第二個階段,再次執(zhí)行pgbench前打開1000個連接,每個連接從information_schema表獲取一行數(shù)據。下面是步驟:
1)打開一個連接
2)獲取所有表名及information_schema視圖:
SELECT table_schema||'.'||table_name as relname from information_schema.tables WHERE table_schema='information_schema';
3)循環(huán)執(zhí)行select:
SELECT * FROM information_schema.columns LIMIT 1;
4)對于1000個連接重復以上步驟
5)事務提交后不進行斷開,保持空閑狀態(tài)
重啟實例后,內存中沒有緩存任何數(shù)據頁。第一次執(zhí)行pgbench會加載請求的數(shù)據頁到內存,隨后再次執(zhí)行pgbench,cache中的數(shù)據頁可以重用,此時不再需要從磁盤加載。
為了最小化頁緩存的影響,在執(zhí)行測試案例前執(zhí)行一個初始步驟。下圖顯示了打開1000個連接時,實例內存時如何從4.88GB下降到90MB的。
正如前系列介紹,雖然連接是空閑的,他們也會消耗內存和CPU資源。這個結果顯示空閑連接對性能的影響。
事務率測試1:標準pgbench
第一個測試中,使用標準配置執(zhí)行100個客戶端連接,結果:
transaction type:
1000個連接下,結果:
transaction type:
結果表明,TPS從1249下降到1140,有8.7%的下降。
事務率測試2:select-only
因為空閑連接消耗了內存減小了頁緩存可用內存,所以這些空閑連接對讀的影響尤為明顯。為測試這點,使用-S配置運行pgbench,使用內置的select only腳本。結果:
transaction type:
1000個空閑連接下:
transaction type:
TPS從1969下降到1610,有18.2%的下降。
事務率測試3:custom pgbench
執(zhí)行腳本:
set nbranches :scaleset naccounts 100000 * :scaleset aid random(1, :naccounts)set bid random(1, :nbranches)BEGIN;SELECT * FROM pgbench_accounts WHERE aid >= :aid AND aid < (:aid + 5000) AND bid=:bid LIMIT 1;END;
腳本中每個事物從pgbench_accounts表讀取5000行數(shù)據,然后僅返回1條。結果:
transaction type: pgbench_script.sqlscaling factor: 5000query mode: simplenumber of clients: 100number of threads: 2duration: 600 snumber of transactions actually processed: 227484latency average = 264.140 mstps = 378.586790 (including connections establishing)tps = 378.592772 (excluding connections establishing)
1000個空閑連接下,結果為:
transaction type: pgbench_script.sqlscaling factor: 5000query mode: simplenumber of clients: 100number of threads: 2duration: 600 snumber of transactions actually processed: 124114latency average = 484.485 mstps = 206.404854 (including connections establishing)tps = 206.507645 (excluding connections establishing)
結果顯示TPS從378下降到206,有46%的下降。通過Amazon RDS Performance Insights可以看到引擎wait events詳細信息。下面兩個圖顯示了DataFileRead等待事件中耗費時間最多的。即等待從表數(shù)據文件中讀取數(shù)據。
下圖顯示了Amazon CloudWatch指標中的讀負載:
第一次執(zhí)行時讀為87MB/s,第二次1000個連接下,增長到117MB/s?臻e連接消耗了操作系統(tǒng)內存,導致OS cache變小。因此需要從磁盤讀取更多數(shù)據頁,從而導致性能的衰減。
連接池
連接池可幫助減小數(shù)據庫連接帶來的影響?梢允褂胮gbouncer或者Amazon RDS Proxy。這些連接池可以限制連接數(shù)量。
Pgbouncer
Pgbouncer是輕量級的連接池組件,支持下面三種模式:
Session mode:每個應用連接綁定到一個數(shù)據庫連接上。如果連接處于空閑狀態(tài),pgbouncer不能將它給其他應用連接重用。
Transaction mode:一個事務完成后,該連接就可以重用
Statement mode:一個SQL語句完成后就可以將該連接給其他客戶端重用。
大多數(shù)應用中,使用transaction mode可以提供最優(yōu)結果。下面測試pgbouncer配置了最大5000客戶端連接,但我們的測試中最大連接設置為200.pgbench運行在pgbouncer pool中。結果:
transaction type: pgbench_script.sqlscaling factor: 5000query mode: simplenumber of clients: 100number of threads: 2duration: 600 snumber of transactions actually processed: 227064latency average = 264.600 mstps = 377.928241 (including connections establishing)tps = 377.928476 (excluding connections establishing)
運行過程中,可以查看連接狀態(tài):
pgbouncer=# show pools;-[ RECORD 1 ]-----------database | pgbenchuser | postgrescl_active | 100cl_waiting | 0sv_active | 100sv_idle | 0sv_used | 0sv_tested | 0sv_login | 0maxwait | 0maxwait_us | 0pool_mode | transaction
Pool狀態(tài)顯示有100個客戶端連接(cl_active)從而有100個活躍server連接(sv_active)。第二次執(zhí)行,打開1000個連接,并處于空閑狀態(tài)。Pooler不需要維護任何服務端連接:
pgbouncer=# show pools;-[ RECORD 1 ]-----------database | pgbenchuser | postgrescl_active | 1000cl_waiting | 0sv_active | 0sv_idle | 1sv_used | 0sv_tested | 0sv_login | 0maxwait | 0maxwait_us | 0pool_mode | transaction
1000個空閑連接下,執(zhí)行pgbench:
transaction type: pgbench_script.sqlscaling factor: 5000query mode: simplenumber of clients: 100number of threads: 2duration: 600 snumber of transactions actually processed: 226827latency average = 264.935 mstps = 377.451418 (including connections establishing)tps = 377.451655 (excluding connections establishing)
下面顯示使用連接池是,性能沒有影響:
pgbouncer=# show pools;-[ RECORD 1 ]-----------database | pgbenchuser | postgrescl_active | 1100cl_waiting | 0sv_active | 100sv_idle | 0sv_used | 0sv_tested | 0sv_login | 0maxwait | 0maxwait_us | 0pool_mode | transaction
總共有1100個客戶端連接,但是僅有100個服務端連接活躍。
該測試,RDS實例有2個CPU,因此100個進程并行執(zhí)行,導致大量上下文切換,從而造成性能衰減。Pgbouncer配置最多20個數(shù)據連接下性能:
transaction type: pgbench_script.sqlscaling factor: 5000query mode: simplenumber of clients: 100number of threads: 2duration: 600 snumber of transactions actually processed: 256267latency average = 234.286 mstps = 426.828543 (including connections establishing)tps = 426.828801 (excluding connections establishing)
得到了個更高的TPS,狀態(tài):
pgbouncer=# show pools;-[ RECORD 1 ]-----------database | pgbenchuser | postgrescl_active | 20cl_waiting | 80sv_active | 20sv_idle | 0sv_used | 0sv_tested | 0sv_login | 0maxwait | 0maxwait_us | 125884pool_mode | transaction
只有20個客戶端連接活躍。剩下的80個連接等待被分配。更多的連接并不意味著更多的吞吐量。較少的客戶端連接有助于上下文切換和資源爭用,從而提高總體性能。
總結
連接數(shù)多并不意味著高吞吐。增加連接數(shù),會增加上下文切換和資源爭用,從而影響性能。
PG連接即使空閑狀態(tài),也會消耗資源?臻e連接不會影響性能的假設不正確。
應用設計的時候需要考慮不要有太多連接。
請輸入評論內容...
請輸入評論/評論長度6~500個字
最新活動更多
-
10月31日立即下載>> 【限時免費下載】TE暖通空調系統(tǒng)高效可靠的組件解決方案
-
即日-11.13立即報名>>> 【在線會議】多物理場仿真助跑新能源汽車
-
11月28日立即報名>>> 2024工程師系列—工業(yè)電子技術在線會議
-
12月19日立即報名>> 【線下會議】OFweek 2024(第九屆)物聯(lián)網產業(yè)大會
-
即日-12.26火熱報名中>> OFweek2024中國智造CIO在線峰會
-
即日-2025.8.1立即下載>> 《2024智能制造產業(yè)高端化、智能化、綠色化發(fā)展藍皮書》
推薦專題
- 高級軟件工程師 廣東省/深圳市
- 自動化高級工程師 廣東省/深圳市
- 光器件研發(fā)工程師 福建省/福州市
- 銷售總監(jiān)(光器件) 北京市/海淀區(qū)
- 激光器高級銷售經理 上海市/虹口區(qū)
- 光器件物理工程師 北京市/海淀區(qū)
- 激光研發(fā)工程師 北京市/昌平區(qū)
- 技術專家 廣東省/江門市
- 封裝工程師 北京市/海淀區(qū)
- 結構工程師 廣東省/深圳市