PostgreSQL高可用之Repmgr和Patroni部分場景對比

T1YSL發表於2022-08-11

PostgreSQL資料庫有著各種各樣的高可用方案,絕大多數,都是基於流複製機制實現的,常見的例如Patroni+DCS,Pacemaker+Corosync,Repmgr,keepalived,pg_auto_failover,PGpool等等,其中使用較多的應該是Patroni和Repmgr兩種,下文針對PostgreSQ的兩種高可用方案Repmgr和Patroni進行部分場景對比。

一、Repmgr

1.Repmgr特點

Repmgr是2010年由2ndQuadrant推出的一款PostgreSQL故障切換工具,repmgr是一個開源工具套件,用於管理PostgreSQL伺服器叢集中的複製和故障轉移。它擴充套件了PostgresSQL內建的hot-standby能力,可以監控複製和執行管理任務。

image.png

(1)Repmgr命令管理 (replication manager)

Repmgr是一個命令列工具,日常操作主要透過Repmgr進行操作,功能包括叢集狀態檢視、switchover、克隆備庫、失效節點重新加入等。

用於執行管理任務的命令列工具,主要有以下方面作用:

  1. 設定備用伺服器
  2. 將備用伺服器升級為主伺服器
  3. 切換主伺服器和備用伺服器
  4. 顯示流複製狀態
  5. clone恢復備機資料
  6. 註冊節點

(2)Repmgrd守護程式 (replication manager daemon)

Repmgrd 是一個守護程式,支援故障檢測、failover,監控和記錄叢集資訊以及自定義指令碼接受叢集事件通知event_notification_command,它有一組預定義的事件,並將這些事件的每次發生都儲存在 repmgr.events 表中。Repmgr 允許將事件通知傳遞給使用者定義的程式或指令碼,該程式或指令碼可以採取進一步的行動,例如傳送電子郵件或觸發任何警報。

可以使用Repmgrd設定自動故障轉移。Repmgrd 需要在啟動 PostgreSQL 伺服器時載入共享庫“repmgr”。庫名稱應配置在 postgresql.conf 檔案的shared_preload_libraries裡。並且需要在 repmgr.conf 檔案中設定  failover=automatic 引數。一旦設定了所有這些引數,Repmgrd 守護程式就會開始主動監控叢集。如果主節點出現任何故障,它將嘗試多次重新連線。當所有連線到主節點的嘗試都失敗時,Repmgrd 將透過選舉選擇最符合條件的備用節點作為新的主節點。

它主動監視複製叢集中的伺服器並執行以下任務:

  1. 監控和記錄叢集複製效能
  2. 透過檢測主伺服器故障並提升最合適的備用伺服器來執行故障轉移
  3. 將有關群集中事件的通知提供給使用者定義的指令碼,該指令碼可以執行諸如透過電子郵件傳送警報等任務
  4. repmgrd 根據本地資料庫角色不同,其功能也不同:
    主庫:repmgrd僅監控本地資料庫,負責自動恢復、同非同步切換
    備庫:repmgrd監控本地資料庫和主資料庫,負責自動切換、複製槽刪除

(3)相關後設資料

repmgr.events:用來記錄repmgr管理的事件資訊
repmgr.nodes:複製群集中每個伺服器的連線和狀態資訊
repmgr.monitoring_history:repmgrd寫入的歷史備用監視資訊
repmgr.voting_term:【5.2新增】主要用來記錄投票資訊

檢視

repmgr.show_nodes:基於表repmgr.nodes,增加了顯示上游節點的資訊
repmgr.replication_status:啟用repmgrd的監視時,顯示每個備用資料庫的當前監視狀態。

Repmgr後設資料的schema可以儲存在現有的資料庫或在自己的專用資料庫,repmgr後設資料的schema不能駐留在不屬於Repmgr管理的複製叢集的資料庫伺服器上。

——
Repmgr本身不支援虛擬IP的功能 ,我們可以藉助keepalived來實現虛擬IP的功能。另外在配置檔案中,也可以設定promote_command為一個自定義指令碼

2.Repmgr如何仲裁哪臺備機升主

  • 每個備機檢查到主機資料庫故障後會進行重試,重試最後一次後,會去詢問其他備用資料庫。如果其它備用節點的最後一個複製的LSN或與主節點的最後一次通訊的時間比當前節點的最後一個複製的LSN或最後一次通訊的時間更近,則該節點不執行任何操作,並等待與主節點的通訊恢復。
  • 如果所有備機資料庫節點都看不到主庫,則它們將檢查witness見證節點是否可用。如果也無法到達witness見證節點,則備機會假定主伺服器端發生網路中斷,因此不會繼續選擇新的主伺服器。如果可以到達witness見證節點,則備機節點會假定主伺服器已關閉,然後繼續選擇主節點。之後將升級配置為“首選”主節點的節點。每個備機資料庫節點將重新初始化其複製,以跟隨新的主資料庫。

Repmgr怎麼選主:  當需要failover時,repmgr選舉候選備節點會以以下順序選舉: LSN > Priority > Node_ID。若LSN一樣,會根據priority優先順序進行比較,該優先順序是在配置檔案中進行引數配置,將priority設定為0會禁止參與選主。若優先順序也一樣,會比較節點的Node ID,小者會優先選舉

3.Repmgr如何處理腦裂場景(位置引數、witness見證節點)

(1)位置引數

Repmgr使用location位置引數處理腦裂場景,其中每個節點應根據其所在的資料中心指定位置引數。在任何網路分裂的情況下,Repmgr將確保與主節點位於同一位置的節點的提升。如果它在該位置找不到任何節點,它將不會提升任何位置的任何節點。

location='location1'                    # 定義location

除此之外可以使用witness見證伺服器的額外節點處理網路隔離,避免產生腦裂。

(2)見證節點

witness見證節點重要用來處理叢集主庫和備庫之間可能存在網路擁塞、延遲、路由等問題影響,導致主庫還在正常工作,而備庫無法聯絡主庫的場景。透過設定witness節點可以針對主庫與備庫之間切換的檢查完整性,即輔助備節點進行監控,避免因網路問題導致的腦裂現象。

見證節點主要的工作是幫助備庫達到法定的數量。它是一個僅考慮多數票數的節點。該伺服器上不需要安裝PostgreSQL,因此在複製中沒有任何作用。

當備機連不上主機了,就會連線witness見證節點,如果也連線不上見證節點,那判斷自己網路故障了,如果能連上見證節點,則認為主機故障,見證節點的作用類似於一個信任的閘道器。

witness必須配合Repmgrd。 Remgrd啟動後會作為常規服務執行並持續監視叢集的執行狀況。當達到與主機資料庫失去聯絡的法定人數時,它將啟動故障轉移。它不僅可以自動升級備用資料庫,還可以在多節點群集中重新啟動其他備用資料庫以跟隨新的主資料庫。

4.Repmgr優缺點

(1)repmgr 優點

  • Repmgr 提供了幫助設定主節點和備用節點以及配置複製的實用程式。
  • 不使用任何額外的埠進行通訊。如果想執行切換,那麼它才需要配置無密碼SSH。
  • 透過呼叫已註冊事件的使用者指令碼來提供通知。
  • 在主伺服器發生故障時可以執行自動故障轉移。
  • 對資料庫侵入小,維護起來和正常主備流複製基本一致。
  • 配置簡單。

(2)repmgr 缺點

  • repmgr 不會檢測備用庫是否在恢復配置中使用未知或不存在的節點錯誤配置。即使節點在未連線到主/級聯備用節點的情況下執行,節點也會顯示為備用節點。
  • 無法從 PostgreSQL 服務關閉的節點檢索另一個節點的狀態。因此,它不提供分散式控制解決方案。
  • 它不能在備機單個節點down掉時,自動把其拉起。

二、Patroni

1.Patroni特點

image.png
Patroni起源於 Compose 的一個專案Governor 的一個分支。它是一個用 Python 編寫的開源工具套件,用於管理 PostgreSQL 叢集的高可用性。 Patroni 沒有構建自己的一致性協議,而是利用了分散式配置儲存(DCS) 提供的一致性模型 ,如 Zookeeper、etcd、Consul 和 Kubernetes等。 下文主要以ETCD作為DCS舉例來說明

etcd可以進行心跳檢測(etcd 之間的心態檢測)、儲存並在各個節點上同步鍵值資訊。etcd最少需要三個節點且為奇數來進行 leader 選舉(腦裂發生時 etcd 叢集會僵死等待恢復,不會發生都認為自己是主的情況)。

Patroni透過一個api介面連線到etcd(或者其他DCS),向其插入鍵值對記錄patroni引數、資料庫引數、主備資訊以及連線資訊,平常透過etcd對其它節點做心跳檢測,透過從etcd獲取資料對中儲存的主備資訊來判斷各節點的狀態對叢集進行自動管理

Patroni 確保 PostgreSQL HA 叢集的端到端設定,包括流複製。它支援建立備用節點的各種方式,並且可以根據您的需要定製模板。 Patroni 藉助回撥可以支援事件通知,回撥是由某些操作觸發的指令碼。它使使用者能夠透過提供暫停/恢復功能來執行任何維護操作。watchdog支援功能使框架更加健壯。

2.DCS(分散式配置儲存) Zookeeper vs etcd vs Consul

Zookeeper

Zookeeper帶來的主要優勢是它的成熟度,健壯性和功能豐富性。 但是,它也有其自身的一系列缺點,其中Java和複雜性是主要原因。 Zookeeper對Java的使用以及相當數量的依賴關係使它比同等競爭產品消耗更多的資源。 除此之外,Zookeeper也很複雜。 維護成本比較高。 功能豐富性很高,但是很多複雜的功能可能不會使用到。

etcd

etcd是可透過HTTP訪問的鍵/值儲存。 它是分散式的,具有可用於構建服務發現的分層配置系統。 它非常易於部署,設定和使用,可提供可靠的資料永續性,安全性並具有非常好的文件。etcd的簡單性比Zookeeper更好。 但是,必須先將其與少量第三方工具結合使用,然後才能實現服務發現目標。

Consul

Consul是一個高度一致的資料儲存,它形成了一個動態叢集。 具有分層的鍵/值儲存,該鍵/值儲存不僅可以用於儲存資料,還可以註冊服務,這些服務可以用於各種任務,從傳送有關資料更改的通知到根據其輸出執行執行狀況檢查和自定義命令。與Zookeeper和etcd不同,Consul實現了嵌入式服務發現系統,因此無需構建自己的系統或使用第三方系統。 除其他事項外,該發現還包括對節點和在它們之上執行的服務的執行狀況檢查。

ZooKeeper和etcd僅提供原始的K/V儲存,並要求應用程式開發人員構建自己的系統來提供服務發現。 另一方面,Consul提供了用於服務發現的內建框架。 客戶端只需要註冊服務並使用DNS或HTTP介面執行發現。 其他兩個工具需要手工解決方案或使用第三方工具。 Consul為多個資料中心提供了開箱即用的本機支援,該系統不僅可以在同一叢集中的節點之間工作,而且還可以跨資料中心工作。

3.Patroni如何仲裁哪臺備機升主

Patroni監控本地的PostgreSQL狀態,並將相關資訊寫入etcd,每個Patroni都能讀寫etcd上的key,從而獲取外地PostgreSQL資料庫資訊。當etcd的leader節點不可用時,etcd會一致性的選擇一個合適的節點作為主節點,新的etcd主節點將獲取leader key。

etcd怎麼選主:假設etcd有三個節點,三個節點都去建立一個全域性的唯一key,誰先建立成功誰就是master主節點。其他節點持續待命繼續獲取,主節點繼續續租key值(key值會過期)。當持有key的節點down機時,或者key值過期被刪,其他節點建立key成功,則新master主節點產生,其他節點繼續這樣待命持續獲取key的狀態。

  • Patroni 自動建立主備流複製叢集透過 api 介面往 etcd 記錄鍵值來儲存主備資訊與連線
    資訊以及配置資訊,而Etcd 進行心跳檢測(etcd 之間的心態檢測)與儲存鍵值資訊
  • Patroni 透過連線 etcd 對其它節點做心跳檢測,每 loop_wait 秒一次
  • Patroni 透過連線到 etcd 叢集,向其插入鍵值記錄 patroni 引數、資料庫引數、主備資訊以及連線資訊。 透過向 etcd 拿取鍵值中儲存的主備資訊來判斷各節點的狀態來切換。各節點會在 data 目錄下生成 recovery.done(與 recovery.conf一樣,裡面的 primary_conninfo 記錄是上一次主節點的連線資訊),原主節點發生切換時自動改變字尾為 recovery.conf,原備節點會刪除掉自身的recovery.conf 檔案,再透過 pg_rewind 來快速恢復節點,不需要做bacebackup基礎備份。
  • 非同步流複製時主從之間延時:主從之間 wal 日誌延時超過
    maximum_lag_on_failover(byte)的大小,主備有可能會重啟但不會發生切換。
    資料丟失量透過 maximum_lag_on_failover,ttl,loop_wait 三個引數控制。
    最壞的情況下的丟失量:maximum_lag_on_failover 位元組+最後的 TTL 秒時間內寫入的日誌量(loop_wait /2 在平均情況下)。
  • haproxy+keeplived 保持對外的訪問 ip 埠不變

4.Patroni如何處理腦裂場景(watchdog)

正常停止Patroni時,Patroni會順便把本機的PG程式也停掉。然而,當Patroni程式自身沒法正常工作時,以上的保護措施難以成功。例如Patroni程式異常終止或主機臨時hang住等。
為了更可靠的防止腦裂,Patroni支援經過Linux的watchdog監視patroni程式的執行, 當Patroni程式沒法正常往watchdog裝置寫入心跳時,由watchdog觸發Linux重啟

使用watchdog防止出現腦裂,如果Leader節點異常導致Patroni程式無法及時更新watchdog,會在Leader key過期的前5秒觸發重啟。重啟如果在5秒之內完成,Leader節點有機會再次獲得Leader鎖,否則Leader key過期後,由備庫透過選舉選出新的Leader。

Patroni會在將PostgreSQL提升為master之前嘗試啟用watchdog。
如果看atchdog啟用失敗並且watchdog模式是required那麼節點將拒絕成為主節點。
在決定參加leader選舉時,Patroni還將檢查watchdog配置是否允許它成為領導者。

在將PostgreSQL降級後(例如由於手動故障轉移),Patroni將再次禁用watchdog。當 Patroni處於暫停狀態時,watchdog也將被禁用。正常停止Patroni服務,也會將watchdog禁用。

5.Patroni優缺點

(1)Patroni優點

  • Patroni 支援叢集的端到端設定。
  • 支援 REST API 和 HAproxy 整合。
  • 透過某些操作觸發的回撥指令碼支援事件通知。
  • 利用 DCS 選取主節點。
  • 支援自動failover和按需switchover
  • 支援同步複製下備庫故障時自動降級為非同步複製(功效相似於MySQL的半同步,可是更加智慧)
  • 支援控制指定節點是否參與選主,是否參與負載均衡以及是否能夠成為同步備機
  • 支援經過pg_rewind自動修復舊主。
  • 支援多種方式初始化叢集和重建備機,包括pg_basebackup和支援pgBackRest,barman等備份工具的自定義指令碼
  • 支援自定義外部callback指令碼
  • 支援REST API
  • 支援經過watchdog防止腦裂
  • 支援k8s,docker等容器化環境部署
  • 支援多種常見DCS儲存後設資料,包括etcd,ZooKeeper,Consul,Kubernetes等

除此之外,Patroni在目前支援的   邏輯複製槽的自動failover 這一功能,在PostgreSQL的高可用方案裡,是比較方便且獨樹一幟的。所以,如果可用伺服器在至少3臺或者有邏輯複製需求的時候,Patroni是一款很值得推薦的PostgreSQL高可用工具,但是這個最少節點的限制也是其中一個缺點。

(2)Patroni缺點

  • Patroni 不會檢測到在恢復配置中具有未知或不存在節點的備用的錯誤配置。即使備節點在未連線到主/級聯備用節點的情況下執行,該節點也將顯示為從節點。
  • 使用者需要處理 DCS 軟體的設定、管理和升級。和原本運維主備流複製環境差異較大。對資料庫的侵入較大。
  • 需要為元件通訊開啟多個埠:
    • Patroni 的 REST API 埠
    • DCS 最少 2 個埠

三、Patroni和Repmgr相關場景對比

1.備機測試

場景 Repmgr Patroni
kill PostgreSQL 程式 需要手動干預才能再次啟動PostgreSQL 程式。 Patroni 使 PostgreSQL 程式回到執行狀態。
正常停止 PostgreSQL 程式 需要手動干預才能再次啟動PostgreSQL 程式。 Patroni 使 PostgreSQL 程式回到執行狀態。
重啟伺服器 需要手動啟動PostgreSQL,並將伺服器標記為正在執行。 Patroni會在在重啟及伺服器後啟動,除非配置為在重新啟動時不啟動。一旦 Patroni 啟動,它就會啟動 PostgreSQL 程式並設定備機配置。
正常停止repmgrd或Patroni 備機的不會成為自動故障轉移的一個節點,(備機狀態無變化) Patroni會停止備機PostgreSQL程式

2.主機測試

場景 Repmgr Patroni
kill PostgreSQL 程式 Repmgrd在固定的時間間隔內,所有備機都會對主節點連線進行健康檢查。當所有重試都失敗時,在所有備機上觸發選舉。作為選舉的結果,具有最新收到的 LSN 的備用被提升。失去選舉的備用伺服器將等待來自新主節點的通知,並在收到通知後跟隨它。原主節點需要手動干預才能再次啟動 postgreSQL 程式。 Patroni 使 PostgreSQL 程式回到執行狀態。在該節點上執行的 Patroni 具有主鎖,因此沒有觸發選舉。
正常停止 PostgreSQL程式並在健康檢查到期前立即將其恢復 Repmgrd在固定的時間間隔內,所有備機都會對主節點連線進行健康檢查。當所有重試都失敗時,在所有備機上觸發選舉。然而,新當選的主節點沒有通知現有的備機,因為舊的主節點回來了。群集處於不確定狀態,需要人工干預。 Patroni 使 PostgreSQL 程式回到執行狀態。在該節點上執行的 Patroni 具有主鎖,因此沒有觸發選舉。
重啟伺服器 當所有備機上與主的連線健康檢查失敗時,remgrd 開始選舉。符合條件的備機被提升為新主。當原主回來時,它沒有加入叢集並被標記為失敗。需要執行 repmgr node rejoin 命令將伺服器新增回叢集。 發生故障轉移,其中一臺備機在獲得鎖後被選為新的主節點。當Patroni在舊主機點上啟動時,它會拉起原主的PostgreSQL程式並執行pg_rewind,並、且開始跟隨新主節點。
正常停止repmgrd或Patroni 主節點不會成為自動故障轉移的一部分。PostgreSQL 服務正常執行。啟動Repmgrd,PostgreSQL程式不自動拉起。 Patroni所在的其中一臺備機獲得了 DCS 鎖並提升自身成為主庫。舊主的PostgreSQL被Patroni關掉,一旦在舊主機上啟動了 Patroni,它會將舊主的時間線和 lsn(use_pg_rewind設定為 true)調整到與新主一致並開始跟隨新主。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69990629/viewspace-2910063/,如需轉載,請註明出處,否則將追究法律責任。

相關文章