李雁明,劉相坤,段應杰,王凱旋
(中國鐵道科學研究院集團有限公司 電子計算技術研究所,北京 100081)
隨著云計算和大數據技術的廣泛應用,企業信息系統集中化部署成為主流趨勢。為保障企業信息系統安全高效運營,滿足不同故障和災難場景下對業務連續性的要求,為企業提供更加安全、穩定、高效的信息化平臺,兩地三中心已成為企業數據中心建設的共識。數據庫作為信息系統的重要組成部分,需要解決高并發、海量數據訪問、持續提供服務、數據安全等越來越復雜的問題[1],高可用數據庫設計與實現是兩地三中心建設的一項關鍵任務[2]。
高可用是信息系統提供連續性業務服務的一種能力。高可用數據庫架構設計需要綜合考慮如何避免因服務器、網絡及軟件等發生故障而造成業務服務不可用。實現兩地三中心數據庫的高可用有多種途徑,各大廠商紛紛提出各自的數據庫高可用解決方案。以TiDB為代表的云原生分布式數據庫解決方案,基于分布式一致性算法,保障了集群數據的一致性和高可用,但對數據中心之間的網絡延時有較高要求;以Oracle為代表的集中式數據庫解決方案,通過數據同步軟件實現數據在多個數據中心之間的實時邏輯復制,但在主數據庫發生故障時可能存在數據丟失情況。
本文借鑒商用數據庫高可用解決方案和國內外相關研究,設計一種基于開源關系型數據庫管理系統PostgreSQL和開源分布式協調服務ZooKeeper的兩地三中心數據庫高可用架構,并進行了驗證測試。
兩地三中心通常由同城的2個數據中心(即同城一中心和同城二中心)和1個異地的災備中心構成。
兩地三中心數據庫劃分為3個層次:為業務提供服務的數據訪問接入層、負責數據存儲的數據存儲層、實現數據庫高可用保障的數據高可用層,其架構如圖1所示。

圖1 兩地三中心數據庫架構示意
Patroni是PostgreSQL的一個開源HA工具,用于檢測各個數據庫節點的狀態和配置,并負責數據庫的故障切換。Zookeeper是一個開源的分布式協調服務,用于管理數據庫集群,負責存儲數據庫節點的狀態和配置。
數據訪問接入層是面向應用的數據訪問接口,根據應用需求提供數據庫讀/寫服務。
數據訪問接入層主要由負載均衡器組成,其工作過程如圖2所示。

圖2 數據訪問接入層工作過程示意
負載均衡器通過Patroni的接口獲取數據庫的狀態信息,確定可提供數據讀寫服務的數據庫主庫和僅提供數據讀服務的數據庫備庫[3]。同城中心的3個備庫與主庫始終保持同步更新,存儲的數據完全一致;而災備中心備庫以異步方式更新數據,存儲的數據相比主庫有一定延遲。正常情況下,負載均衡器不對災備中心的異步備庫進行探測,僅從數據完全一致的同城中心選擇同步備庫對外提供服務。
負載均衡器實時對同城中心數據庫節點進行探測,可獲4個數據庫節點的主備狀態。當數據庫主備庫發生切換時,負載均衡器快速進行流量切換,將業務流量切換至正確的數據庫,屏蔽數據庫切換對上層業務的影響,為上層業務提供持續穩定的數據訪問服務。
數據存儲層作為數據存儲的載體,采用基于PostgreSQL數據庫的5節點數據副本模式,即兩個同城數據中心各部署2個數據庫節點,災備中心部署1個數據庫節點,每個數據庫節點部署1個具有全部數據的數據副本[4]。數據庫的主庫由兩個同城中心通過選舉產生,主庫對外提供數據讀寫服務,備庫僅提供數據讀服務。異地災備中心主要用于數據異地備份,正常情況下不會被選舉為主庫。數據庫的主庫到同城的3個備庫采用同步復制模式,確保一個同城中心整體發生故障時,另一個同城中心仍具有全部業務數據,且故障恢復后不丟失數據(即RPO為0)。同時,當備庫發生故障時,主備庫間的同步復制自動降級為異步復制[5]。為了降低數據復制對數據庫系統的性能影響,主庫到災備中心的備庫采用異步復制模式。
為了保障業務服務的連續穩定和數據同步的安全高效,數據存儲層將南北向流量(即數據中心外部用戶和內部服務器之間交互的流量)和東西向流量(即數據中心內部不同服務器之間交互的流量或不同數據中心之間的網絡流量)進行邏輯隔離,南北向的業務流量采用業務網,東西向的數據同步流量采用數據同步網。
數據庫高可用層采用Patroni+集群狀態信息配置存儲服務(DCS,Distributed Configuration System)的組合模式。Patroni運行在每個數據庫節點上,通過探測數據庫節點及數據副本的狀態來進行數據庫主備切換。DCS負責存儲數據庫節點的狀態信息,為Patroni的數據庫主備切換決策提供依據,采用基于ZooKeeper的分布式數據一致性解決方案。ZooKeeper采用與數據存儲層相同的5節點集群部署模式,分別部署在數據副本駐留的數據庫節點上,通過ZooKeeper原子廣播(ZAB,ZooKeeper Atomic Broadcast)協議來保障服務高可用。
在兩地三中心數據庫集群上實現分布式事務一致性是實現數據庫高可用的基礎。基于ZooKeeper的分布式事務一致性解決方案采用多副本方式,天然適用于兩地三中心架構。ZooKeeper能夠保障事務請求的順序一致性、原子性、單一視圖性、可靠性及實時性。
(1)順序一致性:同一個客戶端發起的事務請求將按照發送的順序被寫入到ZooKeeper。
(2)原子性:所有事務請求的處理結果在整個集群中所有節點上的執行情況完全一致,即整個集群所有節點都成功地執行了某一個事務,或都不執行。
(3)單一視圖性:客戶端連接到任一ZooKeeper服務器,看到的服務端數據模型都是一致的。
(4)可靠性:一旦服務端成功地執行一個事務,并完成對客戶端的響應,該事務所引起的服務端狀態變更會被一直保留下來。
(5)實時性:ZooKeeper可確保在一定時間段內,客戶端能夠從服務端讀取到最新數據狀態[6]。
ZooKeeper使用ZAB協議。ZAB協議是為分布式協調服務ZooKeeper設計的一種支持崩潰恢復的原子廣播協議,基于該協議ZooKeeper可實現多個副本間數據一致性。ZooKeeper定義有3種角色的節點:Leader、Follower和Candidate。在選舉過程中,一個節點只要求獲得半數以上投票,即可當選為Leader。Leader節點負責處理客戶端的寫請求并進行消息廣播,當收到一個寫請求后,將其廣播給各個Follower節點,當一半以上Follower節點應答之后,Leader節點再向各Follower節點發送Commit命令,告知其提交相關事務[7]。Candidate 僅出現在 Leader選舉過程中,如果 Follower副本在一段時間內沒有收到 Leader 副本的心跳,則判斷 Leader 可能已經故障,此時啟動選主過程,副本會變成 Candidate,直到選主結束。一旦Leader節點出現網絡中斷、崩潰、退出與重啟等異常情況時,ZAB協議就會進入恢復模式,并通過選舉產生新的Leader。采取這種工作機制,ZooKeeper集群中只要有超一半的節點存活,集群就可對外提供服務。
兩地三中心ZooKeeper集群部署如圖3所示。Patroni通過Leader節點將數據直接寫入ZooKeeper集群,也可通過Follower節點將數據傳遞至Leader節點,再由Leader節點寫入ZooKeeper集群,通過Leader或Follower讀取ZooKeeper集群中的數據。

圖3 ZooKeeper集群部署示意
數據庫高可用是由ZooKeeper和Patroni共同保障的,其工作機制如圖4所示。ZooKeeper集群負責數據庫主備節點狀態及配置等信息的存儲。Patroni負責監控和控制本地數據庫,周期性地檢測本地數據庫節點狀態,將數據庫節點狀態記錄在ZooKeeper集群中,同時讀取最新的配置信息和集群狀態,當發現主數據庫故障后自動進行主備切換[8]。

圖4 數據庫高可用工作機制
擁有Leader密鑰的數據庫作為主數據庫,主數據庫的Patroni會定期向ZooKeeper發送更新Leader密鑰的請求[9];當主數據庫異常導致Patroni無法及時更新Leader密鑰時,Leader密鑰就會過期,從而觸發新的選舉。數據庫主備切換流程為:
(1)主數據庫發生故障,導致Leader密鑰被刪除,處于健康且存活狀態的所有備數據庫會發起對Leader密鑰的爭奪。Patroni之間可互相訪問,先與原來的主數據庫進行通信,當發現訪問超時,則訪問ZooKeeper查詢數據庫集群狀態,向滿足選舉條件的Patroni發送創建密鑰的請求,搶到Leader密鑰的數據庫成為新的主數據庫
搭建兩地三中心數據庫的測試環境需要綜合考慮數據中心位置、網絡條件、計算及數據存儲等多方面因素。
(1)數據中心位置:本文測試環境選擇的兩個同城數據中心相距約10 km,兩個同城數據中心到災備中心的距離均超過100 km。
(2)網絡連接:數據中心內部均采用萬兆網絡互聯,兩個同城數據中心之間采用千兆網絡專線互聯,保障兩個同城中心之間具有較大的帶寬和較小的網絡延遲,以滿足兩個同城中心的主庫和備庫間的同步數據復制需求。同城數據中心與災備中心采用千兆網絡互聯,在實際生產中采用此方式可降低經濟成本。同時,為業務網和數據同步網配置獨立且相互隔離的網絡地址段。數據中心內部及兩個同城中心間網絡延遲在2 ms以內,同城中心到災備中心網絡延遲在8 ms以內。
(3)計算及數據存儲:采用物理服務器+本地盤存儲的數據庫部署模式[10],而不是傳統物理服務器+集中存儲的數據庫部署模式。傳統的數據庫部署模式采用集中存儲主要是為了提高數據讀寫性能,并利用集中存儲硬件的冗余保護來保障數據存儲的安全性。而兩地三中心數據庫采用本地SSD盤存儲數據,既可滿足數據庫的讀寫性能要求,采用多副本存儲還能夠提高數據的安全性。數據庫采用物理服務器+本地盤存儲的部署模式,可降低復雜度,并有助于降低建設成本及后期運維成本[11]。
為了模擬較為復雜的生產場景,將主數據庫置于一個同城數據中心(同城一中心),ZooKeeper Leader置于另一個同城數據中心(同城二中心)。
深化課程考試體系改革,實現考核方式向多樣化轉變,考核內容向注重綜合能力考核轉變,成績評定由終結性評價向形成性評價轉變。取消原有的“一考定成績”,推行形成性評價方案(見圖4),提升評價的科學性和客觀性。將學生的線上學習情況、課堂參與情況、解決問題能力、計算思維能力等納入學習評價體系,更科學、客觀地衡量學生學習效果。在教學過程中,通過線上、線下的數據分析,把握學生整個學習過程,并及時反饋評價結果,使學生通過評價結果了解自己的不足,進行及時、有效的改正。
生產環境中常見的故障有服務器硬件故障、數據庫故障、業務網故障、數據同步網故障及極端情況下的整個數據中心故障[12]。根據生產環境中常見的故障,設計了12種故障場景測試用例:
(1)兩個同城中心間業務網異常;
(2)兩個同城中心間數據同步網異常;
(3)同城二中心與同城一中心、災備中心間數據同步網均異常;
(4)同城一中心與同城二中心、災備中心間數據同步網均異常;
(5)災備中心與同城一中心、同城二中心間數據同步網均異常常;
(6)三個中心數據同步網全部異常;
(7)同城一中心整體故障;
(8)同城二中心整體故障;
(9)災備中心整體故障;
(10)同城一中心與同城二中心整體故障;
(11)同城一中心與災備中心整體故障;
(12)同城二中心與災備中心整體故障。
(1)兩個同城中心間業務網異常
數據同步網正常,ZooKeeper集群正常,數據庫集群正常。同城二中心數據訪問接入層因無法連接到主庫,僅能提供讀服務,無法提供寫服務,而同城一中心可正常提供服務。
(2)兩個同城中心間數據同步網異常
同城一中心ZooKeeper無法連接到ZooKeeper Leader,故脫離集群。ZooKeeper集群仍有3個節點正常運行,故集群仍可正常提供服務。同城一中心的主庫可訪問災備中心ZooKeeper,故主庫正常。同城二中心所有數據節點無法連接到同城一中心主數據節點,致使同城二中心的同步備庫降級為異步備庫,但并未脫離集群,在降級過程中,數據庫短暫停止服務,業務閃斷后恢復正常。
(3)同城二中心與同城一中心、災備中心間數據同步網均異常
同城二中心ZooKeeper無法連接到同城一中心和災備中心的ZooKeeper,成為少數派脫離集群,ZooKeeper Leader重新在同城一中心和災備中心選舉產生,重新選舉Leader對業務無影響。同城二中心所有數據庫無法連接到新的ZooKeeper集群,致使同城二中心數據庫脫離集群,同時同城一中心主庫到同城二中心備庫的同步復制降級為異步復制,在降級過程中,數據庫短暫停止服務,業務閃斷后自動恢復正常。
(4)同城一中心與同城二中心、災備中心間數據同步網均異常
同城一中心ZooKeeper無法連接到同城二中心和災備中心的ZooKeeper,成為少數派脫離集群,此時ZooKeeper變為3節點集群,Leader無需切換,可正常提供服務。同城一中心主備庫均無法連接到ZooKeeper集群,致使同城一中心數據庫脫離集群,此時同城二中心的一個同步備庫升級為主庫,在主備切換的過程中,數據庫短暫停止服務,業務閃斷后自動恢復正常。
(5)災備中心與同城一中心、二中心間數據同步網均異常
災備中心ZooKeeper無法連接到同城一中心和二中心的ZooKeeper,成為少數派脫離集群,此時ZooKeeper變為4節點集群,Leader無需切換,可正常提供服務。災備中心數據庫均無法連接到ZooKeeper集群,致使災備中心數據庫脫離集群。業務網正常,同城一、二中心數據訪問接入層均可正常提供讀寫服務,業務不會受到影響。
(6)三個中心數據同步網全部異常
當三個中心數據同步網全部異常,ZooKeeper集群無法正常運行,此時數據庫集群無法正常運行,需要人工干預,將某一數據庫提升為主庫。
(7)同城一中心整體故障
同城一中心ZooKeeper脫離集群,此時ZooKeeper變為3節點集群,Leader無需切換,可正常提供服務。同城一中心數據庫脫離集群,同城二中心一個同步備庫升級為主庫,當發生主備切換時,數據庫短暫停止服務,業務閃斷后自動恢復正常。
(8)同城二中心整體故障
同城二中心Zookeeper脫離集群,ZooKeeper Leader重新在一中心和災備中心選舉產生,Leader的重新選舉對業務無影響。同城二中心數據庫脫離集群,同城一中心數據庫正常,無需切換主備庫,但同城一中心主庫到二中心備庫的同步復制降級為異步復制,在降級過程中,數據庫短暫停止服務,業務閃斷后自動恢復正常。
(9)災備中心整體故障
ZooKeeper 集群仍有 4 個節點正常運行,故集群仍可正常提供服務,兩個同城數據庫節點均正常,業務不會受到影響。
(10)同城一中心與同城二中心整體故障
ZooKeeper 集群無法正常工作,此時數據庫集群無法正常運行,需要人工干預,將災備中心數據庫節點提升為主庫。
(11)同城一中心與災備中心整體故障
ZooKeeper 集群剩余節點不超過總節點數的50%,此時數據庫集群無法正常運行,需要人工干預,將同城二中心一個數據庫節點提升為主庫。
(12)同城二中心與災備中心整體故障
ZooKeeper 集群剩余節點不足一半總節點數,此時數據庫集群無法正常運行,需要人工干預,將同城一中心一個數據庫節點提升為主庫。
通過對本文提出的兩地三中心數據庫的測試與分析,可得到以下結論:
(1)當兩個同城中心間發生網絡故障時,無論是業務網或數據同步網故障,業務幾乎不會受到影響,系統服務恢復時間(RTO,Recovery Time Objective)約為0,恢復點目標(RPO,Recovery Point Objective)為0。但業務網故障時,僅有一個同城中心的數據訪問接入層可提供服務。
(2)當任一同城數據中心數據同步網或整體發生故障時,業務幾乎不會受到影響,RTO 約為 0,RPO 為 0;當災備中心數據同步網或整體發生故障時,業務不會受到影響,RTO為 0,RPO 為 0。
(3)當兩個同城數據中心同時發生故障或數據同步網整體發生故障時,由于 ZooKeeper 集群無法正常工作,此時業務會受到影響,需要人工干預來恢復業務。
本文提出一種用于兩地三中心的高可用數據庫架構,能夠實現分布式事務一致性及故障場景下數據庫高可用;并結合實際生產過程中可能出現的故障,設計了12種故障場景測試用例進行驗證。結果表明,按照該架構部署兩地三中心數據庫,除了兩個同城數據中心同時發生故障或者數據同步網整體發生故障的情況外,其它故障發生時,數據庫均可自動進行故障隔離,且數據零丟失,能夠持續穩定地提供數據訪問服務,不會影響到業務。該數據庫架構使用了開源的關系型數據庫管理系統PostgreSQL和開源的分布式協調服務ZooKeeper,不但節約軟件成本,透明可靠、安全性高,還可針對實際需要進行定制。此外,數據存儲介質使用的是服務器本地盤而非集中存儲,有利于降低數據庫建設成本和運維成本。
本文提出的兩地三中心高可用數據庫架構中,ZooKeeper集群對網絡傳輸的穩定性具有一定的要求,數據中心間的網絡抖動會對數據庫的高可用產生一定的影響,下一步將繼續優化數據庫集群的網絡設計,降低網絡對數據庫高可用性的影響。