七八年前,老馮手里維護著一百套大規(guī)模 PostgreSQL 集群,兩百多臺頂配物理機,開始做高可用方案選型。 那段時間我把市面上能叫得出名字的方案都翻了一遍:Patroni、Corosync + Pacemaker、repmgr、Stolon、pgpool-II……
最后選了 Patroni。基于它做 HA,上線后效果很穩(wěn):這些年碰到幾十次真實硬件故障,RTO 基本都在二三十秒?yún)^(qū)間。 最爽的是:。
回頭看,這個選擇屬于 “少走七年彎路”。今天無論你看傳統(tǒng) Linux 發(fā)行版方案(Percona、AutoBase 等), 還是 K8S Operator(Crunchy PGO 等),主流 PG 發(fā)行版高可用幾乎都繞不開 Patroni。 Patroni 在 GitHub 上的 Star (8.1K) 也超過其他這些 HA 組件的總和。
那么,為什么是 Patroni 成為了事實標準?它到底好在哪里? PostgreSQL 高可用到底應該怎么做?今天我們就來聊聊這個話題。
可用性,RTO與RPO
可用性 (Availability)是一個服務指標,一般用 “服務可用時間/總時間窗口” 的百分比來計算,時間窗口一般是整年或者整月。 通常 99.99% 以上的可用性(4個9)被稱作高可用 —— 意味著年度故障預算 52 分鐘,或月度故障預算 4.3 分鐘。
但可用性是業(yè)務連續(xù)性指標,不是數(shù)據(jù)庫的 技術(shù)能力。一個經(jīng)典誤區(qū)是:你完全可以單憑運氣做到 100% 的可用性,這很常見。 云廠商承諾幾個9的SLA,本質(zhì)上也不是歷史戰(zhàn)績,而是代金券對賭協(xié)議。
真正重要的是,發(fā)生故障的頻率與恢復時間。對于數(shù)據(jù)庫來說,你控制不了故障發(fā)生的頻率(MTBF); 但你能控制的是:發(fā)生故障后最多丟多少數(shù)據(jù),以及要多長時間恢復。這就是兩個核心可靠性指標 —— RPO 與 RTO:
RPO(Recovery Point Objective,恢復點目標) : 定義了在主庫發(fā)生故障時,允許丟失的最大數(shù)據(jù)量。
RTO(Recovery Time Objective,恢復時間目標) : 定義了在主庫發(fā)生故障時,系統(tǒng)恢復寫入能力所需的最長時間。
RTO 和 RPO 代表了真正 抗事的能力,也是我們考察高可用方案的關(guān)鍵所在。
那么 RPO / RTO 要多好才算好?這里有幾個相關(guān)的國際/國家標準,規(guī)定了各個行業(yè)要求的 RPO / RTO 水平。 比如 SHARE-78,GB/T 20988-2025,SOX / HIPPA / Basel III 都對 RTO/RPO 提出了合規(guī)要求。 于今年元旦開始實行的國內(nèi)的 《網(wǎng)絡(luò)安全技術(shù) 信息系統(tǒng)災難恢復規(guī)范》將災難恢復劃分為六個等級:
![]()
![]()
最高等級的容災要求,通常要求 RTO 在分鐘級(幾十秒的量級),RPO = 0 不丟失數(shù)據(jù)。 十幾年前,你可能要花幾百萬上千萬采購專有軟硬件來滿足這樣的要求。 而在 2026 年的當下,有了 Patroni + PostgreSQL,實現(xiàn)這種容災水平的軟件成本已經(jīng)無限接近于零。
但顯然,因為信息不對稱,很多人并不知道這件事。所以今天我就來給大家講講 PostgreSQL 高可用的 SOTA 事實標準 —— Patroni。
太長不看
Patroni 在合理配置的情況下,可以輕松做到 RTO < 30s,RPO = 0 的水平,這是經(jīng)過理論推演與實戰(zhàn)檢驗的結(jié)果。 在 RPO 上,Patroni 可以實現(xiàn) Oracle 最大性能/最大可用/最大保護模式,甚至提供了比 Oracle 最大保護模式更強的數(shù)據(jù)一致性選項。 在 RTO 上,Patroni 可以在常規(guī)硬件上實現(xiàn)端到端 RTO < 30s 的水平,包含從故障檢測,主從切換,到負載均衡器健康檢查的全鏈路耗時。 接下來,我們將詳細介紹高可用中 RPO 與 RTO 的利弊權(quán)衡。
RPO 利弊權(quán)衡
RPO 定義了主庫故障時允許丟失的最大數(shù)據(jù)量。對于金融交易這類數(shù)據(jù)完整性至關(guān)重要的場景,通常要求 RPO = 0,即不允許任何數(shù)據(jù)丟失。
然而更嚴格的 RPO 指標是有代價的:它會引入更高的寫入延遲,降低系統(tǒng)吞吐量,并且存在從庫故障導致主庫不可用的風險。 因此對于常規(guī)場景,通常可以接受一定量的數(shù)據(jù)丟失(例如不超過 1MB),以換取更高的可用性與性能。
在異步復制場景下,從庫和主庫之間會存在一定的復制延遲(取決于網(wǎng)絡(luò)和吞吐量,正常在 10KB~100KB / 100μs~10ms 的數(shù)量級)。 這意味著主庫故障時,從庫可能還沒有完全同步最新數(shù)據(jù)。此時如果發(fā)生故障切換,新主庫可能會丟失一些尚未復制的數(shù)據(jù)。
![]()
實現(xiàn)原理
Patroni 提供了一個參數(shù) maximum_lag_on_failover,用于控制潛在數(shù)據(jù)丟失量的上限,默認為 1048576 (1MB)。 這意味著自動故障轉(zhuǎn)移時,最多可以容忍 1MB 的數(shù)據(jù)丟失。當主庫宕機時,如果有任何一個從庫的復制延遲在這個值以內(nèi),Patroni 將自動提升該從庫為新主庫。
然而當所有從庫的復制延遲都超出這個閾值時,Patroni 將拒絕進行自動故障切換以避免數(shù)據(jù)丟失。 此時需要人工介入決策:等待主庫恢復(可能永遠不會恢復),還是接受數(shù)據(jù)損失并強制提升一個從庫。
這就引入了第一項利弊權(quán)衡:你需要根據(jù)業(yè)務需求配置這個值,在 可用性 和 一致性 之間進行 利弊權(quán)衡。 增大這個值可以提高自動故障切換的成功率(降低不可用時長),但也會增加潛在的數(shù)據(jù)丟失量上限。
在不允許任何數(shù)據(jù)丟失的場景下,你可以使用 Patroni 的同步模式與嚴格同步模式,來確保 RPO = 0。
Oracle 類比
對于熟悉 Oracle 的用戶來說,Patroni 的復制模式可以類比 Oracle Data Guard 提供的三種數(shù)據(jù)保護模式:最大性能、最大可用、最大保護。
![]()
實際上,通過配置 Patroni 和 PostgreSQL,你甚至可以實現(xiàn)比 Oracle 最大保護模式更強的數(shù)據(jù)一致性選項。 例如 Oracle Data Guard 的最大保護模式只要求一個同步從庫確認寫入,而 Patroni 可以配置多個同步從庫確認寫入, 甚至確認重放完成(remote_apply),來進一步提高數(shù)據(jù)持久性與一致性。
![]()
JEPSEN 提供了一個非常罕見的例子,我們會有一篇專門的文章詳細介紹。
對于絕大多數(shù)業(yè)務來說,異步復制(最大性能)模式提供的 RPO 保證已經(jīng)足夠。 對于對數(shù)據(jù)完整性要求極高的場景,可以使用最大可用 / 最大保護模式來確保 RPO = 0。
RTO 利弊權(quán)衡
RTO 定義了主庫故障時,系統(tǒng)恢復寫入能力所需的最長時間。
當主庫故障時,整個恢復流程涉及多個階段:檢測故障、DCS 鎖過期、新主選舉、執(zhí)行 promote、負載均衡器感知新主庫。因此不同于 RPO,RTO 不可能等于零。
而且需要注意,RTO 并非越小越好。更短的 RTO 意味著縮短各階段的超時時間,這會使集群對網(wǎng)絡(luò)抖動更加敏感,從而增加誤切風險。 RTO 設(shè)置的太小,切換耗時雖然變短,但是誤切概率上升了,切換頻率增加,整體可用性反而下降了。
這就引出了第二項利弊權(quán)衡,你需要根據(jù)實際網(wǎng)絡(luò)條件選擇合適的配置,在 恢復耗時 與 誤切概率 之間取得平衡: 網(wǎng)絡(luò)質(zhì)量越差,越應該選擇保守的配置;網(wǎng)絡(luò)質(zhì)量越好,越可以選擇激進的配置。
關(guān)于 RTO 的營銷話術(shù)
因為 RPO 這個指標沒什么好吹的,RTO 已經(jīng)淪為數(shù)據(jù)庫營銷吹牛的重災區(qū)。有時候是拿特例場景樂觀路徑來以點蓋面,或者在驅(qū)動 / 連接池層面排隊并用統(tǒng)計口徑做文章。因此討論 RTO 的時候,需要明確幾個因素:
故障域 :是計算節(jié)點故障,還是存儲故障、網(wǎng)絡(luò)故障?
測量口徑 :可用標準是數(shù)據(jù)庫可寫入,還是 LB,APP,連接池/驅(qū)動層可用?
統(tǒng)計量 :使用的是最優(yōu)值、最差值,還是平均值與中位數(shù)?
網(wǎng)絡(luò)條件 :是同機柜、同機房、同城,還是跨大洲的全球復制?
通常來說,在同機柜網(wǎng)絡(luò)條件中,常見故障路徑下,RTO < 30s 算是業(yè)界頂級水平。 如果有人不帶場景、故障域、統(tǒng)計口徑說自己 RTO < 10 秒,通常可以判定為吹牛。
嚴肅的 RTO 的討論非常復雜,在下面,我們會討論四種典型網(wǎng)絡(luò)條件下的參數(shù)配置,兩種主要故障路徑下的 RTO 拆解,以及最優(yōu),平均,最劣三種情況; 并使用更為嚴格的 HAPRXOY 端側(cè)接受連接寫入作為 RTO 的測量口徑,如果沒有特別解釋,我們討論的是用于兜底的 最劣 情況,而非平均或最優(yōu)情況。
架構(gòu)原理
RTO 無法脫離架構(gòu),場景,環(huán)境,資源來討論,因此我們需要先來介紹一下基于 Patroni / Etcd / HAProxy 的經(jīng)典高可用架構(gòu),在這個架構(gòu)中:
![]()
?PostgreSQL 使?標準流復制搭建物理從庫,主庫故障時由從庫接管。?Patroni 負責管理 PostgreSQL 服務器進程,處理高可用相關(guān)事宜。?Etcd 提供分布式配置存儲(DCS)能力,并用于故障后的領(lǐng)導者選舉?Patroni 依賴 Etcd 達成集群領(lǐng)導者共識,并對外提供健康檢查接口。?HAProxy 對外暴露集群服務,并利? Patroni 健康檢查接口,自動分發(fā)流量至健康節(jié)點。
在這套架構(gòu)中,高可用 RTO 主要取決于 Patroni 參數(shù),次要取決于 Haproxy 參數(shù)。
參數(shù)配置
Patroni 中關(guān)于 RPO 的核心參數(shù)只有三個,但考慮 RTO 時,總共要納入的參數(shù)有 10 個: Patroni 5 個,HAProxy 健康檢查 5 個。這十個參數(shù)的組合決定了 RTO 的表現(xiàn)。
請注意,默認參數(shù)的表現(xiàn)并不是最優(yōu)的。我在長期實踐中提出了四組不同網(wǎng)絡(luò)條件下的參數(shù)優(yōu)化配置:fast、normal、slow、safe。
![]()
四種模式實際上對應著四組不同的參數(shù)配置,如下所示:
![]()
這四種模式下,RTO 的最壞,最好,平均表現(xiàn)水平如下圖所示。
![]()
我們以最壞口徑作為討論的基準, 在默認配置下 RTO < 45s,最優(yōu)模式下 RTO < 30s。 更寬容的模式則設(shè)置有 90s / 150s 的 RTO 上線目標。
這里特別需要提到的是,市面上絕大多熟 PG 高可用方案幾乎都沒有修改 Patroni 默認參數(shù), 盡管默認參數(shù)在常規(guī)被動故障切換中提供 RTO < 45 秒的表現(xiàn),但默認 primary_start_timeout 的 300 秒配置, 會導致 PG 主庫崩潰重新拉起這個故障場景中,最劣表現(xiàn)高達 324 秒,違背常規(guī)的 RTO 目標。
如果你自己手搓 Patroni 高可用,這一點務必注意。
故障路徑
那么這個圖里的數(shù)據(jù)是怎么計算得到的呢?這里我們就要討論 故障路徑 了。
在 Patroni 這套高可用架構(gòu)中,有 10 種典型故障:節(jié)點宕機 / 假活、PG 崩潰 / 拒絕連接 / 假活、Patroni 崩潰 / 假活、主庫 / DCS 網(wǎng)絡(luò)中斷、存儲故障等等。 這些故障總體可以劃分為五條 RTO 拆解路徑,在討論最壞情況時,歸并到兩條典型的故障路徑:
被動檢測 : Patroni 掛了或者網(wǎng)絡(luò)隔離,主庫無法續(xù)租,觸發(fā)集群選舉
主動檢測 : Patroni 活著,嘗試修復 PG 掛了這種問題,超時后觸發(fā)集群選舉
這兩種故障路徑殊途同歸,可以用下面的流程圖表示:
![]()
這兩條故障路徑的 RTO 計算方式有差異,下面會簡要介紹,詳細完整的分析報告請參閱下面的文檔: http://pigsty.cc/docs/concept/ha/failure/[1]
![]()
![]()
這里的 RTO 時序拆解,給出了 RTO 的下界和上界。 我們在設(shè)定的時候,以上界最悲觀的情況設(shè)置,確保滿足最嚴格的容災等級要求。
考慮 平均 情況的話 fast 檔位在 23-24 秒,默認 norm 檔位在 34-35 秒的水平。
![]()
![]()
關(guān)于 RAC 與分布式數(shù)據(jù)庫
有些數(shù)據(jù)庫承諾非常低的 RTO,甚至號稱秒級切換、RTO = 0。這些方案通常使用共享存儲 RAC 架構(gòu),或者分布式 Raft/Paxos 協(xié)議。 但仔細推敲就會發(fā)現(xiàn),這些聲稱往往只針對特定故障域成立,而且會因為架構(gòu)上的利弊權(quán)衡引入其他局限性。
以 Oracle RAC 為例,多個計算節(jié)點訪問同一個底層磁盤陣列。在實例故障時確實可以快速切換,但當?shù)讓哟鎯Τ霈F(xiàn)單點故障時,RTO 就直接炸了 —— 所有節(jié)點一起完蛋。 這本質(zhì)上是把復雜度和風險下推到存儲層,逼著你購買價格高昂的企業(yè)級 SAN 存儲來兜底。 而且真要做跨區(qū)域容災,還是得靠 Data Guard 這類主從復制技術(shù)。然后 RTO 又回到幾十秒的量級了。 所以 Oracle RAC 的營銷宣傳在我看來極具誤導性。
一些 NewSQL 分布式數(shù)據(jù)庫稍微誠實一點。比如 CockroachDB 用 Raft 協(xié)議管理多節(jié)點集群,在主要故障場景下號稱 RPO = 0、RTO < 9s。 這個數(shù)字是可信的,但代價是什么?翻了幾倍的寫入延遲,幾分之一的性能吞吐,以及更高的架構(gòu)/運維復雜度。 關(guān)于這一點,老馮在《》中詳細探討過(還有《DDIA 第六章:復制》)。 說到底一切都是利弊權(quán)衡,只要你不在乎代價,AWS 開源的 pgactive PG 擴展號稱能把 RTO 做到亞秒級。
相比之下,無共享架構(gòu)(Shared Nothing)的思路就清爽得多:顯式管理多套存儲副本,每個節(jié)點都是自治的,沒有存儲單點。 共享存儲方案很難水平擴展,而無共享架構(gòu)可以輕松拉出幾十個從庫 —— OpenAI 1 主 40 從 ,我們在探探1主32從的 PG 集群就是這么玩的。 這也是為什么過去二十年,無共享架構(gòu)逐漸成為數(shù)據(jù)庫高可用的主流選擇。
老馮自己的看法是,這年頭鼓吹共享存儲高可用方案,有大概率是為了給硬件/云盤帶貨。 老馮對這種事向來不感冒,本文就進一步具體展開批判了。但后面也許會專門寫一篇,聊聊 RAC 與分布式數(shù)據(jù)庫的真實表現(xiàn)與實際代價, 順便講講 Corosync + Pacemaker 這種極其繁瑣的老古董 PG 高可用方案為什么該進博物館了。
關(guān)于實操
聊完原理,說說落地。我知道很多人看到這里會想:道理我都懂,但讓我自己一臺一臺去配 Etcd、Patroni、HAProxy,俺做不到啊。
放心,老馮自己也不會干這種傻事。
我把這套 PG 高可用方案做成了開源免費、一鍵部署的完整解決方案:Pigsty。
![]()
你也可以用別的 —— AutoBase,Percona,各種 K8S PG Operator 也大同小異。 反正高可用部分的核心架構(gòu)基本都是一樣的 Patroni + etcd + Haproxy。
不過,很多用著 patroni 的方案幾乎都清一色用著默認參數(shù)。 看起來沒人認真優(yōu)化過,也沒人做過精細的 RTO 時序分析,也許是放到“企業(yè)級”方案里去了吧。 而 Pigsty 在大規(guī)模生產(chǎn)環(huán)境中實戰(zhàn)打磨出來,針對不同網(wǎng)絡(luò)條件提供了多種 RTO/RPO 策略可選, 除此之外,還內(nèi)置了連接池、自動故障切換、完整的監(jiān)控告警體系 —— 開箱即用不操心。
另外提醒一句:光有高可用還不夠。硬件故障 Patroni 能扛,但誤刪數(shù)據(jù)、邏輯錯誤這類場景,還得靠 PITR 來兜底。 所以今天講的是 PostgreSQL 高可用的事實標準——Patroni,后面還會介紹備份恢復的事實標準 —— pgBackRest。
朋友們,別折騰手搓 PG 高可用了!土法自建對技術(shù)成長和業(yè)務發(fā)展都沒啥幫助 —— 把原理搞明白會用就行。 與其重復造輪子,不如折騰折騰怎么用好 PG 本身,這里能玩的擴展太多了,可比折騰什么 HA PITR 有意思多了。
小結(jié)
通過精細的參數(shù)調(diào)優(yōu),Patroni 的 RTO 上界可以被精確控制在不同檔位。 在常規(guī)網(wǎng)絡(luò)環(huán)境下,30 秒的 RTO 水平觸手可及。 這些年我在生產(chǎn)環(huán)境中經(jīng)歷的幾十次真實故障切換,監(jiān)控數(shù)據(jù)顯示 RTO 穩(wěn)定在 20~30 秒,完全滿足最嚴苛的金融級容災要求。
七年前做這個選型時,Patroni 還是個小眾方案。當時不少人覺得它不夠"企業(yè)級",不如商業(yè)方案有保障。 現(xiàn)在再看,那些迷信復雜架構(gòu)和昂貴軟件的團隊,要么還在為高可用焦頭爛額,要么早就悄悄換成了 Patroni。
技術(shù)選型這件事,從來不是看誰更復雜、誰更貴,而是看誰能真正把問題解決掉。 Patroni 用最簡潔的架構(gòu)實現(xiàn)了最可靠的效果,這就是它成為事實標準的原因。
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺“網(wǎng)易號”用戶上傳并發(fā)布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.