天天看點

OpenStack_Swift源碼分析——Ring基本原理及一緻性Hash算法1、Ring的基本概念2、Ring基本原理及一緻性Hash算法3 一緻性Hash算法在Ring中的應用參考資料:

Ring是swfit中最重要的元件,用于記錄存儲對象與實體位置之間的映射關系,當使用者需要對Account、Container、Object操作時,就需要查詢對應的Ring檔案(Account、Container、Object都有自己對應的Ring),Ring 使用Region(最近幾個版本中新加入的)、Zone、Device、Partition和Replica來維護這些資訊,對于每一個對象,根據你在部署swift設定的Replica數量,叢集中會存有Replica個對象。部署完成後,相應的Ring檔案也建立,如我上篇部落格中部署示例,在/etc/swift中會存有Ring檔案。

Swift利用一緻性Hash算法建構了一個備援擴充的分布式對象存儲叢集、Swift采用一緻性哈希的主要目的是在改變叢集的device數量時,能夠盡可能少地改變已存在Key和device的映射關系。本文将對一緻性Hash算法進行一些了解性的介紹,關于一緻性Hash算法其他參考資料做具體的了解。swift中一緻性hash算法的具體代碼實作,我将在下邊幾篇部落格中具體介紹。

OpenStack_Swift源碼分析——Ring基本原理及一緻性Hash算法1、Ring的基本概念2、Ring基本原理及一緻性Hash算法3 一緻性Hash算法在Ring中的應用參考資料:

  圖1 環形Ring

如圖所示的,hash算法将value映射成一個0—2**32-1的數值空間。

假設有四個對象、通過hash函數計算每一個對象對應的hash值在環上的分布如下。swift中利用了MD5雜湊演算法,根據對象的名字進行hash的:

hash(object1)=key1;

...........

hash(object4)=key4

OpenStack_Swift源碼分析——Ring基本原理及一緻性Hash算法1、Ring的基本概念2、Ring基本原理及一緻性Hash算法3 一緻性Hash算法在Ring中的應用參考資料:

                                          圖2 object的key值映射到Ring

     對應儲存設備,利用同樣的Hash算法,将value映射到環上,假如有三個裝置device1,device2,device3,他們對應的hash值為dev1,dev2,dev3,其在Ring上的分布如下圖所示。

OpenStack_Swift源碼分析——Ring基本原理及一緻性Hash算法1、Ring的基本概念2、Ring基本原理及一緻性Hash算法3 一緻性Hash算法在Ring中的應用參考資料:

                                           圖3 裝置映射到Ring

現在裝置和對象通過hash算法都映射到了Ring上,那麼如何将對象映射到将要存儲的裝置上呐,在這個環,每一個對象從自己在環上的位置開始,按順時針方向移動,直到遇到一個裝置,則把對象存入到此裝置上,如上圖所示,則key1會映射到dev2,key4映射到dev3,key3,key2映射到dev1。如果增加一個裝置device4,若其hash值為dev5,其在Ring上的映射為

OpenStack_Swift源碼分析——Ring基本原理及一緻性Hash算法1、Ring的基本概念2、Ring基本原理及一緻性Hash算法3 一緻性Hash算法在Ring中的應用參考資料:

 圖4 新增裝置後的Ring

對于新增的裝置device4,環中需要變動的對象隻有key3所對應的對象,它在按順時針找裝置時找到的是device4而不是device1,其他的資料存儲不變,這樣減少了資料的遷移。

 平衡性是hash算法的一個重要名額,平衡性是指對于存儲的所有對象,盡可能均勻的分不到所有的裝置上去。如上圖所示,若是hash算法所算出的對象hash值大多數落在順時針方向的key4到key2之間時,還是按如上方法對象映射裝置,device2就得到很少的對象存儲,以至于其他三個裝置承受了比較大的壓力。顯然這樣設計是不符合實際需求的。引入虛拟節點能很好的解決此問題。

虛拟節點實際上是實際節點在空間中的複制品,一個實際的節點對應若幹個虛拟的節點,加入虛拟節點後,對象的存儲從對象—裝置的映射轉換為對象——虛拟節點——裝置的映射,虛拟節點在空間中按hash值排列。假如虛拟節點為20個,他們均勻的分布在Ring中,每一個裝置對一個的虛拟節點為5個,對象映射裝置時變為如圖所示的過程:

OpenStack_Swift源碼分析——Ring基本原理及一緻性Hash算法1、Ring的基本概念2、Ring基本原理及一緻性Hash算法3 一緻性Hash算法在Ring中的應用參考資料:

圖5 對象—虛拟節點—裝置映射過程

        如果資料在整個叢集中隻有一份,一旦發生故障就可能會造成資料的永久性丢失。是以,需要有備援的副本來保證資料安全。Swift中引入了Replica的概念,其預設值為3,在部署時可也指定具體的本分樹,理論依據主要來源于NWR政策(也叫Quorum協定)。 NWR是一種在分布式存儲系統中用于控制一緻性級别的政策。在Amazon的Dynamo雲存儲系統中,使用了NWR來控制一緻性。其中,N代表同一份資料的Replica的份數,W是更新一個資料對象時需要確定成功更新的份數;R代表讀取一個資料需要讀取的Replica的份數。

公式W+R>N,保證某個資料不被兩個不同的事務同時讀和寫;公式W>N/2保證兩個事務不能并發寫某一個資料。 在分布式系統中,資料的單點是不允許存在的。即線上正常存在的Replica數量為1的情況是非常危險的,因為一旦這個Replica再次出錯,就可能發生資料的永久性錯誤。假如我們把N設定成為2,那麼隻要有一個存儲節點發生損壞,就會有單點的存在,是以N必須大于2。N越高,系統的維護成本和整體成本就越高。工業界通常把N設定為3。

        如果所有的裝置都在一個機架或一個機房中,那麼一旦發生斷電、網絡故障等,都将造成使用者無法通路。是以需要一種機制對機器的實體位置進行隔離,以滿足分區容忍性(CAP理論中的P)。是以,Ring中引入了Zone的概念,把叢集的device配置設定到每個Zone中。在swift 中其中同一個Partition的Replica不能在同一個Zone内,也就是說所有的資料備份應該分布在不同的zone中。在最近版本的swift 中又引入了比Zone更大的概念Region。

在Ring每一個裝置引入了weight概念,weight 的作用就是,假如一個叢集中有的裝置容量為1T,有的為2T、3T,對于不共同的裝置,在存儲資料時,我們肯定希望容量的更大的裝置有更多的被選擇的機會,存儲更多的對象,通過設定weight,存儲容量多的裝置有更大的權重,它也就有了更大的part_wants,那麼就會有更多的虛拟節點和它映射,有更多的虛拟節點映射後,對象就有更大的可能落在它所對應的虛拟節點上,這樣就會有更多的機會得到對象。

在部署swift 時可以設定資料的 最小遷移時間如我上篇部落格swift部署中訓示的為1個小時

swift-ring-builder object.builder create 18 3 1

上兩節介紹了Ring的基本原理以及一緻性hash算法的原理,現在講解Ring是如何使用一緻性hash算法的。在Ring 中有一個replica2part2dev(備份到分區到裝置的映射),replica2part2dev是含有replica(replica為正整數時,)個子list的list,,每一個子list含有2**power個元素。當replica為>1的float值時會有int[replica]+1個子list,其中最後一個list長度為(replica-int[replica])*2**power。比如在2.2.4中部署時訓示的power為18

,replica為3,而每一個元素中存放的是裝置的id。如下所示power為8,replica為3,3個裝置且在三個zone中,經過reassign_parts後得到的replica2part2dev,0,1,2即為裝置的ID。

 [ [2, 2, 0, 0, 2, 0, 0, 2, 1, 0, 0, 0, 2, 0, 1, 2, 2, 0, 1, 0, 0, 0, 1, 2, 1, 1, 1, 2, 0, 2, 2, 0, 1, 0, 2, 1, 1, 0, 2, 0, 2, 1, 0, 1, 1, 0, 1, 1, 0, 2, 0, 1, 1, 1, 2, 2, 0, 2, 1, 1, 2, 2, 2, 2, 1, 1, 0, 2, 1, 1, 0, 2, 0, 0,

1, 1, 1, 2, 0, 0, 0, 1, 0, 2, 0, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 2, 0, 2, 1, 2, 0, 1, 1, 2, 2, 0, 2, 1, 2, 2, 0, 1, 1, 0, 0, 2, 1, 0, 2, 0, 2, 2, 0, 1, 0, 2, 0, 1, 1, 1, 0, 2, 2, 1, 1, 0, 0, 1, 1, 0, 1, 2, 0, 0, 0, 0, 0, 1, 2, 2, 2, 0, 2, 2, 2, 0, 0, 1, 0, 0,

0, 0, 2, 2, 2, 2, 0, 1, 0, 1, 2, 2, 1, 1, 1, 1, 0, 2, 2, 1, 0, 1, 0, 2, 2, 1, 2, 1, 2, 0, 2, 2, 0, 2, 0, 1, 0, 1, 2, 1, 1, 2, 2, 1, 0, 2, 1, 2, 2, 0, 0, 0, 1, 2, 2, 0, 0, 2, 1, 2, 1, 1, 1, 1, 1, 2, 2, 0, 1, 1, 0, 1, 2, 2, 2, 0, 2, 2, 0, 1, 2, 1, 2, 0, 0, 2,

0, 0, 1, 1, 0, 2, 2, 2, 0, 1],

 [1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 1, 2, 1, 1, 0, 1, 1, 2, 0, 2, 1, 2, 0, 1, 2, 0, 0, 0, 1, 0, 1, 1, 2, 2, 1, 0, 2, 2, 0, 2, 1, 2, 1, 0, 0, 1, 2, 2, 2, 0, 2, 2, 0, 0, 1, 0, 2, 1, 2, 2, 1, 1, 0, 0, 0, 2, 1, 0, 2, 2, 2, 1, 1, 1, 0, 0, 2, 0, 2, 2, 2, 0, 2, 0, 2,

2, 0, 0, 0, 0, 2, 2, 1, 0, 0, 0, 1, 1, 0, 1, 2, 0, 2, 1, 1, 1, 0, 0, 0, 0, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 0, 1, 1, 0, 1, 0, 2, 0, 0, 2, 2, 1, 0, 0, 2, 1, 1, 2, 0, 2, 0, 1, 2, 2, 1, 2, 1, 0, 1, 1, 1, 2, 0, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 0, 0, 1, 2, 0, 1, 2, 1,

1, 2, 0, 2, 0, 1, 1, 1, 2, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 2, 0, 2, 0, 2, 0, 0, 2, 2, 1, 1, 0, 2, 1, 2, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 1, 2, 1, 2, 0, 0, 0, 2, 0, 1, 2, 2, 2, 2, 0, 1, 0, 0, 2, 1, 1, 1, 2, 1, 0, 0, 2, 1, 0, 2, 2, 0, 2, 2, 1, 1, 1, 1, 2],

[0, 0, 2, 2, 0, 2, 2, 1, 0, 1, 2, 1, 0, 2, 2, 0, 0, 1, 2, 1, 2, 1, 2, 0, 0, 2, 2, 1, 2, 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 1, 0, 0, 2, 2, 2, 2, 0, 0, 1, 1, 1, 0, 2, 2, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 2, 0, 2, 1, 0, 0, 1, 0, 2, 2, 2, 2, 0, 1, 1, 1, 1, 2, 1, 1, 1, 0,

2, 2, 2, 1, 0, 0, 0, 1, 2, 1, 2, 0, 2, 0, 1, 2, 0, 0, 0, 2, 1, 2, 1, 1, 2, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 2, 2, 2, 1, 1, 2, 2, 0, 1, 0, 1, 2, 0, 2, 2, 0, 2, 1, 2, 0, 1, 1, 2, 1, 2, 2, 0, 0, 0, 1, 1, 0, 0, 2, 2, 0, 2, 2, 1, 1, 0, 1, 1, 0, 1, 2, 2, 0, 0, 0,

0, 2, 0, 2, 2, 0, 0, 0, 2, 2, 2, 0, 1, 2, 0, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 2, 1, 0, 0, 0, 0, 2, 2, 2, 0, 1, 0, 1, 0, 0, 1, 2, 0, 1, 1, 1, 0, 0, 2, 0, 0, 2, 1, 1, 2, 1, 1, 1, 2, 0, 1, 0, 0, 0, 2, 0]]

在得到replica2part2dev後,當對象需要存放時,首先 根據對象的名字account/container/object,計算出其對應的hash值,取hash值的前4個位元組(32位),将其右移32-power位,得到值即為partion的值,從partion中取出replica個對應裝置的id,根據裝置的id得到裝置的其他屬性傳回,裝置的其他屬性中包含了裝置的ip位址,port等資訊,通過http請求,和三個裝置建立連結,因為三個裝置中運作了object-server,他們接收這些請求,将資料存入到裝置中。

如圖所示環的運作機制

OpenStack_Swift源碼分析——Ring基本原理及一緻性Hash算法1、Ring的基本概念2、Ring基本原理及一緻性Hash算法3 一緻性Hash算法在Ring中的應用參考資料:

                                                                          圖6 環的運作機制                                               

1、

2、

繼續閱讀