zoukankan      html  css  js  c++  java
  • 深入云存储系统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)。

  • 相关阅读:
    安装配置ZooKeeper及基本用法
    关于SqlServer数据库数据备份失败的问题
    input 框自动检测输入是否为数字
    nginx配置负载均衡
    nginx日志文件的配置
    nginx的proxy模块详解以及参数
    nginx配置反向代理
    正向代理和反向代理
    Linux建立虚拟ip的方法
    nginx基于ip的虚拟主机
  • 原文地址:https://www.cnblogs.com/yuxc/p/2568584.html
Copyright © 2011-2022 走看看