Sheepdog是開源的分佈式塊存儲項目,具備零配置、Thin-Provision、高可靠、智能節點管理、容量線性擴展、虛擬機感知(底層支 持冷熱遷移和快照、克隆等)、支持計算與存儲混合架構的特色等,可擴展到上千級別的物理節點。開源軟件如QEMU、Libvirt以及Openstack 都很好的集成了對Sheepdog的支持。 node
本系列將手把手讓讀者體驗Sheepdog的各類功能,並解釋背後的工做機制和原理。Sheepdog目前只支持Linux的環境,對文件系統沒有 任何假設。本文以Ubuntu 12.04爲背景,假設GIT、GCC、Autoconf以及Make等常見的編譯環境已經配置好了。讀者能夠根據本身的環境微調命令。
創建環境 linux
# 編譯一個最新的Sheepdog執行文件 $ sudo apt-get install liburcu-dev $ git clone git://github.com/collie/sheepdog.git $ cd sheepdog $ ./autogen.sh; ./configure --disable-corosync $ make; sudo make install # 創建一個3節點的Sheepdog集羣,利用操做系統的IPC和SHM機制來實現節點管理 $ for i in 0 1 2; do sheep /tmp/store$i -c local -z $i -p 700$i;done $ collie cluster format -b plain
編譯後的Sheepdog主要由兩個部分組成,一個是守護程序sheep,一個是集羣管理程序collie。守護程序sheep同時兼備了節點路由和和對象存儲的功能。總體架構以下圖所示:
sheep進程之間經過節點路由(gateway)的邏輯轉發請求,而具體的對象經過對象存儲的邏輯保存在各個節點上,這就把全部節點上的存儲空間聚合起來,造成一個共享的存儲空間。 git
體驗節點的智能管理 github
# 安裝QEMU-kvm $ sudo apt-get install kvm # 下載一個鏡像 $ wget http://wiki.qemu.org/download/linux-0.2.img.bz2 $ bunzip2 linux-0.2.img.bz2 # 將下載的鏡像轉換成sheepdog卷,默認爲raw格式 # Sheepdog支持全部的QEMU格式,好比qcow2,可是默認的raw的性能是最好的 $ kvm-img convert -t directsync linux-0.2.img sheepdog:test $ collie vdi list # 能夠看見已經轉化爲Sheepdog捲了 $ collie node info # 查看節點的信息 $ collie vdi create data 1G # 建立一個1G data卷,一樣能夠經過'collie vdi list'確認下 $ kvm -hda sheepdog:test -hdb sheepdog:data # 啓動鏡像並掛載data # 進入虛擬機後,能夠嘗試dd if=/dev/urandom of=/dev/hdb把data卷寫滿 # 作IO的同時,咱們嘗試加入新的節點。注意到節點的添加和刪除對於IO操做是沒有影響的。 $ sheep /tmp/store3 -c local -z 3 -p 7003 # 加入一個新節點就這麼簡單 $ collie node info # 再次查看一下,集羣的容量動態的增長了,數據也在各節點間自動均衡 $ pkill -f "sheep /tmp/store2" # 模擬節點2掛掉,IO仍是在繼續,數據在從新自動恢復! $ sheep /tmp/store2 -c local -z 2 -p 7002 # 從新加回節點2 # 模擬動態擴容,瞬間加入6個節點 $ for i in `seq 4 9`; do sheep /tmp/store$i -c local -z $i -p 700$i;done # 更多操做請看collie的幫助
智能節點管理背後的機制 算法
在分佈式文件系統中,一個大問題就是如何知道數據存放的位置。在本地文件系統中,一般經過元數據來索引數據具體的位置。由於元數據同數據能夠放到一 塊邏輯卷(分區)上,因此經過簡單的位圖或者樹等數據結構就能夠創建一個完整的(數據,塊號)映射表。而在分佈式文件系統中,一樣須要必定的機制來索引數 據。若是使用元數據來索引數據,因爲這些數據的地址空間遠遠超過了本地硬盤提供的容量,如Hadoop中的HDFS,元數據數據量很是大,須要單獨的節點 或者集羣來存放大量的元數據。而Sheepdog同不少其它開源軟件如GlusterFS同樣基於對象存儲,經過把數據對象與節點都映射到一個巨大的哈希 空間來完全避免元數據。對於塊設備的對象存儲,通俗的說就是把模擬的設備的塊號同對象映射起來,而後分散存儲這些對象,一般是一個對象有多個拷貝,以提升 數據的可靠性。 數組
對象、哈希空間以及節點的關係如何呢?這裏作個簡化的類比,好比,咱們把哈希空間假設爲[0, 300),而後A,B,C節點經過sheep定義的哈希函數計算ID的哈希值分別落在了0, 100, 200的位置,咱們規定順時針向後直到碰見下一個節點的空間都是屬於這個節點的,那麼A,B,C三個節點分別分得的空間爲A[0, 100), B[100, 200), C[200, 300)。這樣經過計算對象的ID咱們獲得一個哈希值,落在哪一個空間就屬於哪個節點,這樣咱們就創建起了一個映射表。當一個節點,好比B掛掉的時候,這 個時候空間在節點中從新分佈,獲得A[0,200),C[200,300)。能夠看到B的數據空間分配到了A中,對於sheep也意味着B的數據將從新恢 復到A中,而對於C是沒有任何影響的。這就是Sheeepdog採用的一致性哈希算法最核心的思想。固然現實中,sheep的實現比這個稍微複雜點,爲了 更好的數據均衡,用到了虛擬節點的概念。 數據結構
有了(對象,節點號)的映射,剩下的事情就是sheep進程之間如何定位然傳遞數據對象。不少開源軟件如GlusterFS是實現 DHT(Distributed Hash Table)來提供查找服務的。DHT最初是爲廣域網上的海量節點設計的,因此實現比較複雜。同時,爲了實現節點的智能化管理,成員列表這個數據結構在所 有的節點中都必須任什麼時候刻徹底一致,若是分散到各個節點中列表視圖一致性維護起來異常複雜。節點之間通訊時分佈式查找也會是一個不小的開銷。 Sheepdog採用了全對稱的結構,也就是每一個節點都保存一個本地的節點數組(視圖),數組的成員表明一個節點,其中包括IP地址等信息。這樣經過節點 ID查找節點位置,只是一個數組的下標解引用操做。找到目標節點對應的IP後,Sheepdog經過TCP的方式以點對點的形式來傳遞數據。 架構
接下來的問題就是Sheepdog如何保證各個節點的視圖一致性。Sheepdog是經過外部成熟的開源軟件來實現可靠的視圖一致性,好比 Corosync和Zookeeper。對於這個視圖,咱們有兩種操做,分別是添加和刪除,對應的是節點的加入和(主動以及被動)退出。好比說咱們有3個 節點組成的集羣(A,B,C),添加節點D進去就是向每個成員包括D發送一個新的視圖(A,B,C,D)。固然這是最簡化的過程,實際中除了一個完整的 新視圖,sheep進程還須要知道誰是新添加的或者離開的節點。若是咱們把視圖抽象爲消息,那麼整個節點變化造成的新視圖就成了一個消息序列。分佈式系統 中維護各個節點看到的消息序列的是一致的問題,是一個歷史悠久而複雜的難題。目前有不少成熟的理論,好比Virtual Synchrony(Corosync採用),Paxos(Zookeeper採用),來保證消息序列的一致性。實現這些消息系統自己的難度已經大大超過 了Sheepdog本身。正是站在這些巨人的肩膀上,纔有了Sheepdog簡單而智能的節點管理。 dom
特別的指出,Sheepdog有內在的請求重試機制,因此節點變化的時候,不少無效的請求會根據新的視圖進行重試,直到成功爲止。因此節點的變化對於虛擬機來講,徹底是透明的。對於IO路徑會在之後的章節進行描述。 分佈式