Facebook的MySQL數(shù)據(jù)庫遍布在我們位于全球的數(shù)據(jù)中心內(nèi),我們必須能在任何時間內(nèi)從任何位置發(fā)生的故障中恢復(fù)。在發(fā)生此類災(zāi)難事件后,不僅需要盡量快速可靠地恢復(fù)服務(wù),而且需要確保整個過程不會丟失任何數(shù)據(jù)。為此我們構(gòu)建了一套能夠?qū)膫浞葜谢謴?fù)數(shù)據(jù)庫的能力進行持續(xù)不斷測試的系統(tǒng)。
我們的還原系統(tǒng)包含兩個重要組件:
持續(xù)還原層(Continuous Restore Tier,CRT) - 負責(zé)對所有還原操作進行調(diào)度和監(jiān)控。該組件會查找包含新備份的數(shù)據(jù)庫,為其創(chuàng)建還原作業(yè),監(jiān)控還原過程,并確保每個備份可以成功還原。
ORC 還原協(xié)調(diào)器(ORC) - 由負責(zé)執(zhí)行還原的工作進程(Peon)和負載均衡器(Warchief)組成。Warchief接收來自CRT的新建還原作業(yè)并將其分配給Peon。Peon承載了負責(zé)執(zhí)行實際還原過程的本地MySQL實例。
數(shù)據(jù)CRT會收集每個還原作業(yè)的進度信息,借此幫助我們了解數(shù)據(jù)庫還原操作的資源需求,ORC則可以幫助我們驗證備份的完整性。本文將側(cè)重于介紹ORC的內(nèi)部原理,尤其是內(nèi)部的Peon狀態(tài)機(State machine),以及在對單一數(shù)據(jù)庫進行還原的過程中我們遇到并克服的挑戰(zhàn)。
備份概述
在構(gòu)建持續(xù)還原流程前,我們首先需要了解各種可用備份選項的本質(zhì)。目前我們主要進行三種備份,所有備份內(nèi)容均存儲在HDFS中:
完整邏輯備份 ,使用 mysqldump 每幾天進行一次。
差異(Diff)備份 在所有未進行完整備份的日子里進行。備份過程中會再次創(chuàng)建完整轉(zhuǎn)儲,但只存儲與上一次完整備份相比有差異的內(nèi)容。我們會通過元數(shù)據(jù)記錄每次差異備份是基于哪個完整備份進行的。
二進制日志(Binlog)備份 從主數(shù)據(jù)庫持續(xù)不斷地流式傳輸至HDFS。
完整和差異備份均會將 --single-transaction 選項傳遞至 mysqldump ,這樣我們就可以對數(shù)據(jù)庫獲得一致的快照,該快照可取自從屬(Slave)或主(Master)實例。下文會將差異和完整備份統(tǒng)稱為轉(zhuǎn)儲(Dump)。
由于每天只進行一次轉(zhuǎn)儲操作,因此可通過Binlog備份確保自從備份之后,數(shù)據(jù)庫所執(zhí)行的每一筆事務(wù)都能被我們記錄在案。隨后只要對轉(zhuǎn)儲內(nèi)容執(zhí)行還原操作將數(shù)據(jù)庫恢復(fù)至某個時點,隨后通過Binlog對事務(wù)進行重播(Replay),即可順利實現(xiàn)數(shù)據(jù)庫的時點還原。我們的所有數(shù)據(jù)庫服務(wù)器都使用了全局事務(wù)ID(GTID),因此在從Binlog備份進行事務(wù)重播時我們可以獲得額外的一層控制能力。
除了將備份存儲在HDFS中,我們還會將其寫入離場位置。Code as Craft活動中 Shlomo Priymak的講話 更詳細地介紹了我們的備份基礎(chǔ)架構(gòu)。
ORC:ORC還原協(xié)調(diào)器
架構(gòu)
ORC包含三個組件:
Warchief - 負載均衡器。這是一種可暴露出Thrift接口的Python程序,通過接口可接收新的還原請求,并將其調(diào)度至可用的Peon。
ORC DB - 負責(zé)維持分配給每個Peon的作業(yè)狀態(tài)、每個作業(yè)的當(dāng)前狀態(tài),以及Peon健康度狀態(tài)等信息的中央MySQL數(shù)據(jù)庫。Warchief會使用該數(shù)據(jù)庫中存儲的信息決定要將某個作業(yè)分配給哪個Peon,以及故障恢復(fù)過程中要使用的Peon。
Peon - 負責(zé)還原操作的工作進程。Peon也使用Python編寫,可暴露出Thrift接口,通過該接口接收有關(guān)Peon的各類狀態(tài)信息。每個Peon會定期與ORC DB進行同步,查詢分配給自己的新作業(yè),并匯報自己的健康度狀態(tài)。運行Peon的服務(wù)器上還運行了一個本地MySQL實例,備份將還原至該實例中。

內(nèi)部原理:Peon
Peon中包含了從HDFS獲取備份,將其載入自己的本地MySQL實例,通過Binlog重播將實例推進至某一時點等操作的所有相關(guān)邏輯。Peon處理的每個還原作業(yè)會經(jīng)歷下列五個步驟:
選擇(SELECT) - 決定需要用哪個備份進行還原(例如完整或增量,HDFS或離場等)。
下載(DOWNLOAD) - 將所選文件下載至磁盤。如果要還原的是完整備份,只需下載一個文件。對于差異備份,首先需要下載完整和差異備份,隨后在完整備份的基礎(chǔ)上應(yīng)用差異備份,并將最終結(jié)果存儲到磁盤上。無論備份類型為何,至此我們已經(jīng)在磁盤上有了一個 mysqldump 輸出的內(nèi)容。
加載(LOAD) - 將下載的備份載入Peon的本地MySQL實例。按照與備份文件中每張表有關(guān)的語句進行解析,并行恢復(fù)每張表,這一過程類似于 Percona的Mydumper 。