[實驗] HAProxy as PostgreSQL Connection Pool

HAProxy 適合作為 Connection Pool 使用嗎?

古哥
pgsql-tw
5 min readMay 25, 2021

--

HAProxy 是常見的 Connection Pool 方案,多數是用於 HTTP 的 Web 服務上。由於 HAProxy 也能用於 TCP 的負載導向服務,所以當然也可以用於 PostgreSQL 服務。先前我以實驗的方式介紹了 pgBouncer,「你當然需要 PgBouncer 啊」,本篇文章也以類似的方式來表現 HAProxy 的特性,並且以比較方式提供更為清淅的想像。

兩者都可以限制進入實際資料庫的查詢連線,並且接受大量的連線保持在等待的狀態,以維持資料庫的穩定度及效率。不過,兩者用途上仍然有許多不同,我先把比較寫在前面,實驗後的結論在文末:

HAProxy 優於 pgBouncer 之處

  1. HAProxy 更為泛用
    由於運作於 Layer 4 的關係,如果你希望能以更為一致的方式管理不同的負載服務,HAProxy 同時能夠服務到不同的網路服務。
  2. HAProxy 可以協助 Failover
    這點是 HAProxy 與 PostgreSQL 合作最重要的功能之一。它可以自動檢查 PostgreSQL 的狀態,並且在服務失效時切換新的連線到備選的主機。
  3. HAProxy 可以進行 Load Balance
    在已經進行資料複寫的情況下,可以對唯讀的資料主機進行連線的分流,也可以線上水平擴充。對於讀取需求繁重的服務,提供有效的解決之道。

pgBouncer 優於 HAProxy 之處

  1. pgBouncer 能夠做到資料庫層級的管理
    pgBouncer 是 Layer 7 的服務,以實作 PostgreSQL protocol 來實現其服務,所以能夠進行資料庫層次的管理。如依資料庫或使用者的資源分配,使用者認證,查詢或交易時限控制。
  2. pgBouncer 的連線成本較低
    這點於後面的實驗數據可以明顯看得出來。由於 pgBouncer 是運作於應用層的關係,在連線交接的時候,實際上是完全不需要中斷伺服器連線的(Layer 4 的角度),所以在連線的成本數據上明顯較低。
  3. pgBouncer 的連線交換效率高
    由於 pgBouncer 能夠識別資料庫查詢的狀態(idle),所以在大量連線的情況下能夠更有效率地透過交換連線,來減少等待連線的浪費。在實驗及實務上,pgBouncer 確實也能承受更高的連線等待數。

以下為實驗數據,簡單地使用 pgbench 來進行標準化的測試。在單主機上執行評測,以最小化網路延遲。pgbench 指令範例:

  • PostgreSQL: port=5555, max_connection=500
  • pgbouncer: port=5432, max_connection=1000, pool_size=100
  • haproxy: port=5433, frontend maxconn=1000, backend maxconn=100, timeout 600s

總是就是產生 150 個連線,持續查詢 60 秒而得到的結果,但同時間只保持 100 條連線到資料庫,也就是要製造一定有人在等待的情況。有自己實驗的人可以另開一個連線到資料庫查詢看看真實的連線數。

pgbench → HAProxy (5433) → PostgreSQL (5555)

overhead 為建立連線的成本,可以明顯觀察得出來,是很穩定地有點負擔。對照組(pgbouncer)如下:

pgbench → pgbouncer (5432) → PostgreSQL (5555)

連線成本僅有上者的 8%。也就是若以 HAProxy 取代 pgbouncer,那麼將會在連線效率上付出代價。

再來看一下 HAProxy 在連線數增加時的情況吧。

pgbench → HAProxy (5433) → PostgreSQL (5555)

橫軸為連線數,趨勢明顯為向下。至於為何最右側為 190,因為在本實驗的設定下,它只能承擔到 190,同時間 200 個連線就完成不了了。這部份就不需要對照組來製造傷害了。

雖然做了一些實驗看起來好像是對 HAProxy 不利的,但這只是為了要突顯每一件事都是有其成本的。如果你只是很直覺地想要可以自動容錯或負載平衡,別忘了思考看看其代價是否值得。

有關連線成本的部份,提示一下,加入 pgBouncer 和 HAProxy 一起合作可以有效改善,至於要怎麼合作比較好,我覺得可以保留給本文的讀者各位自行實驗,應該會滿有趣的。

簡單結論,如果是期待 HAProxy 要作為以 PostgreSQL Connection Pool 來使用的話,是不適合的;但我們更需要的是 HAProxy 所擁有容錯及分流優勢。至於 Connection Pool 的部份,pgBouncer 是省不了的,兩者需要相互合作才能有最大的效益。

--

--

古哥
pgsql-tw

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