一文了解數據庫高可用容災方案的設計與實現 原

一個系統可能包含很多模塊,如數據庫、前端、緩存、搜索、消息隊列等,每個模塊都需要做到高可用,才能保證整個系統的高可用。對於數據庫服務而言,高可用的實現可能更加複雜,對用戶的服務可用,不僅僅是能訪問,還需要有正確性保證,因此討論數據庫的高可用方案時,在容災之外,還要同時考慮方案中數據一致性問題。

本文將通過介紹一些業界主流的數據庫高可用架構、每種方案的特性和優缺點,以及數據庫高可用架構的自動化運維實現,講講數據庫高可用容災方案設計與實現,希望拋磚引玉,和大家一起討論。

一、高可用數據庫概述

什麼是高可用數據庫?

高可用數據庫是由一系列數據庫構成的總體系統,在任何時刻,至少有一個節點可以接受用戶的請求並提供數據庫服務。大多數數據庫架構中,有一個主節點處理主要請求,還有若干備用節點用於容災切換,當主節點不能提供服務時,備用節點成爲主節點繼續提供服務,用以保證整個系統的可用和穩定。

高可用數據庫有很多優點:

第一,方便讀寫分離。數據庫請求當中,一般讀操作的請求次數遠大於寫操作,高可用數據庫可以通過將寫操作放在主數據庫節點上進行,將讀操作分擔到若干從庫上,來提升讀操作吞吐量,進而提升讀寫效率; 第二,變更不停服。當整個高可用數據庫架構或者主節點升級時,可以讓高可用數據庫先進行主庫切換,讓備用節點替換原主節點提供數據庫服務,當主節點升級完畢後,再將主從庫服務切換回來,這樣能有效避免系統升級或變更時對用戶服務質量產生影響; 第三,備份不影響服務性能。高可用數據庫架構包含多個從庫,在不影響主節點服務性能的情況下,能非常方便地實現數據的容災備份。

一般,高可用數據庫地架構設計時,也需要考慮三個問題:

第一,如何同步各數據庫之間的節點數據?同步需要保證切換後的數據庫是最新數據,以及在切換過程中數據不會丟失,同時還要考慮同步過程對主庫和備庫的影響。 第二,高可用數據庫的容災切換如何進行?架構不同容災切換的複雜度也不一樣,且切換以後需要保證主、從庫數據的一致性,這可能需要開發者在設計之初就儘量優化和簡化容災切換邏輯。 第三,如何提高高可用的運維效率?

二、業界典型高可用數據庫架構

按照數據同步方式,我們可以將業界主流的高可用架構劃分成四種:第一種,共享存儲方案;第二種,操作系統實時數據塊複製;第三種,數據庫級別的主從複製;第四種,高可用數據庫集羣。每一種數據同步方式可以衍生出不同的架構。

方案一:共享存儲

共享存儲指若干DB服務使用同一份存儲,一個爲主DB,其他的爲備用DB,若主服務崩潰,則系統啓動備用DB,成爲新的主DB,繼續提供服務。一般共享存儲採用比較多的是SAN/NAS方案。

這種方案的優點是沒有數據同步的問題,但也有一些限制,如對於共享存儲的實時性和網絡性能有較高要求。因爲共享存儲一般是通過網絡來訪問存儲當中的數據,在網絡性能較差的情況下,數據庫的性能也無法達到令人滿意的效果。不過,隨着硬件性能的不斷提升,將計算存儲分離、和DB深度結合的共享存儲亦是高可用數據庫未來發展的趨勢之一。

方案二:操作系統實時數據塊複製

這個方案的典型場景是DRBD,可以把它理解爲遠程的RAID1,如下圖所示,左側數據庫寫入數據以後立即同步到右側的存儲設備當中。如果左邊數據庫崩潰,系統可以直接激活右邊的數據庫存儲設備,啓動新的數據庫服務,實現容災切換。

這個方案同樣有一些問題,如系統只能有一個數據副本提供服務,無法實現讀寫分離;另外,如果系統崩潰,主庫進程中斷,容災切換後需要在掛掉的數據庫上做數據庫崩潰恢復,系統需要的容災恢復時間較長。

方案三:數據庫主從複製

這種方案我認爲是最經典的數據同步模式,系統採用一個主庫和多個從庫方式,其實現原理主要是基於日誌的主從複製,主庫操作以日誌的形式發送給各個從庫,從庫接收到日誌後進行數據備份。這種方式的好處是一個主庫可以連接多個從庫,能很方便地實現讀寫分離,同時,因爲每個備庫都在運行中,所以備庫裏面的數據基本上都是熱數據,容災切換也非常快。

不過,這個方案也並非完美無缺,如容災切換時,從庫一定要同步完最新數據以後才能升級爲主庫,否則極有可能發生數據丟失的情況。針對傳統主從架構的一些問題,業界也逐漸研發出對應的改進技術。

改進技術一:雙主架構

問題:經典主從架構裏面,原主庫崩潰恢復的過程中,新的數據無法及時同步到該數據庫當中,原主庫恢復後,需要重新設置爲從庫,並將容災過程中的數據重新同步進行。

改進措施:爲了保證容災後的數據一致性,業界對這種架構做了一些改進,其中一種改進措施就叫雙主架構,如下圖所示,雙主架構一般會選擇兩個DB做一對主庫,這兩個DB之間互相爲對方的從庫,無論往哪個DB寫入數據,另一個都會自動同步。容災時系統只需要把流量從左邊切換到右邊,容災後數據同步依舊自動進行,這樣,就保證了容災後原主庫的數據一致性。

改進技術二:日誌自動尋址

問題:容災備份時,當某一從庫提升爲主庫後,其他備庫需要自動定位新主庫的日誌同步點,同步新主庫的日誌。早期數據庫日誌中,MySQL是通過文件名加上文件的偏移量進行尋址,因此,主庫的自動定位並不好實現。

改進措施:爲了解決此問題,MySQL提供了一種叫做GTID的全局事務標誌技術,一個事務對應一個ID,所有的日誌都帶有唯一的標識符,主從庫切換後,其餘從庫只要根據新主庫的日誌ID,就可以辨別新的日誌同步點,然後根據這個日誌同步數據,這對於搭建一主庫多從庫的架構來說尋址非常便捷。

改進技術三:異步複製改進

問題:默認情況下,MySQL的複製是異步的,主庫將新生成的日誌發送給各從庫後,無需等待從庫的ack回覆(從庫將接收到的日誌寫進relay log後,纔會回覆ack),直接就認爲這次DDL/DML成功了。但在極端情況下,如主庫剛提交日誌,其他從庫還沒有接收到相關日誌時,數據庫發生故障,此時,該日誌的內容就會全部丟失。

改進措施:半同步複製機制。半同步複製是指主庫在將新生成的日誌發送給各從庫前,需發送日誌到一個(默認)從庫,等待從庫返回ack信息後,主庫再提交日誌發送給各從庫,這就防止了上述情況下的數據丟失。半同步複製是一種提升數據一致性的有效方式,也是比較關鍵的技術。

方案四:數據庫高可用集羣

前面三種方案主要是通過日誌的複製模式實現高可用,第四種方案則是基於一致性算法來做數據的同步,數據庫提供多節點一致性同步機制,利用該機制構建多節點同步集羣。這種方式比較經典的案例包括MGR(MySQL Group Replication)和Galera等,最近業內也有一些類似的嘗試,如使用一致性協議算法,自研高可用數據庫的架構等。

以上示意圖有五個節點,他們之間是構建成了一個一致性的同步集羣,客戶端可以讀寫其中的任何一個節點,任意一節點寫入,其他節點都能夠將數據進行同步,因此,理論上每個節點都可以進行讀寫操作。這種方式的容災實現也比較簡單,假設第二個節點出現故障,系統只需要斷開客戶端對第二個節點的訪問路徑,其他節點照常訪問就可以了,這也是業界近年來比較流行的高可用集羣方案。

UCloud高可用數據庫解決方案UDB

UCloud對比了業內的各解決方案的優劣點,綜合了原生MySQL兼容,不同版本、不同應用場景的覆蓋等多種因素,最終選擇採用基於數據庫主從複製的方式實現高可用架構,並在原架構基礎上,使用雙主架構、半同步複製、採用GTID等措施進行了系列優化,保證數據一致性的同時,實現日誌的自動尋址。

如上圖所示,最底層爲數據層,使用了雙主架構,主庫與備主庫之間通過半同步的方式實現數據同步,整個數據層是雙主架構+半同步架構的模式。中間層有一個代理服務器Proxy,Proxy將流量導入到雙主數據庫的主節點,架構使用了GTID的模式,方便從庫自動尋址。

系統的容災切換也非常簡單,數據庫崩潰前,Proxy將流量導到主DB上,發生容災以後,只需要把Proxy從左邊Master導到右邊的Slave,即可快速完成切換。

三、高可用數據庫的自動化運維

自動化運維的重點方向

自動化運維是高可用數據庫中的難點,因爲企業業務不一定只有一個數據庫,可能需要同時管理十幾個甚至上百個數據庫,如果每一個數據庫都配置一個高可用數據庫架構,系統則需要保證其中任何一個發生問題以後都可以進行容災,這無疑給運維帶來了極大挑戰。

那麼,如何同時管理大量高可用數據庫,讓他們都可以進行容災呢?這裏有一些自動化運維方向的思路:1、容災切換自動化;2、高可用數據庫運行狀況監控;3、健康狀況自動檢查和問題修復。

1、容災切換自動化。要實現容災切換的自動化,首先需要考慮兩個問題:

第一,怎樣準確判斷需要容災。這是實現自動容災的基礎和前提,它需要結合實際情況討論和判斷。如發生網絡波動時,可能有一段時間發現無法連上主庫,實際上幾秒鐘以後整個業務系統又恢復了,如果這時候數據庫做容災的話代價比較大,且容災後還可能會有額外的風險。所以需要在前期準確判斷是否需要容災,並保證在最需要容災的時候及時容災; 第二,容災切換時,備庫數據儘量和主庫數據保持一致,否則,就會帶來數據丟失的問題。

針對上述問題,MySQL已經有比較常用方案供參考,老牌的如MHA,還有一種比較新的方案叫Orchestrator,如果大家自己搭建數據庫,可以考慮採用這兩種方案。

2、健康狀況自動檢查。健康狀況檢查需要通過自動監控搭配告警來做,高可用容災中,最關心的還是高可用數據庫的主庫和備庫數據是否一致,一般情況,導致主從庫數據不一致的主要是兩點:

第一,複製有沒有正常進行,如發送日誌時主庫與備庫之間的連接突然斷掉,這時候需要系統時常掃描主備庫是否異常; 第二,主從延時,如果主從之間的數據延遲較大,那麼切換數據庫時也會比較麻煩,這方面也可以考慮使用業內比較常用的監控模塊如Prometheus等工具定期採集,發現異常狀況後及時調整。

第三,異常情況自適應調整。以主從延遲爲例,一般來說可能是CPU的問題或者IO的問題等,如果是IO的問題,一種辦法是將IO調高,這是一種比較好的解決方案,如果IO調高以後發現還是無法降低延時,可以在從庫把日誌的持久化等級暫時性調低。當然,如果主從之間延遲過大,完全無法調整爲正常水平,這時候就要考慮通過一些手段重做從庫。

UDB:海量高可用數據庫自動化運維

UDB擁有海量的高可用數據庫,在自動化運維和管理方面,UDB採用的是高可用容災集中式自動化管理的方式,通過自研的自動容災邏輯,進行大規模、高併發的DB自動化容災。同時,UDB的運維體系還可以做到自動化的問題探測以及問題修復,如自動拉起DB、恢復服務,自動恢復數據同步,自適應流量控制等。此外,UDB還會配合一些高效運維工具和巡檢工具做更深層次的問題的發現和解決。

在UDB高可用運維當中,有幾點經驗可以跟大家分享:

第一,日常需要做例行巡檢,保證高可用數據庫的健康。主從延時是導致高可用數據庫無法容災的關鍵原因之一,這一點一定要在日常運維工作中重視起來; 第二,定期容災演練很有必要。容災演練就是在平臺上跑自己的容災邏輯,我們需要在不同場景下做切換,看數據有沒有丟失、是否保持了數據的一致性等等,因爲線上環境非常複雜,可能會有各種莫名其妙的問題導致切換邏輯在發生切換以後結果不一致,所以要通過定期演練把各種可能性降到最低; 第三,高可用切換需要記錄日誌,並且在切換失敗的時候馬上告警。切換日誌可以做事後覆盤分析,看這個DB是什麼時候崩潰做的容災。進入告警後可以保證第一時間介入並解決,縮短整個DB崩潰對用戶的影響時間。

四、總結

高可用架構是數據庫運行穩定必不可少的一部分,設計架構時要考慮諸多問題,如數據是否同步、高可用自動切換、自動化運維等等。前面講解了四種基於數據庫同步的數據庫高可用架構,如果是在雲環境下,推薦使用UDB雲數據庫這樣的產品一鍵完成上述配置,幫助減輕業務的運維壓力。

作者介紹

丁順,UCloud資深存儲研發工程師,在雲產品、大規模海量存儲方面具有豐富的經驗,擅長於分佈式系統、面向服務、容器化、高可用等方面的架構和軟件設計。

想要獲取更多技術和活動資訊,可微信關注“UCloud技術公告牌”公衆號;或搜索微信ID:ucloud_tech進行關注。 您也可以添加運營小妹微信:Likekids,歡迎交流諮詢更多技術問題!9大技術交流羣,等你加入!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章