【轉載】快照原理-差分快照(COW&ROW)

之前在介紹 Linux 文件系統的文章中,有提過 ZFS、Btrfs文件系統中,有內置快照的功能,也有提到過其快照的由 CoW 機制實現的。那麼這篇文章將帶領大家瞭解快照的原理。

快照技術分類

常見快照的類別有兩類:

  • 全拷貝快照
  • 差分快照

全拷貝快照

拷貝快照是通過鏡像技術來實現的,即其同時會寫兩個磁盤,我們可以理解爲磁盤整列技術中的 RAID1。

下面通過一張原理圖來介紹全拷貝快照的實現原理。

全拷貝快照.png

全拷貝快照特點:

  • 空間佔用:需要與源盤相同大小的存儲空間
  • 創建過程:每一次全拷貝快照都需要完全數據同步
  • 讀寫操作影響:

    • 源卷的讀操作不受影響
    • 源卷的寫操作受數據同步的影響
    • 創建完成後,快照的讀寫操作保持最優

差分快照

差分快照又分爲以下幾種技術:

  • CoW (Copy On Write)
  • RoW (Redirect On Write)

CoW

CoW (Copy On Write),譯爲寫時複製。這種方式通常也被稱爲“元數據(源數據指針表)”拷貝。顧名思義,如果快照創建後,試圖改寫源數據塊上的原始數據,首先將原始數據拷貝到新數據塊中,然後再進行改寫。當還原快照需要引用原始數據時,快照軟件將原始數據原有的指針映射到新數據塊上。

再來深入的看看 CoW 的過程,CoW 在創建快照時,並不會發生物理的數據拷貝動作,僅是拷貝了原始數據所在的源數據塊的物理位置元數據。因此,CoW 快照創建非常快,可以瞬間完成。在創建了快照之後,快照軟件會監控跟蹤原始數據的變化(即對源數據塊的寫操作),一旦源數據塊中的原始數據被改寫,則會將源數據塊上的數據拷貝到新數據塊中,然後將新數據寫入到源數據塊中覆蓋原始數據。其中所有的源數據塊就組成了所謂的源數據卷,而新數據塊組成了快照卷。你應該能夠看出 CoW 有一個很明顯的缺點,就是會降低源數據卷的寫性能,因爲每次改寫新數據,實際上都進行了兩次寫操作。

不知道你有沒有看過前面的一篇文章《認識 EXT2 文件系統》,這篇文章中,描述了文件系統的底層結構。我們知道文件路徑與 inode 與文件數據的關係:文件索引 -> inode -> data block。

  • 文件索引:記錄文件名與 inode 的對應關係
  • inode:記錄文件數據所在的 data block
  • data block:保存文件數據

那麼 CoW 的工作原理可以用圖來表示,如下:

CoW快照原理.png

總結一下,CoW 快照的優缺點:

  • 首次修改數據性能下降
  • 讀數據性能不變

RoW

RoW (Redirect-On-Write),譯爲寫時重定向。RoW 的實現原理與 CoW 非常相似,區別在於「RoW 對原始數據卷的首次寫操作,會將新數據重定向到預留的快照卷中」,而 CoW 一般會使用新數據將原始數據覆蓋。所以,RoW 快照中的原始數據依舊保留在源數據卷中,並且爲了保證快照數據的完整性,在創建快照時,源數據卷狀態會由讀寫變成只讀的。

不知道你在使用 Vmware 或 ESXi 虛擬機做快照時,有沒有留意到每做一次快照,其實是生成了一下新的快照文件,這個文件最開始是幾十 KB 的大小,慢慢的隨着虛擬機的運行發生了文件的變動,快照文件大小才逐漸變大。是的, Vmware 快照的實現機制就是 RoW。我們還可以對虛擬機做多個快照,這樣就產生了一個快照鏈,虛擬機磁盤卷始終掛載在快照鏈的最末端,即虛擬機的寫操作全都會落盤到最末端的快照卷中。該特徵導致了一個問題,就是如果一共做了 10 次快照,那麼在恢復到最新的快照點時,則需要通過合併 10 個快照捲來得到一個完整的最新快照點數據;如果是恢復到第 8 次快找時間點,那麼就需要將前 8 次的快照卷合併成爲一個完整的快照點數據。從這裏可以看出 RoW 的主要缺點是沒有一個完整的快照卷,其快照之間的關係是鏈式的,如果快照層級越多,進行快照恢復時的系統開銷會比較大。但 RoW 的優勢在於其解決了 CoW 快照寫兩次的問題,所以就寫性能而言,RoW 無疑是優於 CoW 的。

我們也用一張圖來表示其原理,如下:

RoW快照.png

總結一下,RoW 快照的優缺點:

  • 修改數據只是指針的重新指向,性能不變
  • 因爲要追蹤其鏈式關係找到源卷的數據,因此讀數據性能下降

快照的應用場景

前面我們介紹了快照的分類,可以分爲“全拷貝快照”、“差分快照”。而差分快照的主要實現技術是“CoW”或“RoW”。

那麼快照技術適用於哪些場景呢?

  • 全拷貝快照

     

    沒見過這麼玩的,太昂貴了,也許在一些高端產業上會用到

  • CoW

     

    大多高端文件系統都實現了 CoW 機制,快照是其賣點之一

    很多數據庫軟件自身也實現了 CoW 機制

  • RoW

     

    最典型的就是虛擬機的快照了,各虛擬機、虛擬化平臺所使用的快照技術一般都基於 RoW 來實現的

UnionFS

UnionFS 本來和快照沒有關係,爲什麼在這裏拎出來講一下呢?因爲 UnionFS 技術和 RoW 技術非常的類似,其採用聯合掛載的概念將多個層掛載成一個掛載點。

第一層:

/1.txt,內容:111
/2.txt,內容:222

第二層:

/1.txt,內容:112
/3.txt,內容:333

將第一層、第二層聯合掛載之後,看到的文件將是:

/1.txt,內容:112
/2.txt,內容:222
/3.txt,內容:333

不知道你發現其中的奧妙了沒有?是的,聯合掛載之後,整個掛載點就由一層疊加一層來實現的,術語叫遮掩層。其邏輯是:

  • 讀取上層沒有的文件,往下層逐層搜索,一直搜索到最底層,有則讀取
  • 新增文件,直接體現在上層中,不會往下層讀取
  • 修改文件,直接體現在上層中,不會往下層讀取
  • 刪除文件,在上層遮掩住,不會往下層讀取

Docker 把 UnionFS 的想像力發揮到了容器的鏡像。你可以查看這篇文章介紹Linux Namespace上篇用mount namespace 和 chroot 山寨了一鏡像。現在當你看過了這個 UnionFS 的技術後,你是不是就明白了,你完全可以用UnionFS 這樣的技術做出分層的鏡像來。

下圖來自 Docker 的官方文檔 Layer,其很好的展示了 Docker 用 UnionFS 搭建的分層鏡像。

docker-filesystems-multilayer.png

關於 docker 的分層鏡像,除了 aufs,docker 還支持 btrfs, devicemapper 和 vfs,你可以使用 -s 或 --storage-driver= 選項來指定相關的鏡像存儲。在 Ubuntu 14.04 下,docker 默認 Ubuntu 的 aufs(在CentOS7下,早期用的是devicemapper,現在用的是 Overlay File System)。

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