大話Sheepdog 2 – 對象緩存

分佈式存儲系統的性能一直都是衆矢之的,主要是因爲數據甚至元數據的存取都添加了網絡層的開銷。對於多拷貝的對象存儲來說,甚至還有複雜的邏輯來保持各個拷貝的一致性。對於拷貝的讀寫,讀寫的優化通常是不可兼得。比如通過最終一致性(eventual consistency)優化了寫,但是讀的時候需要讀取大於一份的拷貝,來判斷是否是最新的。這些問題都導致了性能的低下。

很多POSIX文件的操作都是元數據操作的重度用戶,通常一個文件系統的系統調用會含有多個元數據操作。比如在EXT4上,一個簡單的讀4K大小的數據操作,最壞的情況會讀3次(對於大文件來說,可能大於3次)磁盤,但是隻有一次磁盤操作用於讀這個4K數據,而其它操作都是元數據操作。這也是爲什麼Linux內核需要引入複雜的dentry和inode兩個cache來加速元數據操作。所以對於很多支持POSIX文件操作的分佈式文件系統來說,額外的元數據操作加重了性能的惡化,往往一次系統調用會產生好幾次的網絡數據操作。而塊設備的操作模式簡單很多:順序的讀、寫和沖刷(FLUSH),沒有了元數據的讀寫負擔,所以Sheepdog可以相對簡單高效的存取數據,強一致性寫,讀任意一份拷貝即可。Sheepdog的讀操作是1比1的比例,不會有任何額外的操作。這也算得上Sheepdog 相對於分佈式文件系統如GlusterFS用文件來提供卷服務的優勢,避免了不必要的POSIX軟件層的開銷。QEMU、虛擬機與Sheepdog集羣的關係如下圖所示:
sd-node

雖然Sheepdog用哈希算法來尋址數據,免去元數據的操作,實際上也有自己的元數據。這個元數據同普通的數據對象一樣,也是一個固定大小的對象,專門用來描述虛擬卷(一個卷對應着一個元數據對象)。Sheepdog通過這個元數據來實現以下的功能:數據的稀疏存儲和寫時複製(Copy-On-Write)。對於這個特殊的對象,由於很小,虛擬機在啓動的時候QEMU就會整個讀取加載到內存裏面,當寫到卷的“空洞”的時候,也就是需要創建一個數據對象來裝載用戶數據時,纔會去更新這個元數據對象。

同其它軟件一樣,Sheepdog也通過客戶端的緩存,對象緩存(Object Cache)來加速對象的存取。但是這個對象緩存除了加速IO操作,還有另外一個重要的功能:減少網絡的流量。這對於大規模的集羣至關重要,因爲相對於處理器和硬盤來說,帶寬更加緊張也更容易成爲集羣擴展的瓶頸。

體驗對象緩存

# 啓動3個節點,並且開啓200M大小的對象緩存。因爲shm不支持directio,所以默認沒有開啓directio模式
 $ for i in 0 1 2; do sheep /tmp/store$i -c local -w object:size=200:dir=/dev/shm/$i -z $i -p 700$i;done
 $ collie cluster format -b plain
 $ collie vdi create data 1G
 # 然後您可以啓動虛擬機,像往常一樣掛載data卷,或者直接把操作系統安裝到捲上,體驗加速的卷!

對象緩存實現原理

對象緩存的實現非常的簡單和直觀,這裏我用本地文件作爲塊設備的存儲後端來做類比,描述其工作機制。當用本地文件作爲存儲後端時,比如(QCOW2格式),我們主要通過主機的內存頁來緩存模擬的塊設備的塊來加速IO性能(writeback模式)。首先QEMU將這些模擬的設備塊對應到文件的邏輯塊上,然後內核在內部把文件的邏輯塊對應到頁緩存(Page Cache)的內存頁上,並且依賴內存子系統來預讀數據/回寫髒數據。所以虛擬機的塊設備操作通過一系列的轉換變成了內存頁的讀寫。一般情況下,只有虛擬機發送沖刷(比如虛擬機裏面執行了fsync(2))請求的時候,內核纔會將這些髒數據回寫到硬盤。當然,現實更加複雜,因爲內存是有限的,所以當內存不夠時,內核還要通過LRU(Least Recently Used)算法進行頁面回收。如下圖所示:

QEMU 《----》 VM
  ^
  |                           writeback/readahead pages
  V                                                |
POSIX file 《 --- 》 page cache 《 --- 》 disk
                                     |
             Kernel does page wb/ra and reclaim

對象緩存跟這個結構非常的類似,如下圖所示:

QEMU 《----》VM
  ^
  |                                                 push/pull objects
  V                                                             |
Sheepdog device 《--- 》 object cache 《 --- 》 Sheepdog replicated object storage.
                                                  |
                  Sheep daemon does object push/pull and reclaim

這裏sheep進程扮演了內核的角色,內存頁變成了對象。同本地文件一樣,虛擬機的讀寫請求在操作完緩存裏面的對象後就返回了,只有當收到沖刷的請求時,纔會把髒數據回寫到集羣中去。值得注意的是,同本地文件一樣,對象緩存只是充當虛擬卷(塊設備)的磁盤緩存,並沒有犧牲任何虛擬機裏面文件系統的數據一致性,因爲目前的操作系統(包括Linux和Windows)幾乎都是磁盤緩存感知的,當認爲數據必須寫到持久化介質時,都會顯示的發送沖刷命令,同時應用程序也可以通過fsync(2)或者open(2)參數設置SYNC標記發送沖刷請求。同本地文件緩存還有一個大的區別,就是對象緩存可以選擇把數據放在磁盤上而不是內存裏,這樣不會佔用相對緊張的內存資源。對象緩存也是通過LRU算法來進行對象回收的。

對象緩存、快照與熱遷移

當虛擬機釋放(如關機等)的時候,sheep進程負責沖刷髒數據(如果還有的話)和回收對象,釋放緩存,所以不管是關機冷遷移,還是運行時熱遷移,對象緩存都會自動的隨着虛擬機遷移到指定的節點,不需要用戶任何手動的介入。

對象緩存也考慮到了克隆的數據去冗餘。當多個克隆來自於同一個快照的時候,這個時候這些克隆將共享大多數的數據(如操作系統和大多數系統配置文件),而所有共享的數據在緩存中只有一份拷貝。這些共享對象也是寫時複製的,所以不會出現任何安全問題。

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