一個系統可能包含很多模組,如資料庫、前端、快取、搜尋、訊息佇列等,每個模組都需要做到高可用,才能保證整個系統的高可用。對於資料庫服務而言,高可用的實現可能更加複雜,對使用者的服務可用,不僅僅是能訪問,還需要有正確性保證,因此討論資料庫的高可用方案時,在容災之外,還要同時考慮方案中資料一致性問題。
本文將通過介紹一些業界主流的資料庫高可用架構、每種方案的特性和優缺點,以及資料庫高可用架構的自動化運維實現,講講資料庫高可用容災方案設計與實現,希望拋磚引玉,和大家一起討論。
一、高可用資料庫概述
什麼是高可用資料庫?
高可用資料庫是由一系列資料庫構成的總體系統,在任何時刻,至少有一個節點可以接受使用者的請求並提供資料庫服務。大多數資料庫架構中,有一個主節點處理主要請求,還有若干備用節點用於容災切換,當主節點不能提供服務時,備用節點成為主節點繼續提供服務,用以保證整個系統的可用和穩定。
高可用資料庫有很多優點:
第一,方便讀寫分離。資料庫請求當中,一般讀操作的請求次數遠大於寫操作,高可用資料庫可以通過將寫操作放在主資料庫節點上進行,將讀操作分擔到若干從庫上,來提升讀操作吞吐量,進而提升讀寫效率;
第二,變更不停服。當整個高可用資料庫架構或者主節點升級時,可以讓高可用資料庫先進行主庫切換,讓備用節點替換原主節點提供資料庫服務,當主節點升級完畢後,再將主從庫服務切換回來,這樣能有效避免系統升級或變更時對使用者服務質量產生影響;
第三,備份不影響服務效能。高可用資料庫架構包含多個從庫,在不影響主節點服務效能的情況下,能非常方便地實現資料的容災備份。
一般,高可用資料庫地架構設計時,也需要考慮三個問題:
第一,如何同步各資料庫之間的節點資料?同步需要保證切換後的資料庫是最新資料,以及在切換過程中資料不會丟失,同時還要考慮同步過程對主庫和備庫的影響。
第二,高可用資料庫的容災切換如何進行?架構不同容災切換的複雜度也不一樣,且切換以後需要保證主、從庫資料的一致性,這可能需要開發者在設計之初就儘量優化和簡化容災切換邏輯。
第三,如何提高高可用的運維效率?
二、業界典型高可用資料庫架構
按照資料同步方式,我們可以將業界主流的高可用架構劃分成四種:第一種,共享儲存方案;第二種,作業系統實時資料塊複製;第三種,資料庫級別的主從複製;第四種,高可用資料庫叢集。每一種資料同步方式可以衍生出不同的架構。
方案一:共享儲存
共享儲存指若干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大技術交流群,等你加入!