深入雲存儲系統Swift核心組件:Ring數據結構及構建、重平衡操作



  在上一篇深入雲存儲系統Swift核心組件:Ring實現原理剖析中,我們分析了Ring的設計原理,深入探討了Swift如何通過Ring組件來實現冗余的、可擴展的目的。本文旨在分析在實際swift的運行中,如何來構建Ring文件。

Ring數據結構

  Ring 的數據結構由三個頂層域構成,其中

  1. List of Devices,表示集群中設備的列表
  2. Partition Assignment List表示partitiondevice的指派;
  3. Partition Shift Value,表示計算數據hash的移位量

1.List of Devices

  設備列表在Ring類內部被稱為devs。在設備列表中的每一項是帶有以下鍵的字典:

                                          表1:Devs鍵值說明

id

integer

device列表中的索引

zone

integer

設備所在的zone

weight

float

device與其他device的相對權重。這常常直接與device和其它device的磁盤空間數量的比有關

ip

string

device的服務器IP地址

port

int

服務器進程所使用的TCP端口用來提供該設備的服務請求

device

string

 服務器上device的磁盤名稱。例如:sdb1

meta

string

存儲設備額外信息的通用字段。該信息並不直接被服務器進程使用,但是在調試時會派上用場。例如,安裝的日期和時間和硬件生產商可以存儲在這。

 

2.Partition Assignment List

  用於存放每個replicadevice間映射關系。在Ring類內部被稱為_replica2part2dev_id,列表中含有replica數量(3)array(I),array(I)的長度等於ringpartition數量,在array(I)中的每個值為List of Devices中的索引id

3.Partition Shift Value

  Partition Shift Value在Ring類內部稱為_part_shift。該值用於轉換一個MD5 hash值來計算對於哈希值數據所在的partition使用hash值的前4個字節用於計算。例如,為了計算路徑/account/container/object的虛節點,Python代碼如下:

partition = unpack_from('>I',md5('/account/container/object').digest())[0] >> self._part_shift

 

  其中>表示big-endian byte order,I表示長度為4 byte unsigned int

 

  舉例:我們以SAIO安裝下的ring文件為例,使用python讀取/etc/swift/object.ring.gz存放的數據,獲得的是以devs、 part_shift、 replica2part2dev_id keydict類數據,其中:

 devs=

[{'device': 'sdb1',

  'id': 0,

  'ip': '127.0.0.1',

  'meta': '',

  'port': 6010,

  'weight': 1.0,

  'zone': 1},

{'device': 'sdb2',

  'id': 1,

  'ip': '127.0.0.1',

  'meta': '',

  'port': 6020,

  'weight': 1.0,

  'zone': 2},

{'device': 'sdb3',

  'id': 2,

  'ip': '127.0.0.1',

  'meta': '',

  'port': 6030,

  'weight': 1.0,

  'zone': 3},

{'device': 'sdb4',

  'id': 3,

  'ip': '127.0.0.1',

  'meta': '',

  'port': 6040,

  'weight': 1.0,

  'zone': 4}]

 

part_shift=4

replica2part2dev_id=[array(I, [3, 2...]) array(I, [0, 1...]), array(I, [1, 3...])]

 

構建Ring文件

 

  假設我們配置了一個4個node組成的集群,分別為node0、node1、node2、node3,在這個集群中,我們為4個存儲節點配置了2^18個partition,平均每個存儲節點分配65536個partition。

  需要使用swift-ring-bulider命令來構建ring文件,關於swift-ring-builder命令的詳細用法,在shell下直接敲該命令即可獲得提示。這里只涉及構建新Ring文件的方法,需要用到兩個相關選項:

  1. 構建相關的builder文件:swift-ring-builder <builder_file> create <part_power> <replicas><min_part_hours>
  2. 添加node到builder文件:swift-ring-builder <builder_file> add  z<zone>-<ip>:<port>/<device_name>_<meta> <weight>

例如,該集群目前ring的配置如下:

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

swift-ring-builder account.builder add z1-192.168.1.50:6002/sdc 100

swift-ring-builder account.builder add z2-192.168.1.51:6002/sdc 100

swift-ring-builder account.builder add z3-192.168.1.52:6002/sdc 100

swift-ring-builder account.builder add z4-192.168.1.54:6002/sdc 100

swift-ring-builder account.builder rebalance

 

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

swift-ring-builder container.builder add z1-192.168.1.50:6001/sdc 100

swift-ring-builder container.builder add z2-192.168.1.51:6001/sdc 100

swift-ring-builder container.builder add z3-192.168.1.52:6001/sdc 100

swift-ring-builder container.builder add z4-192.168.1.54:6001/sdc 100

swift-ring-builder container.builder rebalance

 

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

swift-ring-builder object.builder add z1-192.168.1.50:6000/sdc 100

swift-ring-builder object.builder add z2-192.168.1.51:6000/sdc 100

swift-ring-builder object.builder add z3-192.168.1.52:6000/sdc 100

swift-ring-builder object.builder add z4-192.168.1.54:6000/sdc 100

swift-ring-builder object.builder rebalance

 

Ring的Rebalance機制

  當集群中發生存儲節點宕機、新增(刪)存儲節點、新增(刪)zone等必須改變partition和node間的映射關系時,就需要對Ring文件進行更新,也就是在swift文檔中見到的rebalance一詞。

  在基於原有的Ring構造Ring時,swift-ring-builder首先要重新計算每個設備所需的partition數量。然后,將需要重新分配的partition收集起來。取消分配被移除設備partition並把這些partition添加到收集列表。從擁有比當前所需的partition數多的設備上隨機地取消分配多出的partition並添加到收集列表中。最后,收集列表中的partition使用與初始化分配類似的方法重新分配。

  在本地執行swift-ring-builder命令行來生成新的ring文件,然后把這些文件復制到集群的每個節點的/etc/swift目錄中,所有需要使用ringserver進程會每15秒(默認值)檢查一遍ring文件的修改時間mtime,如果發現和內存中的不一致,則重新加載ring文件到內存中去。

  舉例說明

  現在再增加一台存儲節點node4並作為zone5,使用相同權重的devcie。那么每個存儲節點上的partition數是52428.8。需要從每台存儲節點上隨機地移除13107.2partition到收集列表,然后再重新分配這些parttionnode4上。當有partitionreplica被重分配時,重分配的時間將被記錄。在RingBuilder使用min_part_hours來限制在規定時間內,同一個partition不會被移動兩次。

  由於收集用來重新分配partition是基於隨機rebalacne進程並不能一次就可以完美地重平衡ring。為了達到一個較為平衡的ringrebalacne進程被重復執行直到接近完美(小於1%)或者當rebalacne的提升達不到最小值1%

  具體的操作如下,首先移除舊的ring文件:

rm -f account.builder account.ring.gz backups/account.builder backups/account.ring.gz

.......

 

  然后,重新平衡ring文件:

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

swift-ring-builder account.builder add z1-192.168.1.50:6002/sdc 100

swift-ring-builder account.builder add z2-192.168.1.51:6002/sdc 100

swift-ring-builder account.builder add z3-192.168.1.52:6002/sdc 100

swift-ring-builder account.builder add z4-192.168.1.54:6002/sdc 100

swift-ring-builder account.builder add z5-192.168.1.53:6002/sdc 100

swift-ring-builder account.builder rebalance

 

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

swift-ring-builder container.builder add z1-192.168.1.50:6001/sdc 100

swift-ring-builder container.builder add z2-192.168.1.51:6001/sdc 100

swift-ring-builder container.builder add z3-192.168.1.52:6001/sdc 100

swift-ring-builder container.builder add z4-192.168.1.54:6001/sdc 100

swift-ring-builder container.builder add z5-192.168.1.53:6001/sdc 100

swift-ring-builder container.builder rebalance

 

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

swift-ring-builder object.builder add z1-192.168.1.50:6000/sdc 100

swift-ring-builder object.builder add z2-192.168.1.51:6000/sdc 100

swift-ring-builder object.builder add z3-192.168.1.52:6000/sdc 100

swift-ring-builder object.builder add z4-192.168.1.54:6000/sdc 100

swift-ring-builder object.builder add z5-192.168.1.53:6000/sdc 100

swift-ring-builder object.builder rebalance

 

  最后,復制account.ring.gzcontainer.ring.gzobject.ring.gz到集群的各節點的/etc/swift目錄下。這樣我們就完成了Ring的重平衡(rebalance)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM