你當然需要 PgBouncer 啊

讓資料庫專心當個資料庫吧!

古哥
古哥
Oct 13, 2019 · 5 min read

這篇利用 PgBouncer 來做一個小小的實驗,給大家瞭解看看 Connection Pool 的效果如何,也提供簡易的設定檔,可以給想要試做的朋友當作初步的環境建置設定。

實驗架構

Image for post
Image for post

本實驗的 Client 使用 pgbench 來模擬查詢和連線,PostgreSQL 連線上限照預設為 100,PgBouncer 則設為 2,000。pgbench 本身能執行的同時連線數為 1,000 個,所以就實驗到 1,000 個同時連線。不論有沒有 pgBouncer,對 client(pgbench) 而言的執行方式都完全一樣。範例如下,只有 -p 的 port 目標不同,-c 和 -j 控制連線數。

數據結果

總之就先看一下結果吧!

https://gist.github.com/ycku/d148f47e366a9fc636d8a7ddbf7913d8

結果都是 pgbench 所產出的,TPS (Transactions per second),越高越好。「including」和「excluding」則分別代表了「including connections establishing」及「excluding connections establishing」,也就是是否採計建立連線所需時間。很明顯就可以看到,連線時間的成本並不低。

畫個圖應該會更清楚。

Image for post
Image for post

紅線和藍線是沒有使用 PgBouncer 的部份,因為超過 100 個同時連線跑不出來,後面就沒有啦。而綠線和黃線則一路測到 1,000 個同時連線,到最後效能也是掉了下來,是為了表現 connection pool 也是有極限的啦,而這個極限視你的應用查詢和軟硬體環境而定,建議可以定期自我測試一下,看緊急情況時可以開到多大。

為何要使用 pgbouncer?

不囉嗦,就列舉一些好處參考吧。

  1. 提升效能
    從本次實驗數據來看,有很明顯的效能差異,即使是在 100 個連線以下也有相同的趨勢。就算你的連線數不多,就統一都使用 connection pool 也沒什麼損失。
  2. 降低連線成本
    另一個數據上顯而易見的是連線的成本,從 4 成降到 1 成多,這些節省下來的時間當然就回饋到實際處理資料的效能中囉。
  3. 提高連線數
    以本實驗來說,雖然資料庫一直都只設定 100 個連線上限,但對於外面應用程式而言,則可以擴展到 1,000 個。事實上這是建議的作法,你不應該讓資料庫本身的連線數量去追逐應用程式的要求。
  4. 保護資料庫
    這點其實是最重要的,實際上的確會發生過多連線數湧入時,造成資料庫服務異常,甚至遺失資料。資料的保全當然是資料庫系統最重要的任務之一,connection pool 作為一道保護,即使因為攻擊而失去服務能力,資料庫也不會受到影響。
  5. 幾乎沒有額外負擔
    負擔可分為兩點,一是 PgBouncer 的資源需求很低,二是設定簡單。你不需要有額外的主機,也不需要為了它保留系統資源。它不保存任何資料,服務重啓就能解決異常狀態。對於管理人員來說是相當友善的。
  6. 安全性
    通常使用了 Pgbouncer 之後,PostgreSQL 就會設定成只接受 pgbouncer 的來源連線了,多餘的連線嘗試就會被擋在 PgBouncer 之外。更具體一點,當 PostgreSQL 本機啓用了 PgBouncer 之後,就設定為只接受本機連線。

資料庫連線應該設多大

要考慮這個問題必須要先認同,資料庫最重要的工作是處理資料,而不是接受連線。個人經驗上,一般的 PostgreSQL 服務,我個人不會設定到超過 500 個以上,甚至為了更高的可用性,降到 50 個以下也有可能。

目標只有一個,讓資料庫好好把眼前的工作做完

軟體系統並非完美,現實上,在多工的情境下確實存在著各種崩潰的可能性,只是如果崩潰的是資料庫,通常就代表整個服務崩潰,所以不得不更加多保護它一些。

當然現實上,也還是希望資料庫可以同時服務更多連線,以提升資源利用率,這點就交給 Connection pool 來管理。其他資料庫有些會直接內建 Connection pool 服務並不是沒有道理的。

如果你的系統沒有遇到異常,或效能下降的問題,你可以偶爾嘗試加大 PostgreSQL 連線數來嘗試取得更好的效能,但不應該時常變更。而當你增加連線數的同時,和 write ahead log 及記憶體相關的參數通常也需要增加,甚或硬體資源的增加,否則它們可能會產生另一個系統不穩定的因素。

其他

PgBouncer 和其他 connection pool 相比的缺點是功能很少,第一次設定完就很空虛了。剩下的時間就都回到 PostgreSQL 和應用程式身上吧。

不需要捨棄應用程式端的 Connection Pool,兩端各有各的作用,pgBouncer 的設定並不需要考慮應用程式端的連線架構。

你也可以套用多層次的 PgBouncer 來做到更多緩衝或多個 PostgreSQL 資料庫的單一入口功能,使用彈性很高。

額外和 PgBouncer 有關的是,這個專案規模不算大,想要瞭解 PostgreSQL protocol 的朋友可以 trace 它的原始碼來試試看。

Image for post
Image for post

上圖為一般化的架構圖,pgbouncer 為兩層式設計,中間的 pgBouncer 依資料庫分流,而和 PostgreSQL 較近的 pgBouncer 則負責保護資料庫本身。兩者的流量和認證方式還可以額外再做更細部的調整。

pgsql-tw

這裡是 PostgreSQL 台灣使用者社群,歡迎任何人投稿!

古哥

Written by

古哥

解決不了問題,就解決提出問題的人

pgsql-tw

pgsql-tw

你懂資料庫,資料庫就會幫你🐘

古哥

Written by

古哥

解決不了問題,就解決提出問題的人

pgsql-tw

pgsql-tw

你懂資料庫,資料庫就會幫你🐘

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store