資料庫的自我修鍊——阿里雲MongoDB備份恢復功能說明和原理介紹
摘要: 2018年1月17-25日,NoSQL資料庫直播大講堂峰會順利結束,阿里雲資料庫團隊為大家帶來了一場別開生面的知識盛會,給大家帶來深度的資料庫技術及產品分享。本文是《阿里雲MongoDB備份恢復功能說明和原理介紹》演講整理,主要講解了阿里雲在MongoDB備份恢復上採用的技術原理和優勢。
原文:http://click.aliyun.com/m/41266/
本次直播視頻精彩回顧,戳這裡!
直播涉及到的PPT,戳這裡!
演講嘉賓簡介:
鄭涔(花名:明儼) 阿里雲技術專家,2011年加入阿里,曾參與TFS、Tengine研發,目前主要參與阿里雲MongoDB雲資料庫服務研發,主要關注分散式存儲、資料庫等領域。
本篇文章來自於阿里雲技術專家鄭涔(明儼)在2018年《Redis、MongoDB、HBase大咖直播大講堂》技術直播峰會中的分享,該分享整體由四個部分構成:
1、MongoDB備份恢復
2、阿里雲MongoDB備份恢復
3、阿里雲MongoDB Sharding備份恢復
4、阿里雲MongoDB物理熱備份恢復
初來乍到——MongoDB備份恢復
MongoDB備份恢復在備份方法上總體來說分為兩部分:邏輯備份和物理備份。
邏輯備份就是通過mongodump和mongorestore兩個工具在資料庫層將MongoDB的數據進行導出和導入。物理備份的作用更接近底層一些,例如作用在文件系統上,通過cp和tar文件系統工具,將MongoDB的物理文件拷貝走進行備份。物理備份還有一種方式是通過邏輯卷或者塊設備更為底層的部分進行備份,例如配置一個邏輯卷採用lvm snapshot的方法去做磁碟的快照,或者利用像阿里雲的ECS雲伺服器執行雲盤的快照功能,從而實現物理備份。
MongoDB全量邏輯備份恢復是通過mongodump和mongorestore兩個工具來實現的,這兩個工具不僅可以作用在正在運行的MongoDB上,也可以作用在Sharding的mongos上,把整個資料庫的數據進行導入導出。全量邏輯備份恢復可以輸出為兩種格式:第一種為BSON格式,以這種方式導出之後可以看到本地磁碟上會有很多目錄,每一個資料庫都會有各自的BSON格式的數據;第二種為歸檔的格式,即把所有資料庫的數據輸出成一個文件,可以方便地實現流式備份和恢復。
全量邏輯備份的基本機制是通過資料庫層的一些結構來實現的,在當本的過程中通過資料庫find的方法,將資料庫中的數據全部查詢出來,如果數據為索引時,導出的只是一些元數據,例如索引建在哪個欄位上、什麼類型的索引、索引有哪些選項這些元數據,並沒有把索引的數據本身導出來,在恢復時通過insert方法重新將數據插回到資料庫當中。在恢復的過程中需要重建索引,如果索引的數據量非常大,重建索引的過程將花費很長的時間,成為了全量邏輯備份比較大的問題。
全量邏輯備份恢復的一大優點,即備份和恢復單庫單表的能力,方便於某些場景的應用,例如緊急狀態下需要恢復某一資料庫的某一個表,此時不需要下載整個全量的數據備份,只需單獨把想要恢復的表進行恢復即可。
全量邏輯備份通過資料庫介面訪問資料庫,如果資料庫配置一個認證需要賬號和密碼進行訪問時會有一些許可權的要求,可以通過MongoDB內置的backup和restore兩個角色進行備份和恢復。
此外,全量邏輯備份可以指定進行gzip壓縮,從而減少數據備份的大小,節省存儲成本。
在MongoDB全量邏輯備份過程中資料庫可以接受外部正常的讀寫,使用oplog選項抓取備份過程中的修改,恢復時使用oplogReplay選項,此時需要較高的額外許可權,從而獲取一致的備份,確保數據備份的過程中,對數據的修改也會進行備份。
MongoDB全量物理備份恢復通過某些手段將物理文件拷貝走進行備份,其中MongoDB可以支持多個存儲引擎,物理文件與存儲引擎的存儲布局相關,所以物理備份恢復無法做到跨存儲引擎的備份恢復,例如使用WiredTiger的存儲引擎備份的數據只能恢復成WiredTiger,不能恢復成其他的存儲引擎。另外物理備份有一個很大的好處是,由於備份時將所有的域塊進行備份,在恢復的過程中不需要重建索引,只需要將備份數據下載下來,提起進程即可使用,相對全量邏輯備份更為高效。
然而全量物理備份的不足之處在於,它不具備備份和恢復單庫單表的能力,文件之間相互關聯,無法將某一個資料庫的單獨文件提取恢復出來。
全量物理備份方法通常可以分為兩大類:第一類是通過一些系統組件的snapshot快照功能來實現備份,對系統組件有些依賴,在單盤多租戶的情況下,無法做到對塊盤上每一個MongoDB實例單獨進行備份,依賴於配置MongoDB的Journal實現宕機恢復,從而達到一致備份;第二類是使用文件拷貝簡單的方式通過文件系統進行物理備份,可以做到目錄級的拷貝,支持單盤多租戶的數據拷貝,在文件拷貝開始之前需要執行db.fsyncLock的命令,即對MongoDB的全局加一個寫鎖,在整個備份的過程中資料庫無法提供服務,物理文件拷貝完畢執行db.fsynUnclock解鎖命令,間接達到一致備份的效果。
總體上來看,在備份效率上,邏輯備份不如物理備份。邏輯備份通過資料庫介面讀取數據,當邏輯備份數據量很小、條目很多時,效率會很低,物理備份時物理文件一般會經過文件壓縮,拷貝的數據相對來說比較少,同時物理備份較充分地使用系統資源,效率會較高。在恢復效率上,邏輯備份也低於物理備份。邏輯備份需要導入數據和重建索引,而物理備份直接啟動進程即可。在備份影響上,備份影響主要指在備份的過程中是否對一些正常的業務訪問產生影響,由於邏輯備份通過資料庫介面讀取數據,它將直接與業務爭搶資料庫資源,而物理備份間接爭搶系統的資源,相對來說備份影響比較小。在備份集的大小上,由於邏輯備份沒有備份索引數據,一般比原資料庫小或相同,而物理備份與原資料庫是一模一樣的。在兼容性上,邏輯備份優於物理備份,物理備份與存儲引擎相關,無法做到跨存儲引擎的備份恢復,而邏輯備份兼容絕大部分版本。同時,物理備份的成功率比邏輯備份高很多,在某些場景邏輯備份無法進行恢復。
在MongoDB副本集有oplog進行主備同步,增量備份就是採集oplog並進行存儲,全量備份加增量備份就可以實現任意時間點的備份。
厚德載物——阿里雲MongoDB備份恢復
阿里雲MongoDB備份恢復主要分為四大塊:備份、恢復、備份存儲和備份有效性驗證。
備份當中可以定製一些備份策略,為用戶的MongoDB做一些自動備份,用戶也可以在控制台進行手動備份,同時用戶可以指定一個備份周期和保留時間對備份進行安排。恢復策略中用戶可以選擇恢復時覆蓋原來的實例或者克隆一個新的實例,也可以指定恢復的力度,選擇恢復到全量的備份集或者恢復到指定的時間點。備份存儲中,將數據存儲在阿里雲OSS上具有10個9的可靠性。備份有效性驗證中,定期對MongoDB實例的備份做一些有效性的驗證,避免恢復備份時發現備份出現問題,確保備份可以進行恢復。
以下為阿里雲MongoDB控制台的兩個主要界面:
上圖為備份列表界面,可以看到備份的一些情況,包括備份的完成時間、是否為自動備份、手動備份等。用戶可以點擊右上角的備份實例進行手動備份,可以下載備份、根據備份創建實例或者指定一個時間點新建實例、克隆實例。
上圖為備份設置界面,用戶可以制定一些備份策略,包括備份的保留天數、備份的周期等。
精益求精——阿里雲MongoDB Sharding備份恢復
MongoDB Sharding架構主要由三大組件構成:藍色部分為路由節點mongos,它是無狀態的、沒有存儲數據的,不需要進行備份;綠色部分為Shard集群,用於存儲用戶分片的數據,通過副本集的方式實現高可用,需要進行數據備份;黃色部分為Config Servers,主要存放集群當中的元數據,作為副本集同樣需要進行備份。
面對MongoDB Sharding出現的問題,阿里雲是如何進行有效解決的呢?
第一個普遍的問題是關於集群多個節點在外部修改情況下如何取得一致備份。在一個集群當中的多個節點和每一個節點的容量是不同的,導致節點備份的耗時不同,當對應用進行寫入時,由於每個節點備份結束的時間不同,有些節點的備份會多包含一些新寫入的數據,其中備份結束的時間點很難進行確定。
針對問題一,阿里雲採用全量備份加增量備份可以做到各節點備份恢復至同一時間點,在備份結束比較早的節點可以多抓取一些oplog,備份結束比較晚的節點可以少抓取一些oplog,從而保證各自節點的備份加oplog能夠對應到同一個時間點。
第二個備份問題是關於內部數據的修改,在集群內部通常會有數據的遷移,上圖展示了MongoDB Sharding內部數據的一些表示,在做Sharding時通常需要指定一個Shard Key即分片的片鍵,接下來的數據將會按照Shard Key的大小範圍進行分布,例如選擇使用哈希分片,按照Shard Key哈希之後的結果作為分布。Chunk是Shard Key一部分範圍所對應值的集合,例如上圖左側分為4個Chunk,分別對應Shard Key的不同取值範圍。上圖右側Chunk作為一個基礎的單元在不同的Shard之間進行分布,config server存放著元數據。
由於對集群進行擴容的需要,增加或刪除Shard需要MongoDB Sharding進行數據遷移,同時數據分布不均時也會自發地進行數據遷移,而MongoDB可以決定是否採用數據遷移。上圖右側即為Chunk遷移的基本過程。
如上圖所示,兩個Shard上的Chunk不均衡,Chunk1需要從Shard1遷移到Shard2上,當所有的節點備份結束時,Chunk1的遷移可能還沒有結束,同時config server上還是原來的數據分布,此時Shard1仍存在三個Chunk,而Shard2存儲部分Chunk1,由於數據恢復是以config server為基準,決定去哪裡訪問Chunk數據,所以會認為Shard2拷貝了多餘的Chunk1數據產生數據重複。另外一種情況,備份結束後config server已經更新了路由信息,確認Chunk1已經在Shard2上,但是Shard2中的Chunk2數據還沒有完全拷貝完畢,數據恢復時會發現會有一部分的Chunk2數據丟失。綜上所述,Chunk遷移可能導致數據的重複與丟失問題。
針對問題二,阿里雲會對內部的Chunk遷移進行分析,然後對恢復的時間點進行限制避開有數據遷移的時間段,只有這個時間點沒有數據遷移才允許恢復至這個時間點。
為了解決以上問題,用戶在MongDB Sharding備份時可以配置一個遷移的時間段,即用戶可以根據業務訪問行為指定遷移在哪段時間進行,從而保證遷移在預期時間段內進行,其它時間段可以進行備份恢復。可以通過上圖中的三段代碼配置遷移的時間點。
上圖為阿里雲MongoDB Sharding備份恢復的控制台,與備份列表界面相比多了選擇Shard的功能,可以選擇某一個Shard查看備份情況。
虛懷若谷——阿里雲MongoDB物理熱備份恢復
上文提到,通過文件拷貝做物理備份時,備份過程全程加全局寫鎖,不是熱備份,在這段期間MongoDB是無法正常訪問的。事實上WiredTiger存儲引擎支持熱備份,支持在備份過程中不停服務,為什麼還要在MongoDB上加全局寫鎖呢?其一MongoDB會在內存當中維護一些數據,需要通過fsyncLock把一些元數據刷到磁碟當中;其二WiredTiger的熱備份有個問題,如果在備份的過程當中有寫入,磁碟的空間增長得比較快。
阿里雲針對以上問題對MongoDB和WiredTiger進行了改造,抽象了三個階段的備份過程,在備份之前加入了預備份步驟,在備份之後加入了post-backup動作,並且只需要在預備份階段加入全局寫鎖即可。同時阿里雲改進了WiredTiger的熱備份機制,解決了熱備份過程中磁碟增長太快的問題。阿里雲MongoDB物理熱備份的方法在去年6月份就已經上線,目前的新實例也默認使用熱備份方式。
更多技術乾貨敬請關注云棲社區知乎機構號:阿里云云棲社區 - 知乎
推薦閱讀:
※mysql mybatis怎麼更新blob欄位?
※數據量很大,邏輯不能在內存里做怎麼辦?
※Revit數據導出到資料庫
※Google Spanner 是一個什麼樣東西?對未來會產生什麼樣的影響?