成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Cinder磁盤備份原理與實踐

開發 開發工具
快照(Snapshot)、復制(Replication)、備份(Backup)是存儲領域中最為常見的數據保護技術。備份就是對數據進行導出拷貝并傳輸到遠程存儲設備中。

[[188733]]

一、背景

1.1 數據保護技術概述

快照(Snapshot)、復制(Replication)、備份(Backup)是存儲領域中最為常見的數據保護技術。快照用于捕捉數據卷在某一個時刻的狀態,用戶可以隨時回滾到這個狀態,也可以基于該快照創建新的數據卷。備份就是對數據進行導出拷貝并傳輸到遠程存儲設備中。當數據損壞時,用戶可以從遠端下載備份的數據,手動從備份數據中恢復,從而避免了數據損失。快照類似于git的commit操作,我們可以隨時reset/checkout到任意歷史commit中,但一旦保存git倉庫的磁盤損壞,提交的commit信息將永久丟失,不能恢復。而備份則類似于git的push操作,即使本地的數據損壞,我們也能從遠端的git倉庫中恢復。簡而言之,快照主要用于快速回溯,而備份則用于容災,還能避免誤刪除操作造成數據丟失。數據復制則類似于mysql的master/slave主從同步,通常只有master支持寫操作,slave不允許用戶直接寫數據,它只負責自動同步master的數據,但一旦master出現故障,slave能夠提升為master接管寫操作。因此復制不僅提供了實時備份的功能,還實現了故障自動恢復(即高可用)。

1.2 Cinder數據保護功能介紹

Cinder是OpenStack中相對成熟的組件(總分為8分的成熟度評分中獲得了8分滿分),也是OpenStack的核心組件之一,為OpenStack云主機提供彈性的塊存儲服務,承載著用戶大多數的業務數據,即使出現數據的絲毫損壞也將可能導致災難性后果,因此數據的完整性保護至關重要。不得不說Cinder對數據卷保護方面支持度還是比較給力的,目前Cinder已經同時支持了對數據卷的快照、復制和備份功能。

快照應該是Cinder非常熟悉非常受歡迎的功能了,也是Cinder默認支持的功能,幾乎所有的存儲后端都支持快照。而備份作為Cinder的可選功能之一,由于數據卷的存儲后端很多已經提供了多副本功能(比如Ceph存儲后端默認為三副本),通常很少人會再部署一套備份存儲集群,因此部署率并不是很高。復制也是Cinder的可選功能之一,目前支持的存儲后端還非常有限,最常采用的RBD存儲后端也是在Ocata版本才開始支持,并且要求Ceph版本需要支持rbd-mirror(jewel版本以上),因此受到用戶的關注度還不是很高,部署率較低。

二、深入理解Cinder數據卷備份原理

2.1 cinder backup功能介紹

cinder磁盤備份為用戶的數據卷實例提供備份和恢復功能,實現了基于塊的容災功能。從K版本開始,Cinder引入了增量備份功能,相對全量備份需要拷貝和傳輸整個數據卷,增量備份只需要傳輸變化的部分,大大節省了傳輸開銷和存儲開銷。通常情況下,當用戶執行備份或者恢復操作時,需要手動卸載數據卷,即數據卷不支持在掛載狀態下熱備份。從L版本開始,新增了force選項,當用戶指定force選項時能夠對掛載的數據卷強制執行備份操作,這樣可能帶來數據不一致的風險,不過社區針對這種情況做了些優化,比如在創建備份前先基于該數據卷快照創建臨時數據卷,然后基于臨時數據卷執行后續備份操作。

Cinder開啟備份功能,需要單獨部署cinder-backup服務。cinder-backup服務和cinder-volume服務類似,也支持各種不同的驅動,對接不同的存儲后端,目前支持的存儲驅動列表如下:

  • swift,備份數據保存在OpenStack Swift對象存儲中。
  • google,備份數據保存在Google Cloud Storage(GCS)中。
  • glusterfs,保存到glusterfs中。
  • nfs,保存到NFS中。
  • posix,保存到本地文件系統。
  • tsm,保存在IBM Tivoli Storage Manager(TSM)。
  • ceph,保存到ceph集群中。

從列表中看,目前cinder backup尚不支持備份數據到AWS S3中。

除了數據卷本身的備份,cinder backup還支持將元數據序列化導出(export record),這樣即使數據庫中的數據丟失了,也能從導出的元數據中快速恢復。

2.2 cinder backup原理剖析

前面提到cinder backup支持多種后端存儲驅動,但大體可以分為兩類:

  • 存儲系統本身就提供塊存儲服務,比如ceph。這種情況只需要直接導入到該存儲系統即可。
  • 存儲系統不支持塊存儲服務,只支持基于文件的存儲,以上除了ceph和tsm都屬于此類。此時備份采取了分塊備份策略,即首先把數據卷切割為一個個獨立的文件,然后分別把這些文件存儲到設備中。恢復時只需要重組這些小文件即可。

接下來我們針對此兩種情況深入研究下cinder backup的實現原理。

2.2.1 分塊備份策略在介紹之前先了解兩個重要的參數

  • chunk_size: 表示將volume切割成多大的塊進行備份,一個塊稱為一個chunk。在NFS中這個值叫做backup_file_size,默認是1999994880Byte,大約1.8G。在Swift中這個值叫做backup_swift_object_size,默認是52428800Byte,也就是50M。這個參數決定數據卷備份后塊的數量(Object Count),比如一個2GB的數據卷,如果chunk_size為500MB,則大約需要4個塊,如果使用本地文件系統存儲的話,對應就是4個文件。
  • sha_block_size: 這個值用于增量備份,決定多大的塊求一次hash,hash相同說明內容沒有變化,不需要備份。它決定了增量備份的粒度。在NFS中,這個值叫做backup_sha_block_size_bytes,在Swift中,這個值叫做backup_swift_block_size。默認都是32768Byte,也就是32K。在Ceph,沒有對應的概念。

對一個數據卷做全量備份時,每次從數據卷讀入chunk_size字節的數據構成一個chunk,然后每sha_block_size個字節做一次sha計算,并將結果保存起來,最后把chunk_size的數據進行壓縮(可以配置不壓縮)后保存到對應的存儲系統上,這就形成了NFS上的一個文件或者Swift中的一個object[6]。如此循環直到把整個數據卷都備份到存儲系統。

那恢復的時候怎么重組呢?這就需要保存元數據信息,元數據信息包括:

  • backup信息:其實就是數據庫中的信息,或者說就是一個backup object實例的序列化,包括backup name、description、volume_id等。
  • volume信息:數據卷信息,即volume實例的序列化,包括size、name等。
  • 塊信息:即objects信息,這是最重要的數據,記錄了每一個塊的長度、偏移量、壓縮算法、md5值,備份恢復時主要通過這些塊信息拼接而成。
  • 版本:序列化和持久化必不可少的參數。

除了保存以上元數據信息,還會按順序保存每一個block的sha256值。這些信息主要用于支持增量備份。做增量備份時,也是每次從數據卷讀入chunk_size字節的chunk數據,然后計算該chunk的每個block的sha值。不同的是,Cinder會把每一個block的sha值與其父備份對應的sha值比較,僅當該block的sha值與父備份block的sha值不一樣時,才保存對應的block數據。如果sha值和父備份的sha值相同,說明這個block的數據沒有更新,不需要重新保存該block數據,而只需要保存sha值。當然,如果有多個連續block的sha值都不一樣,則保存時會合并成一個object,通過元數據記錄該object在原volume的偏移量以及長度。

如圖1所示,假設一個chunk分為9個block,每個block為100KB,注意每個block都保存了sha256值,圖中沒有標識。基于該chunk做一次增量備份后,假設只有block 2、7、8有更新,則增量備份只會保存block 2、7、8,由于7和8是連續的,因此會自動合并成一個chunk,而block 2單獨形成一個chunk,即原來的chunk分裂成了兩個chunk,但總大小為300KB,節省了1/3的存儲空間。

圖1 增量備份原理圖

圖1 增量備份原理圖

備份的恢復參考文獻[6]講得非常清楚,這里直接引用:

全量備份的恢復很簡單,只需要找到對應的備份,將其內容寫回對應的volume即可。那么這里有個問題,每個備份都對應存儲上哪些文件呢,每個文件又對于原始volume中哪些數據?還記得創建備份時生成的metadata文件嗎,答案就在其中。恢復備份時,會讀取這個文件,然后將每一個備份文件恢復到對應的位置。當然,如果有壓縮也會根據metadata中的描述,先解壓再寫入對應的volume中。

增量備份的恢復稍微復雜一些,正如之前的描述,增量備份之間有依賴,會形成備份鏈,我們需要恢復所選備份及其在備份鏈上之前所有的數據。在恢復時,需要查詢數據庫,獲取當前備份及備份鏈上之前的所有備份,其順序是[所選備份,父備份,父父備份,…,全量備份],恢復的時候會按照相反的順序依次進行,即首先恢復全量備份,接著創建的第一個增量備份,第二個增量備份,直到所選的備份。每個備份恢復時依賴創建備份時生成的metadata文件,將備份包含的文件,恢復到volume中。每個備份的恢復和全量備份的恢復方式一樣。

從備份的原理可以看出,增量備份能夠節省存儲空間,但隨著備份鏈長度越來越長,恢復時會越來越慢,性能越來越差,實際生產環境中應該權衡存儲空間和性能,控制備份鏈的長度。

Swift、NFS、本地文件系統、GCS等都是使用以上的備份策略,實際上實現也是完全一樣的,區別僅僅在于實現不同存儲系統的Reader、Writer驅動。

2.2.2 直接導入策略

直接導入策略即把原數據卷導出后直接導入到目標存儲系統中。對于支持差量導入的存儲系統,增量備份時則可以進一步優化。

以Ceph為例,我們知道Ceph RBD支持將某個image在不同時刻的狀態進行比較后導出(export-diff)補丁(patch)文件,然后可以隨時將這個補丁文件打到某個image中(import-diff)。即ceph原生支持差量備份,利用該特性實現增量備份就不難了。不過有個前提是,必須保證cinder-volume后端和cinder-backup后端都是ceph后端,否則仍然是一塊一塊的全量拷貝。

如果是對volume進行第一次備份,則:

  1. 在用于備份的ceph集群創建一個base image,size和原volume一樣,name為"volume-VOLUMD_UUID.backup.base" % volume_id。
  2. 在原volume創建一個新的快照,name為backup.BACKUP_ID.snap.TIMESTRAMP。
  3. 在原RBD image上使用export-diff命令導出與創建時比較的差量數據,然后通過管道將差量數據導入剛剛在備份集群上新創建的RBD image中。

如果不是對volume第一次備份,則:

  1. 在原volume中找出滿足r"^backup\.([a-z0-9\-]+?)\.snap\.(.+)$"的最近的一次快照。
  2. 在原volume創建一個新的快照,name為backup.BACKUP_ID.snap.TIMESTRAMP。
  3. 在原RBD image上使用export-diff命令導出與最近的一次快照比較的差量數據,然后通過管道將差量數據導入到備份集群的RBD image中。

恢復時相反,只需要從備份集群找出對應的快照并導出差量數據,導入到原volume即可。

注意:

  • volume和backup都使用ceph后端存儲時,每次都會嘗試使用增量備份,無論用戶是否傳遞incremental參數值。
  • 使用直接導入策略,不需要元數據信息以及sha256信息。

三、踩過的“坑”

雖然在前期做了大量關于cinder backup的調研工作,但實際部署過程中仍然踩了不少坑,PoC測試過程也非一帆風順,還好我們在填坑的過程還是比較順利的。本小節總結我們在實踐過程中遇到的坑,避免后來者重復踩“坑”。

3.1 熱備份導致quota值異常

我們知道備份是一個IO開銷和網絡開銷都比較大的操作,非常耗時。當對已經掛載的數據卷執行在線備份時,Cinder為了優化性能,減少數據不一致的風險,首先會基于該數據卷創建一個臨時卷,然后基于臨時卷創建備份,備份完成時會自動刪除臨時數據卷。從代碼中看,創建臨時卷時并沒有計算quota,換句話說,創建的臨時磁盤是不占用quota值的。但刪除時調用的是標準的刪除接口,該接口會釋放對應數據卷占用的數據卷quota值(主要影響gigabytes和volumes值)。也就是說,創建的臨時磁盤使volume quota值只減不增,用戶可以通過這種方式繞過quota限制。目前該問題社區還未修復,已提交bug:https://bugs.launchpad.net/cinder/+bug/1670636。

3.2 不支持ceph多后端情況

我們內部cinder對接了多個ceph集群,不同的ceph集群通過不同的配置文件區分。但cinder-backup服務向cinder-volume服務獲取connection info時并沒有返回ceph的配置文件路徑,于是cinder-backup服務使用默認的配置文件/etc/ceph/ceph.conf,該ceph集群顯然找不到對應volume的RBD image,因此在多backend情況下可能導致備份失敗。不過該問題在新版本中不存在了。

3.3 使用ceph存儲后端時不支持差量備份

我們前面提到如果cinder-volume和cinder-backup后端都是ceph,則會利用ceph內置的rbd差量備份實現增量備份。那cinder-backup服務怎么判斷數據卷對應的后端是否ceph呢?實現非常簡單,只需要判斷數據卷的連接信息是否存在rbd_image屬性,實現代碼如下:

  1. def _file_is_rbd(self, volume_file):  
  2. """Returns True if the volume_file is actually an RBD image."""  
  3. return hasattr(volume_file, 'rbd_image'

社區從M版開始把與存儲后端交互的代碼獨立出來,建立了一個新的項目–os-brick,與之前的ceph驅動存在不兼容,沒有rbd_image這個屬性。因此backup服務會100%判斷數據卷不是ceph后端,因此100%執行全量備份。該問題社區還未完全修復,可參考https://bugs.launchpad.net/cinder/+bug/1578036。

四、我們的改進

4.1 獲取父備份ID

當備份存在子備份時,用戶無法直接刪除該備份,而必須先刪除所有依賴的子備份。目前Cinder API只返回備份是否存在依賴的子備份,而沒有返回子備份的任何信息,也沒有返回父備份的信息。當用戶創建了很多備份實例時,很難弄清楚備份之間的父子關系。我們修改了Cinder API,向用戶返回備份的父備份id(parent_id),并且支持基于parent_id過濾搜索備份。當用戶發現備份存在依賴時,能夠快速檢索出被依賴的子備份。當然,如果存在很長的父子關系時,需要一層一層判斷,仍然不太方便,并且不能很清楚的輸出備份的父子關系。于是我們引入了備份鏈的概念,下節詳細討論。

4.2 引入備份鏈概念

為了方便查看備份之間的父子關系,我們引入了備份鏈(backup chain)的概念,一個數據卷可以有多個備份鏈,每條備份鏈包括一個全量備份以及多個增量備份組成。我們新增了兩個API,其中一個API輸出指定數據卷的備份鏈列表,另一個API輸出指定備份鏈的所有備份點,按照父子關系輸出。目前我們的備份鏈只支持線性鏈,暫時不支持分叉的情況。通過備份鏈,用戶能夠非常方便地查看備份之間的父子關系和備份時間序列,如圖2。

圖2 備份鏈展示

圖2 備份鏈展示

4.3 創建備份時指定備份鏈

創建增量備份時,默認是基于時間戳選擇最新的備份點作為父備份,我們擴展了該特性,支持用戶選擇在指定備份鏈上創建備份,這樣也可以避免備份鏈過長的情況。

五、后續工作

Cinder backup功能已經相對比較完善了,但仍然存在一些功能不能滿足客戶需求,我們制定了二期規劃,主要工作包括如下:

5.1 級聯刪除

目前Cinder不支持備份的級聯刪除,即如果一個備份實例存在依賴的子備份,則不能刪除該備份,必須先刪除其依賴的所有子備份。如果備份鏈很長時,刪除備份時非常麻煩。在二期規劃中,我們將實現備份的級聯刪除功能,通過指定--force選項,支持刪除備份以及其依賴的所有備份,甚至刪除整個備份鏈。

5.2 獲取增量備份大小

目前Cinder備份的實例大小是繼承自原volume的大小,基于分塊策略備份還有Object Count(chunk 數量)的概念,但這只是顯示分成了幾個chunk,每個chunk大小不一定是一樣的,并不能根據chunk數量計算實際占用的存儲空間。備份存儲空間是我們計費系統的計量標準之一,全量備份和增量備份成本肯定是不一樣的,如果價錢一樣,則用戶并不一定樂于使用增量備份。在二期規劃中,我們將實現計算備份占用的實際存儲空間的接口。

5.3 備份到S3

很多私有云用戶考慮各種成本,不一定會部署額外用于備份的Ceph集群,也不一定需要Swift對象存儲,而更傾向于將數據備份到價格低廉、穩定可靠的AWS S3中。目前Cinder backup后端還不支持S3接口,為了滿足客戶需求,我們計劃在二期中實現S3接口,用戶可以隨時把volume數據備份到S3中。

六、總結

本文首先介紹了數據保護的幾種常用技術,指出備份是數據保護的關鍵技術之一。接下來重點介紹了cinder backup的原理,對比了基于分塊備份策略和直接導入策略。然后吐槽了我們在實踐中踩到的各種“坑”。最后分享了我們做的一些優化改進工作以及后期工作。

【本文是51CTO專欄作者“付廣平”的原創文章,如需轉載請通過51CTO獲得聯系】

戳這里,看該作者更多好文

責任編輯:武曉燕 來源: 51CTO專欄
相關推薦

2017-10-20 15:25:17

DockerOpenStack Cvolume

2020-05-22 09:12:46

HTTP3網絡協議

2009-06-08 16:52:00

2025-02-06 08:24:25

AQS開發Java

2024-05-10 11:35:22

Redis延時隊列數據庫

2025-02-08 08:10:00

2024-04-18 09:20:43

PostgreSQL關系型數據庫數據庫管理系統

2021-12-20 00:03:38

Webpack運行機制

2017-05-04 16:35:45

2023-10-29 16:26:27

Python動查重

2009-07-24 13:54:39

MVVM模式

2023-07-27 06:38:52

HBase大數據

2023-02-22 07:04:05

自動機原理優化實踐

2011-08-15 09:48:30

MySQL數據庫完整備份增量備份

2014-07-28 09:22:46

Linux運維磁盤

2017-09-15 08:22:17

磁盤備份設備

2022-02-15 23:55:35

磁盤F2F備份

2017-07-07 10:40:24

MySQL備份原理

2023-09-12 13:48:47

2010-02-03 09:01:01

Java動態模塊化
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 在线观看国产视频 | 亚洲综合第一页 | 免费午夜电影 | 久久久久久久电影 | 亚洲天堂一区 | 嫩草黄色影院 | 看特级黄色片 | 日韩综合在线视频 | 国产一区二区电影 | 狠狠爱免费视频 | www视频在线观看 | 91视在线国内在线播放酒店 | 一区二区三区高清 | 免费在线国产视频 | 欧美黄色一区 | 国产 日韩 欧美 中文 在线播放 | 中文日韩在线 | 日日骚网 | 亚洲高清一区二区三区 | 欧美日韩中文在线观看 | 9久久婷婷国产综合精品性色 | 美国一级黄色片 | 国产三级 | 伦理午夜电影免费观看 | 久久久久久国产精品久久 | 亚洲精品久久久久avwww潮水 | 日日碰狠狠躁久久躁婷婷 | 搞av.com | 久久99精品久久久水蜜桃 | 爱草在线 | 国产色 | 国外激情av | 久久高清 | h视频在线免费 | 在线一区视频 | 精品久久久久久久久久久 | 国产一区二区三区免费观看视频 | 日韩欧美视频 | 精品视频成人 | 在线中文字幕国产 | 国产一区二 |