周末無(wú)事,故翻譯sheepdog design.
原文地址: https://github.com/collie/sheepdog/wiki/Sheepdog-Design
Sheepdog 設(shè)計(jì)
Sheeepdog采用完全對(duì)稱的結(jié)構(gòu),沒(méi)有類似元數(shù)據(jù)服務(wù)的中心節(jié)點(diǎn). 這種設(shè)計(jì)有以下的特點(diǎn).
1) 性能于容量的線性的可擴(kuò)展性.
當(dāng)需要提升性能或容量時(shí),只需向集群中增加新的機(jī)器便能使Sheeepdog線性成長(zhǎng).
2) 沒(méi)有單點(diǎn)故障
即使某臺(tái)機(jī)器發(fā)生故障,依然可以通過(guò)其他機(jī)器訪問(wèn)數(shù)據(jù).
3) 容易管理
不需要配置機(jī)器角色,當(dāng)管理員在新增的機(jī)器開(kāi)啟Sheepdog守護(hù)進(jìn)程時(shí), Sheepdog會(huì)自動(dòng)檢測(cè)新加入的機(jī)器并配置它成為存儲(chǔ)系統(tǒng)中的一員.
結(jié)構(gòu)概述


Sheepdog是一個(gè)分布式存儲(chǔ)系統(tǒng).為Sheepdog客戶端(QEMU的塊驅(qū)動(dòng)程序)提供對(duì)象存儲(chǔ)(類似于簡(jiǎn)單的鍵值對(duì)). 接下來(lái)幾章將更加詳細(xì)的闡述Sheepdog各個(gè)部分.
1) 對(duì)象存儲(chǔ)(Object對(duì)象存儲(chǔ)(Object Storage)
2) )
Sheepdog不同于一般的文件系統(tǒng), Sheepdog進(jìn)程為QEMU(Sheepdog進(jìn)程名)創(chuàng)建一個(gè)分布式對(duì)象存儲(chǔ)系統(tǒng),它可以存儲(chǔ)”對(duì)象”.這里的”對(duì)象”數(shù)據(jù)大小可變,并有唯一的標(biāo)識(shí),通過(guò)標(biāo)識(shí)可以進(jìn)行讀/寫(xiě)/創(chuàng)建/刪除操作.對(duì)象存儲(chǔ)組成”網(wǎng)關(guān)”和”對(duì)象管理器”.
3) 網(wǎng)關(guān)(getway)
Getway接收QEMU塊驅(qū)動(dòng)的I/O請(qǐng)求(對(duì)象id,偏移,長(zhǎng)度和操作類型),通過(guò)一直散列算法獲得目標(biāo)節(jié)點(diǎn),然后轉(zhuǎn)發(fā)I/O請(qǐng)求至該節(jié)點(diǎn).
4) 對(duì)象管理器(Object manager)
對(duì)象管理器接收getway轉(zhuǎn)發(fā)過(guò)來(lái)的I/O請(qǐng)求,然后對(duì)磁盤(pán)執(zhí)行讀/寫(xiě)操作.
5) 集群管理器(Cluster manager)
集群管理器管理管理節(jié)點(diǎn)成員(探測(cè)失敗/新增節(jié)點(diǎn)并報(bào)告節(jié)點(diǎn)成員的變化),以及一些需要節(jié)點(diǎn)一致的操作(vdi 創(chuàng)建, 快照 vdi等).當(dāng)前集群管理器使用corosync集群引擎.
6) QEMU 塊驅(qū)動(dòng)
QEMU塊驅(qū)動(dòng)把VM image分為固定大小(默認(rèn)4M),并通過(guò)其getway存儲(chǔ)到對(duì)象存儲(chǔ)中
對(duì)象存儲(chǔ)(Object Storage)
每個(gè)對(duì)象使用一個(gè)64bit的整數(shù)作為全局標(biāo)識(shí),并在多臺(tái)機(jī)器存有備份,QEMU塊驅(qū)動(dòng)并不關(guān)心存儲(chǔ)的位置,對(duì)象存儲(chǔ)系統(tǒng)負(fù)責(zé)管理存儲(chǔ)的位置.
對(duì)象類型(object types)
Sheepdog的對(duì)象分為以下四種:
1) 數(shù)據(jù)類型(data object)
它包括虛擬磁盤(pán)映射的真實(shí)數(shù)據(jù),虛擬磁盤(pán)映射分為固定大小的數(shù)據(jù)對(duì)象, Sheepdog客戶端訪問(wèn)這個(gè)對(duì)象.
2) vdi object
它包括虛擬磁盤(pán)映射的元數(shù)據(jù)(例:映射名,磁盤(pán)大小,創(chuàng)建時(shí)間,vdi的數(shù)據(jù)對(duì)象ID等).
3) vmstate object
它存儲(chǔ)運(yùn)行中的VM狀態(tài)映射.管理員通過(guò)它獲取實(shí)時(shí)快照信息.
4) vdi attr object
使用它存儲(chǔ)各個(gè)vdi的屬性,屬性為鍵值對(duì)類型,類似于普通文件的擴(kuò)展信息.
對(duì)象ID規(guī)則(object ID rules)
1) 0 - 31 (32 bits): 對(duì)象類型詳細(xì)信息
2) 32 - 55 (24 bits): vdi id
3) 56 - 59 ( 4 bits): 預(yù)留
4) 60 - 63 ( 4 bits): 對(duì)象類型標(biāo)識(shí)符
每個(gè)VDI有一個(gè)全局唯一的ID(vdi id), 通過(guò)VDI名求得的散列值,低三十二位使用如下:
對(duì)象類型 | 低32位的作用 |
數(shù)據(jù)類型 | 虛擬磁盤(pán)映射的索引號(hào) |
Vdi對(duì)象 | 未使用(填0) |
Vm狀態(tài)對(duì)象 | Vm狀態(tài)映射索引 |
Vdi屬性對(duì)象 | 鍵名的散列值 |
對(duì)象格式(object format)
1) 數(shù)據(jù)對(duì)象
虛擬磁盤(pán)映射的塊
2) Vdi對(duì)象
1 struct sheepdog_inode {
2 char name[SD_MAX_VDI_LEN]; /* the name of this VDI*/
3 char tag[SD_MAX_VDI_TAG_LEN]; /* the snapshot tag name */
4 uint64_t ctime; /* creation time of this VDI */
5 uint64_t snap_ctime; /* the time snapshot is taken */
6 uint64_t vm_clock_nsec; /* vm clock (used for live snapshot) */
7 uint64_t vdi_size; /* the size of VDI */
8 uint64_t vm_state_size; /* the size of vm state (used for live snapshot) */
9 uint16_t copy_policy; /* reserved */
10 uint8_t nr_copies; /* the number of object redundancy */
11 uint8_t block_size_shift; /* info about the size of the data object */
12 uint32_t snap_id; /* the snapshot id */
13 uint32_t vdi_id; /* the vdi id */
14 uint32_t parent_vdi_id; /* the parent snapshot vdi id of this VDI */
15 uint32_t child_vdi_id[MAX_CHILDREN]; /* the children VDIs of this VDI */
16 uint32_t data_vdi_id[MAX_DATA_OBJS]; /* the data object IDs this VDI contains*/
17 };
3) Vm狀態(tài)對(duì)象
Vm狀態(tài)映射塊
4) Vdi屬性對(duì)象
前SD_MAX_VDI_ATTR_KEY_LEN位(256位)為屬性的鍵名,余下的是屬性指.
只讀/可寫(xiě)對(duì)象(read-only/writable objects)
從如何訪問(wèn)對(duì)象的角度,我們還可以把Sheepdog對(duì)象分為以下兩類.
1) 只讀對(duì)象(例:VDI快照數(shù)據(jù)對(duì)象)
只允許一個(gè)VM對(duì)其讀寫(xiě),其他vm無(wú)法訪問(wèn)
2) 可寫(xiě)對(duì)象
不允許任何VM對(duì)其寫(xiě),所有VM都可讀
其他功能(other features)
Sheepdog對(duì)象存儲(chǔ)可接收正在寫(xiě)時(shí)復(fù)制(copy-on-write)的請(qǐng)求.當(dāng)一個(gè)客戶端發(fā)送一個(gè)創(chuàng)建和寫(xiě)的請(qǐng)求時(shí),同時(shí)可以指定基本對(duì)象(CoW操作的來(lái)源),這用于快照和克隆操作.
網(wǎng)關(guān)(Gateway)
對(duì)象存在哪(where to store objects)
Sheepdog使用一致性哈希算法決定存放對(duì)象的位置,一致性哈希算法提供哈希表,而且增加或介紹節(jié)點(diǎn)不回顯著的改變對(duì)象映射,通過(guò)哈希表能使I/O負(fù)載均衡.
副本(replication)
Sheepdog的數(shù)據(jù)副本很簡(jiǎn)單,我們假設(shè)只有一個(gè)寫(xiě),所以寫(xiě)沖突不會(huì)發(fā)生,客戶端可以并行發(fā)生請(qǐng)求到目標(biāo)節(jié)點(diǎn),發(fā)生讀請(qǐng)求到一個(gè)目標(biāo)節(jié)點(diǎn)如果客戶端自己處理I/O請(qǐng)求順序.
寫(xiě)I/O流(write I/O flow)
Getway使用一致性哈希算法計(jì)算目標(biāo)節(jié)點(diǎn)并發(fā)送寫(xiě)請(qǐng)求到所有目標(biāo)節(jié)點(diǎn),只有所有副本均更新成功寫(xiě)請(qǐng)求才會(huì)成功,這是因?yàn)槿绻粋€(gè)副本未更新,getway有可能從未更新的節(jié)點(diǎn)讀取舊數(shù)據(jù).
讀I/O流(read I/O flow)
Getway使用一致性哈希算法計(jì)算目標(biāo)節(jié)點(diǎn),并發(fā)送讀請(qǐng)求到一個(gè)目標(biāo)節(jié)點(diǎn).
1) 修復(fù)對(duì)象一致性
當(dāng)某節(jié)點(diǎn)在轉(zhuǎn)發(fā)I/O請(qǐng)求時(shí)crash,有可能破壞副本的一致性,所以當(dāng)getway第一次讀取對(duì)象時(shí)會(huì)試圖修復(fù)其一致性,從一節(jié)點(diǎn)讀取整個(gè)對(duì)象并用它覆蓋所有副本.
重試I/O請(qǐng)求(retrying I/O requests)
Sheepdog存儲(chǔ)所有成員節(jié)點(diǎn)的歷史信息,我們把歷史版本號(hào)叫做”epoch”(詳見(jiàn)章節(jié)’對(duì)象恢復(fù)’). 如果getway轉(zhuǎn)發(fā)I/O請(qǐng)求至目標(biāo)節(jié)點(diǎn)并且getway與目標(biāo)節(jié)點(diǎn)epoch號(hào)不相符,I/O請(qǐng)求失敗且getway重試請(qǐng)求直到epcho號(hào)相符,這就需要保持副本強(qiáng)一致性.
I/O重試也可能發(fā)生在目標(biāo)節(jié)點(diǎn)掛了導(dǎo)致無(wú)法完成I/O操作.
對(duì)象管理器(Object Manager)
對(duì)象管理器把對(duì)象存儲(chǔ)到本地磁盤(pán),當(dāng)前把每個(gè)對(duì)象存儲(chǔ)為一個(gè)文件,這中方法簡(jiǎn)單.我們也可以使用DBMS(例: BerkeleyDB, Tokyo Cabinet等) 作為對(duì)象存儲(chǔ)器,但還不支持.
路徑命名規(guī)則(path name rule)
對(duì)象存儲(chǔ)成如下路徑:
/store_dir/obj/[epoch number]/[object ID]
所有對(duì)象文件有一個(gè)擴(kuò)展屬性: 副本數(shù)(sheepdog.copies),
寫(xiě)日志(write journaling)
當(dāng)sheep進(jìn)程在寫(xiě)操作過(guò)程中失敗,對(duì)象有可能至少部分更新,一般情況這不會(huì)有問(wèn)題,因?yàn)槿绻?/span>VM未接收成功消息,不保證所寫(xiě)部分的內(nèi)容.然而對(duì)于vdi對(duì)象,我們必須整體更新或整體未更新,因?yàn)槿绻?/span>vdi對(duì)象只是部分更新,VDI的元數(shù)據(jù)有可能被破壞. 為例防止這個(gè)問(wèn)題,我們使用日志記錄對(duì)vdi對(duì)象的寫(xiě)操作. 日志過(guò)程很簡(jiǎn)單:
1) 創(chuàng)建日志文件"/store_dir/journal/[epoch]/[vdi object id]"
2) 首先寫(xiě)數(shù)據(jù)到日志文件
3) 寫(xiě)一個(gè)數(shù)據(jù)到vdi對(duì)象
4) 刪除日志文件
集群管理器(Cluster Manager)
大多情況, Sheepdo客戶端單獨(dú)訪問(wèn)它們的映射因?yàn)槲覀儾辉试S兩個(gè)客戶端同時(shí)訪問(wèn)一個(gè)映射,但是某些VDI操作(例:克隆VDI,創(chuàng)建VDI)必須做,因?yàn)檫@些操作更新全局信息,我們使用Corosync集群引擎完成而不是中心服務(wù)器.
我們將擴(kuò)展Sheepdog以支持其他集群管理系統(tǒng).
本章正在編輯
QEMU 塊驅(qū)動(dòng)(QEMU Block Driver)

Sheepdog卷被分為4M的數(shù)據(jù)對(duì)象,剛創(chuàng)建的對(duì)象未分配,也就是說(shuō),只有寫(xiě)對(duì)象被分配.
Open
首先QEMU塊驅(qū)動(dòng)通過(guò)getway的bdrv_open()從對(duì)象存儲(chǔ)讀取vdi
讀/寫(xiě)(read/write)
塊驅(qū)動(dòng)通過(guò)請(qǐng)求的部分偏移量和大小計(jì)算數(shù)據(jù)對(duì)象id, 并向getway發(fā)送請(qǐng)求. 當(dāng)塊驅(qū)動(dòng)發(fā)送寫(xiě)請(qǐng)求到那些不屬于其當(dāng)前vdi的數(shù)據(jù)對(duì)象是,塊驅(qū)動(dòng)發(fā)送CoW請(qǐng)求分配一個(gè)新的數(shù)據(jù)對(duì)象.
寫(xiě)入快照vdi(write to snapshot vdi)
我們可以把快照VDI附加到QEMU, 當(dāng)塊驅(qū)動(dòng)第一次發(fā)送寫(xiě)請(qǐng)求到快照VDI, 塊驅(qū)動(dòng)創(chuàng)建一個(gè)新的可寫(xiě)VDI作為子快照,并發(fā)送請(qǐng)求到新的VDI.
VDI操作(VDI Operations)
查找(lookup)
當(dāng)查找VDI對(duì)象時(shí):
1) 通過(guò)求vdi名的哈希值得到vdi id
2) 通過(guò)vdi id計(jì)算di對(duì)象
3) 發(fā)送讀請(qǐng)求到vdi對(duì)象
4) 如果此vdi不是請(qǐng)求的那個(gè),增加vdi id并重試發(fā)送讀請(qǐng)求
快照,克隆(snapshot, cloning)
快照可克隆操作很簡(jiǎn)單,
1) 讀目標(biāo)VDI
2) 創(chuàng)建一個(gè)與目標(biāo)一樣的新VDI
3) 把新vdi的‘'parent_vdi_id''設(shè)為目標(biāo)VDI的id
4) 設(shè)置目標(biāo)vdi的''child_vdi_id''為新vdi的id.
5) 設(shè)置目標(biāo)vdi的''snap_ctime''為當(dāng)前時(shí)間, 新vdi變?yōu)楫?dāng)前vdi對(duì)象
刪除(delete)
TODO:當(dāng)前,回收未使用的數(shù)據(jù)對(duì)象是不會(huì)被執(zhí)行,直到所有相關(guān)VDI對(duì)象(相關(guān)的快照VDI和克隆VDI)被刪除.
所有相關(guān)VDI被刪除后, Sheepdog刪除所有此VDI的數(shù)據(jù)對(duì)象,設(shè)置此VDI對(duì)象名為空字符串.
對(duì)象恢復(fù)(Object Recovery)
epoch
Sheepdog把成員節(jié)點(diǎn)歷史存儲(chǔ)在存儲(chǔ)路徑, 路徑名如下:
/store_dir/epoch/[epoch number]
每個(gè)文件包括節(jié)點(diǎn)在epoch的列表信息(IP地址,端口,虛擬節(jié)點(diǎn)個(gè)數(shù)).
恢復(fù)過(guò)程(recovery process)
1) 從所有節(jié)點(diǎn)接收存儲(chǔ)對(duì)象ID
2) 計(jì)算選擇那個(gè)對(duì)象
3) 創(chuàng)建對(duì)象ID list文件"/store_dir/obj/[the current epoch]/list"
4) 發(fā)送一個(gè)讀請(qǐng)求以獲取id存在于list文件的對(duì)象. 這個(gè)請(qǐng)求被發(fā)送到包含前一次epoch的對(duì)象的節(jié)點(diǎn).( The requests are sent to the node which had the object at the previous epoch.)
5) 把對(duì)象存到當(dāng)前epoch路徑.
沖突的I/O(conflicts I/Os)
如果QEMU發(fā)送I/O請(qǐng)求到某些未恢復(fù)的對(duì)象, Sheepdog阻塞此請(qǐng)求并優(yōu)先恢復(fù)對(duì)象.
協(xié)議(Protocol)
Sheepdog的所有請(qǐng)求包含固定大小的頭部(48位)和固定大小的數(shù)據(jù)部分,頭部包括協(xié)議版本,操作碼,epoch號(hào),數(shù)據(jù)長(zhǎng)度等.
between sheep and QEMU
操作碼 | 描述 |
SD_OP_CREATE_AND_WRITE_OBJ | 發(fā)送請(qǐng)求以創(chuàng)建新對(duì)象并寫(xiě)入數(shù)據(jù),如果對(duì)象存在,操作失敗 |
SD_OP_READ_OBJ | 讀取對(duì)象中的數(shù)據(jù) |
SD_OP_WRITE_OBJ | 向?qū)ο髮?xiě)入數(shù)據(jù),如果對(duì)象不存在,失敗 |
SD_OP_NEW_VDI | 發(fā)送vdi名到對(duì)象存儲(chǔ)并創(chuàng)建新vdi對(duì)象, 返回應(yīng)答vdi的唯一的vdi id |
SD_OP_LOCK_VDI | 與SD_OP_GET_VDI_INFO相同 |
SD_OP_RELEASE_VDI | 未使用 |
SD_OP_GET_VDI_INFO | 獲取vdi信息(例:vdi id) |
SD_OP_READ_VDIS | 獲取已經(jīng)使用的vdi id |
between sheep and collie
操作碼 | 描述 |
SD_OP_DEL_VDI | 刪除VDI |
SD_OP_GET_NODE_LIST | 獲取sheepdog的節(jié)點(diǎn)列表 |
SD_OP_GET_VM_LIST | 未使用 |
SD_OP_MAKE_FS | 創(chuàng)建sheepdog集群 |
SD_OP_SHUTDOWN | 停止sheepdog集群 |
SD_OP_STAT_SHEEP | 獲取本地磁盤(pán)使用量 |
SD_OP_STAT_CLUSTER | 獲取sheepdog集群信息 |
SD_OP_KILL_NODE | 退出sheep守護(hù)進(jìn)程 |
SD_OP_GET_VDI_ATTR | 獲取vdi屬性對(duì)象id |
between sheeps
操作碼 | 描述 |
SD_OP_REMOVE_OBJ | 刪除對(duì)象 |
SD_OP_GET_OBJ_LIST | 獲取對(duì)象id列表,并存儲(chǔ)到目標(biāo)節(jié)點(diǎn) |