本文共 2592 字,大约阅读时间需要 8 分钟。
Ring的数据结构
Ring具体映射过程
- 使用对象的层次结构account/container/object计算出的Key作移位运算后得出Partition的编号,然后在replica2part2dev_id表中查得对应的三备份的Device ID,最后到devs中查得对应Device ID的IP及端口号
构建Ring
Swift使用swift-ring-builder工具构建一个Ring,可分为三个步骤:
- 创建Ring文件
swift-ring-builder <build_file> create <part_power> <replicas> <min_part_hours>
build_file是build的文件名,2^part_power是Partition的个数,replicas是副本的个数,min_part_hours单位为小时,一般设置24小时,表示某个Partition在移动后必须等待指定的时间才能再次移动 - 添加设备到Ring中
swift-ring-builder <build_file> add [r<region>] z<zone>-<ip>:<port>/<device_name>_<meta> <weight>
region和zone表示Region和Zone的编号,ip:port表示设备所在节点的IP地址及端口号,device_name是该设备在该节点的名次(如sdb1),meta是该设备的元数据,weight是该设备的权重 - 分配Partition
swift-ring-builder <build_file> rebalance rebalance操作会根据builder file的定义将Partition分配到不同的设备。在rebalance之后需要将生成的Ring文件复制到所有运行相应服务(Account, Container或Object)的节点上,然后用该Ring文件作为参数启动相应的服务
源码调用过程:
swift-ring-builder工具的源码入口是bin/swift-ring-builder,这个脚本仅仅是对swift.cli.ringbuilder模块的封装,直接调用了swift.cli.ringbuilder的main函数
- 首先调用swift.cli.ringbuilder.Commands类的create()函数完成builder文件的构建
- 其次调用swift.cli.ringbuilder.Commands类的add()函数完成设备的添加并保存到builder文件中
- 最后调用swift.cli.ringbuilder.Commands类的rebalance()函数实现balance并最终生成ring(.gz)文件
builder的数据结构:
ring(.gz)文件的数据结构上述已分析,builder的数据结构与ring的数据结构稍有差异,包括:
{'part_power': self.part_power, 'replicas': self.replicas, 'min_part_hours': self.min_part_hours, 'devs_changed': self.devs_changed, 'overload': self.overload, '_replica2part2dev': self._replica2part2dev, '_last_part_moves_epoch': self._last_part_moves_epoch, '_last_part_moves': self._last_part_moves, '_last_part_gather_start': self._last_part_gather_start, '_dispersion_graph': self._dispersion_graph, 'dispersion': self.dispersion, '_remove_devs': self._remove_devs} builder(.builder)文件和ring(.gz)文件的持久化方式
builder(.builder)文件的持久化方式
- 在调用swift.cli.ringbuilder.Commands类的create()函数内部,通过调用的是save()函数将Ring的初始化信息保存到builder(.builder)文件中去
- save()函数内部首先将Ring的初始化信息转化成builder数据结构构成的dict对象,然后采用pickle序列化的方式将dict对象持久化到builder(.builder)文件中,采用的是更高效的新的二进制协议
ring(.gz)文件的持久化方式
- 调用swift.common.ring.Ring类的save()函数实现ring(.gz)文件的持久化
- save()函数内部首先将ring的数据结构转化成得对应的dict对象,再将其转化成JSON形式,然后将这些数据封装成字符串后写入到Gzip压缩文件中,最后flash
转载地址:http://tmbii.baihongyu.com/