天天看點

Openck_Swift源碼分析——增加、删除裝置時算法具體的實作過程1 初始添加裝置後、上傳Object的具體流程 2 增加裝置3 删除裝置

前幾篇部落格中,我們講到環的基本原理即具體的實作過程,加入我們在初始建立Ring是執行如下幾條指令:

?swift-ring-builder object.builder create 5 3 1  

?swift-ring-builder object.builder add z1-127.0.0.1:6010/sdb1 100    

?swift-ring-builder object.builder add z2-127.0.0.1:6020/sdb2 100  

?swift-ring-builder object.builder add z3-127.0.0.1:6030/sdb3 100  

?swift-ring-builder object.builder add z4-127.0.0.1:6040/sdb4 100  

swift-ring-builder object.builder rebalance 

上面幾條指令語句中,黑色的為初始建立Ring,綠色部分為向Ring中添加裝置,四個裝置分别位于不同的Zone中,且權重是一樣的。添加完裝置後需要對Ring進行平衡,以便得到replica2part2dev_id。其中關于create add rebalance方法的具體實作過程請參考和兩篇文章。

平衡後得到的replica2part2dev_id 如下圖所示:

Openck_Swift源碼分析——增加、删除裝置時算法具體的實作過程1 初始添加裝置後、上傳Object的具體流程 2 增加裝置3 删除裝置

                                                            圖1 初始平衡Ring後 replica2part2dev_id的映射

上圖中第一行為配置設定編号(在create時輸入的power為5,故為32個分區),三個list分别代表了三個備份。上圖中一個裝置又同時對應多個不同的分區,如下圖所示:

Openck_Swift源碼分析——增加、删除裝置時算法具體的實作過程1 初始添加裝置後、上傳Object的具體流程 2 增加裝置3 删除裝置

                                        圖 2 裝置反映射分區

結合圖1和圖2,一個裝置對應讀個分區,這些在存儲資料時,能更好的解決平衡性問題。

在得到了replica2part2dev_id 後,現在我們向叢集中存入一個對象。其過程如下所示:

Openck_Swift源碼分析——增加、删除裝置時算法具體的實作過程1 初始添加裝置後、上傳Object的具體流程 2 增加裝置3 删除裝置

                                                 圖3 存入一個對象

向叢集中存入對象的流程如下圖所示:

Openck_Swift源碼分析——增加、删除裝置時算法具體的實作過程1 初始添加裝置後、上傳Object的具體流程 2 增加裝置3 删除裝置

                                                                 圖4  存入對象的流程

 存入對象時,首先根據對象的名稱(account/container/object),計算其hash值,的到hash值後,取hash值的前四位元組,且向右移動32-power位得到目前object對應的分區号,如15,得到分區号後,利用分區号到replica2part2dev_id中找到此分區對應的三個裝置的Id,如圖1所示的裝置ID為3 1 4 。根據這三個裝置的ID,到devs中找到具體的裝置,根據裝置的IP,port已經存儲檔案的磁盤所挂載的檔案夾,如sdb1。将資料存如裝置中,資料存入裝置中的目錄結構為srv/node/sdb1/objects/15/hash值後位/hash/.data檔案;其中15為分區号,是以檔案右移動得到的分區号為15的在該裝置中都存入此檔案夾下。

假如系統運作了一段時間後,因需要存儲更多的對象,現需要對系統進行擴充,如下,我們現在增加一個裝置:

swift-ring-builder object.builder add z1-127.0.0.1:6050/sdb5 100

在zone1裡面右增加了一個裝置,其權重仍為100,添加裝置後,每一個裝置的part_wanted值會變化,之前被配置設定的裝置,會因新添加裝置後其會超出其先需要的part_wanted故需要把他們收集回來,配置設定給新增加的裝置,收集的具體算法實作請參見我前幾篇部落格,裡面有詳細的介紹。添加裝置後,重新對Ring進行平衡,平衡後replica2part2dev_id如下圖所示:

Openck_Swift源碼分析——增加、删除裝置時算法具體的實作過程1 初始添加裝置後、上傳Object的具體流程 2 增加裝置3 删除裝置

                  圖5 添加裝置後映射的變化

如上圖(圖中紅線上部分為添加裝置後的新映射,紅線下部分為沒添加裝置前的映射)所示,再添加了裝置後,被收集的分區是從第一個備份(第一行)先開始收集,如果第一個備份都被收集完,則再從第二個備份開始收集。現在隻添加了一個裝置,不會收集到第二個備份的分區,故如綠框中所示後兩個分區中分區所對應的裝置ID都沒有變化。圖中小紅框和小綠框中所示的,第一次平衡和新加入一個裝置後平衡的分區15所對應的裝置Id 其中一個由3變為5。這種變化,資料的一緻性是如何保證的呢?為保證因重新移動平衡而帶來的分區和裝置映射的變動,Replicator在保證資料的一緻性方面起到至關重要的作用。因為Replicator這個守護程序在每一個伺服器上都有運作,故對于裝置3

,它首先根據分區檔案夾的名字獲得分區号然後利用Ring類對外通過的方法,得到此分區對應的裝置,此時它發現新的replica2part2dev_id中沒有了其本身,這時它會把檔案夾名為15及其下的所有檔案都删除。而對于分區15所對應是新裝置5,它是如何得到這些檔案的呢?我們知道,Swift資料的同步是基于推送模式的,也就是4和3 會把其檔案夾下的檔案推送給裝置5。比如裝置4,其Replicator,在獲得分區15所對應的裝置後,和3對比,發現沒有檔案不同,故不推送資料,而發現5下沒有分區15所對應的内容,故其需要将自己分區15所對應的檔案推送給它,裝置3也是同樣的原理。

叢集又運作了一些時間,其中有些裝置,因為運作時間較長,裝置老化,現需要将其從叢集删掉,Swift裝置的删除,不是直接的實體删除,先将其weight設定為0,當其weight變為0後,其他的裝置的part_wanted就好變大,故在rebalnace時需要先把裝置1(加入删除裝置1)所對應的分區都收回,然後再重新配置設定給其他分區。這個過程中replica2part2dev_id變化如下:

Openck_Swift源碼分析——增加、删除裝置時算法具體的實作過程1 初始添加裝置後、上傳Object的具體流程 2 增加裝置3 删除裝置

                                                                        圖6 删除裝置後replica2part2dev_id的變化

如圖6所示(綠線上方為删除裝置後的新映射,綠線和和藍線之間為沒有删除裝置前添加裝置後的分區映射,最底下為起初的映射)裝置1所對應的所有分區都被收集了。而每一個分區所對應的新的裝置都會經過其他兩個裝置,來将他們檔案下的對象推送給新映射的裝置。

繼續閱讀