StackDoc

人人IT網-StackDoc

當前位置: 主頁 > 編程語言 > Python >

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

時間:2012-06-28 23:45來源:Internet 作者:Internet 點擊:
  在上一篇深入雲存儲系統Swift核心組件:Ring實現原理剖析中,我們分析了Ring的設計原理,深入探討了Swift如何通過Ring組件來實現冗餘的、可擴展的目的。本文旨在分析在實際swift的運

  在上一篇深入雲存儲系統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)。

頂一下
(0)
0%
踩一下
(0)
0%
------分隔線----------------------------
發表評論
請自覺遵守互聯網相關的政策法規,嚴禁發布色情、暴力、反動的言論。
評價:
表情:
驗證碼:點擊我更換圖片
欄目列表
推薦內容