PostgreSQL 開發者 Mailing Lists 中得知,PostgreSQL 內建 Connection Pool 的提案,包括程式原始碼,都已進入到 Review (審閱) 階段。

Connection Pool

作者表示,這個功能不難開發,但是因為牽扯到太多現有程式架構的變動,所以顯得複雜些。

若此功能正式穩定商用,可以算是很亮眼的應用了。畢竟這類的討論已太多且長年,每次討論某些話題時,這也是 PostgreSQL 常被拿出來討論的爭點之一,連 PostgreSQL 開發者內部也有歧義 (詳見 PostgreSQL 核心開發者在各處的留言)。

因為諸多原因,至今 PostgreSQL 主流開發者仍然傾向採用 Process-based 而非 MySQL 的 Thread-based 模型,但技術選擇很難只有優點沒有缺點,所以這相對也帶來了一些問題。

❶ Process 較 Thread 建立連線的時間開銷較高。既使現代 Linux Kernel 已將 Process 及 Thread 在這點的差距縮小不少,但因為模型本質不同,還是有些差距。

❷ Process 較 Thread 建立的記憶體開銷較高,因為缺失 Thread 實作的「共享」特性,使得每次連線建立時,都需要耗費較高的記憶體空間配置。以一台 8 GB 的機器而言,若一個連線佔用 1 MB,則可以支撐 8000 個連線;但若一個連線佔用 10 MB,則機器只能支撐 800 個連線。

結合以上二點,造成 PostgreSQL 在短時間擁進大量連線時,會較 Thread-based 模型的資料庫更早遇到效能瓶頸。

這也是為何通常採用 PostgreSQL 時,文章同時會建議配合引入 Connection Pool 軟體的原因,例如 PgBouncer。因為 Connection Pool 可以減少連線建立的時間 (節省連線時間開銷),又能有效降低連線數量 (節省記憶體)。但是否能節省或節省多少,足以另開專文討論了。

不過,採用 Connection Pool 也不是沒有缺點,通常比較麻煩的是「架構」複雜度提高。因為多了 Connection Pool 的「服務」,所以要多考量:

❶ 需不需要高可用性?若要,則與無 Connection Pool 架構相比,至少要多出二台 Connection Pool 服務的實例。

❷ 因為 Connection Pool 本身是「服務」,引入新服務就有健康檢測及備援問題,所以要隨時檢測是否正常,而且異常時要能切換連線至上述 ❶ 提供的備援實例。

上述二點,使得引入 Connection Pool 而導致整體架構在初期會變得比較複雜,機器成本及維護成本也隨之提高。

當然,並不是 Thread-based (如 MySQL) 不需要 Connection Pool 或沒有其他問題,只是可以讓我們「較晚」才轉用 Connection Pool 架構。若真遇到高併發高流量,如阿里巴巴,他們也依然需要 Connection Pool 以減援 MySQL 的壓力。

在這點,MySQL 也不是沒有繼續努力。從 MySQL 5.6 開始就致力於節省連線的開銷,Oracle 提供的官方資料顯示,MySQL 5.7 的連線開銷只有 MySQL 5.6 的 62.5%,只有 MySQL 5.5 的 40%。每次的連線開銷節省,都能讓 MySQL 能更晚進入 Connection Pool 架構。

我是非常期待 PostgreSQL 內建 Connection Pool,如此在初期建置時,架構及維運都會輕鬆不少。