sheepdog(牧羊犬):一種EBS的開源實現(東西不多,但很全面)

sheepdog是EBS的開源實現, 爲虛擬機提供高可用的塊級存儲, 能夠擴展到數百臺機器, 支持快照,克隆等高級特性,其架構如圖所示



sheepdog從邏輯上分爲三個層次, 第一層QEMU block driver是客戶端,負責在kvm虛擬機中虛擬出一個塊設備;第二層是對象存儲層, 提供一個分佈式對象存儲服務, 對象類似文件,不同之處是定長且用64位ObjectID標識; 第三層是集羣管理,負責檢測節點故障,處理節點加入和退出,保證所有服務器看到一致的集羣成員關係。 另外一個功能是負責全局協調和同步, 例如創建volume,加鎖等操作需要每個節點進行狀態同步,達到一致狀態。集羣管理目前基於corosync實現。
Object Storage包含gateway和Object Manager兩個部分,gateway接受客戶端請求(QEMU block driver),根據一致性哈希計算定位目標節點,並路由請求到這些節點。 Object Manager是本地對象存儲,管理本地對象,實現對象上的讀寫操作。  

數據分片和定位
 

Volume又稱爲VDI(virtual Disk Image), volume數據以4M爲單位劃分爲多個DataObject,而元數據信息存儲在VDI Object中(VDI Object是一種特殊類型的Data Object)。 DataObject的唯一標識是64位ObjectID, 包括4位對象類型,24位VDI標識,32位VDI本地對象標識,整個系統最多有16M個volume, 每個Volume最多有4G個Data Object。本地對象標識從0開始順序編號, 一般來說 Volume第k個DataObject的ObjectID 等於 (VID標識, k )。

sheepdog基於一致性哈希實現從ObjectID到存儲節點的定位: 每個節點劃分成多個虛擬節點, 虛擬節點和ObjectID一樣,採用64位整數唯一標識, 每個虛擬節點負責一段包含節點ID在內的ObjectID區間。DataObject副本存在ObjectID對應的虛擬節點,及在後續的幾個節點上。 採用一致性哈希的好處是, 無需維護映射表, 節點加入或者失效時受影響的數據較小—隻影響到哈希環上相鄰的兩個節點。 爲了增加數據遷移和恢復的速度, 一致性哈希一般搭配虛擬節點使用, 避免對某一個物理服務器造成很大壓力。

數據存儲
 
 
DataObject單獨存儲成一個文件,路徑是/store_dir/obj/[epoch number]/[object ID]。 普通Object直接讀寫, VDI Object更新時使用journal保證一致性。
Sheepdog支持空間延遲分配, VDI Object中維護一個整數數組data_vdi_id[MAX_DATA_OBJS],該數組第k項記錄第k個Data Object對應VDI標識, 如果data_vdi_id[k]等於零,說明第k個DataObject尚未分配,寫數據時要事先創建DataObject,並設置data_vid_id[k]。 在線快照功能的實現思路是複製VDI對象,源VDI對象代表快照,新創建的VDI對象替換爲源卷, 做完快照之後,源卷的DataObject都成爲只讀對象(通過data_vid_id數組判定),並使用copy-on-write方式更新。


集羣成員關係

sheepdog基於p2p開發框架corosync管理集羣成員關係。 corosync支持全局有序且可靠的消息投遞, 節點加入或者退出集羣作爲一種消息按序投遞到所有節點,每個節點看到的集羣成員關係最終能達到一致。 sheepdog維護集羣成員關係歷史,存儲路徑是/store_dir/epoch/[epoch number], epoch是一個全局遞增的數值,用以描述集羣成員關係的版本, 每當節點加入和退出時,需要增加epoch。 基於epoch可以快速判斷兩個節點是否擁有相同的集羣成員關係視圖。
節點加入分爲兩個階段,第一階段新加入節點向master發送加入請求, 第二階段,master檢查節點是否可以加入,如果可以加入,master廣播節點加入消息到集羣其它節點。  master節點故障時,另外一個節點自動成爲master。 master的負載很低,遷移很快,不會帶來性能瓶頸和可用性問題。
節點退出時,馬上進行處理故障,如果節點假死, 可能造成網絡和磁盤資源浪費。
節點加入和退出都會導致數據遷移,大致流程是:首先從其他節點得到集羣中的ObjectID集合,將屬於本節點的ObjectID保存到/store_dir/obj/[the current epoch]/list, 根據上一個epoch的集羣成員關係確定DataObject的源,發送讀請求到源節點讀取數據,寫入到/store_dir/epoch/[the current epoch]。遷移與讀寫請求不能併發進行,如果DataObject未遷移完成,則讀寫請求被阻塞。爲了降低阻塞時間,  sheepdog優先恢復即將被訪問的存儲對象。

複製和一致性

VDI(也就是volume)同時只能被一個客戶端掛載, 通過corosync全局有序的可靠通訊機制,對VDI進行加鎖,可保證VDI同時只能被一個客戶端訪問。如圖所示,由於消息投遞順序是全局有序的, 最後個lock volume b請求在所有服務器上都會被拒絕。

 
sheepdog實現了強一致性, 每個副本完全保證一致,讀操作可以在任意副本完成,更新操作並行的發往所有副本, 當所有副本都更新成功之後,gateway才告訴客戶端更新操作成功。 I/O請求中帶有gateway的epoch信息,如果副本epoch版本不同於gateway,則請求處理失敗,gateway重試請求直到epoch匹配爲止(僅僅重試出錯節點可能是有問題的, 因爲gateway的epoch可能是錯誤的)。 值的注意是的,gateway故障可能導致部分副本更新成功, sheepdog使用讀時修復機制處理這種不一致性: gateway初次讀取DataObject的時候, 讀取整個DataObject,並覆蓋所有其他副本。 讀時修復機制帶來幾個問題:1)第一次讀取的響應時間非常長;2)gateway需要記錄讀過的ObjectID。

性能

由於使用了一致性哈希,無法對數據分佈做人工調優。IO路徑是“client<->gateway<->多個object manager”, 理想情況下2個網絡來回。

總結

sheepdog架構上最顯著的特點是基於p2p技術實現,無單點故障,將複雜的集羣管理,全局協調一致等分佈式系統中通用複雜問題扔給開源的p2p框架corosync,大大降低了sheepdog本身的複雜度。 同時,正是採用p2p技術, 增加了調試除錯、手工調優的難度。
sheepdog的缺點是:一、讀時修復可能惡化讀響應時間。 二、無法實現在線數據遷移。 爲了保證可用性, 充分利用集羣帶寬加速遷移過程, 在實際應用過程中每臺服務器應該多劃分幾個虛擬節點,  但是多劃分虛擬節點又會導致集羣成員關係數據量增加,以及管理的複雜度提升。 這一點可能限制了集羣的可擴展性。

後記
sheepdog今年發展比較快, 目前已經支持zookeeper和accord(功能類似zookeeper), 能夠支持上千節點, 滿足大部分應用場景需求。集羣管理功能統一抽象爲cluster_driver, 無論zookeeper、accord、還是corosync都以driver形式提供。
本地object cache也是比較不錯的特性, 一方面可以提升讀寫性能, 一方面有效減輕了數據遷移造成的不可用性。 
此外, 本地存儲方面,sheepdog引入了新的設計—
—農場。

多謝sheepdog主要開發者@淘泰來,提供sheepdog最新進展。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章