Swift源码解析之创建Ring文件
2018-03-30 18:39
465 查看
通过setup.cfg文件可以知道swift-ring-builder工具的源码入口位于/bin/swift-ring-builder脚本,这个脚本仅仅是对swift.cli.ringbuilder模块的封装,直接调用了swift.cli.ringbuilder中的main函数。
def main(arguments=None): if len(argv) == 2: command = "default" else: command = argv[2] if argv[0].endswith('-safe'): try: with lock_parent_directory(abspath(argv[1]), 15): Commands.__dict__.get(command, Commands.unknown.im_func)() except exceptions.LockTimeout: print "Ring/builder dir currently locked." exit(2) else: #调动Commands类的名为"command"函数,如果该函数不存在则调用 #Commands类的unknown()函数,对于Ring的创建,"command"为create Commands.__dict__.get(command, Commands.unknown.im_func)()完成一定的参数解析工作后,最终使用swift.cli.ringbuilder.Commands类的create()函数去完成Ring的创建。
class Commands(object): def create(): """ swift-ring-builder <builder_file> create <part_power> <replicas> <min_part_hours> Creates <builder_file> with 2^<part_power> partitions and <replicas>. <min_part_hours> is number of hours to restrict moving a partition more than once. """ if len(argv) < 6: print Commands.create.__doc__.strip() exit(EXIT_ERROR) #创建RingBuilder对象实例 builder = RingBuilder(int(argv[3]), float(argv[4]), int(argv[5])) #为builder文件创建一个备份目录,该目录下会备份builder文件 backup_dir = pathjoin(dirname(argv[1]), 'backups') try: mkdir(backup_dir) except OSError as err: if err.errno != EEXIST: raise #将Ring的初始化信息保存到备份文件中去 builder.save(pathjoin(backup_dir, '%d.' % time() + basename(argv[1]))) #将Ring的初始化信息保存到builer文件中去 builder.save(argv[1]) exit(EXIT_SUCCESS)这个函数的逻辑非常简单,主要就是创建一个swift.common.ring.builder.RingBuilder类的实例,然后将它的初始化信息保存到Ring的builder文件和备份文件里。接下来看看这类的初始化过程
# swift/common/ring/builder.py class RingBuilder(object): def __init__(self, part_power, replicas, min_part_hours): self.part_power = part_power self.replicas = replicas self.min_part_hours = min_part_hours self.parts = 2 ** self.part_power self.devs = [] self.devs_changed = False self.version = 0 # _replica2part2dev 是一个二维数组,第一维从replica映射到partition # 第二维从partition映射到device。所以对一个replica个数为3, # partition个数为 2^23 的ring来说,_replica2part2dev是一个3*2^23数组 # 该数据的每一个元素都是device ID(数据类型unsigned short)。 self._replica2part2dev = None # _last_part_moves是一个长度为2^23的数组,数组中每个元素为unsigned byte # 这个数组的每个元素表示该元素所对应的partition据上次移动所过去的时间 # (以小时为单位)。这个数组存在的目的是为了保证同一个partition在一定的时间内(一般是24小时) # 不会被移动两次。不过删除或者把一个设备的weight设为0不受这个时间的限制。这是因为 # 删除设备或者把wight设为0是因为该设备已经出现故障 # _last_part_moves_epoch表示_last_part_moves的基准时间 self._last_part_moves_epoch = None self._last_part_moves = None self._last_part_gather_start = 0 self._remove_devs = [] self._ring = NoneRingBuild类实例初始化后,在保存了传递进来的part_power、replicas以及min_part_hours等参数之后,初始化了一个重要的二维数组_replica2part2dev。_replica2part2dev数组就是设备查询表,它的第一维以replicas为索引,也就是说如果设定replicas等于3,那么该数组第一维就是3个成员,每一个成员都是一个数组(第二维数组)。第二维数组负责partition到device的映射,长度为partition的个数。_replica2part2dev之外的一个重要数组即devs[]数组,该数组即为我们前面提到的设备列表。根据从_replica2part2dev中检索到的设备号,到该表中查询设备的具体位置信息。目前设备表的内容为空,因为此时还不知道设备的情况。到此,构建Ring的第一个步骤创建Ring文件已经完成。
相关文章推荐
- 学习Hibernate源码——配置文件解析,SessionFactory创建
- OpenStack Swift源码分析(4)----swift-ring-builder源代码解析之一
- openstack swift ring文件解析
- OpenStack_Swift源码分析——创建Ring及添加设备源码算法详细分析
- OpenStack Swift源码分析(5)----swift-ring-builder源代码解析之二
- 【原创】OpenStack Swift源码分析(二)ring文件的生成
- Swift源码解析之添加设备到Ring
- hadoop源码解析之hdfs写数据全流程分析---创建文件
- wordpress源码解析-目录结构-文件调用关系(1)
- Dubbo 源码解析 —— Zookeeper 创建节点
- Picasso源码完全解析(二)--Picasso实例的创建
- dex2jar源码解析----解析dex文件<二>
- cocos2d-x:参考案例源码解析之一:Cocos2dx各个文件说明
- wordpress源码解析-目录结构-文件调用关系(1)
- 简单看Spring源码--对xml文件解析
- (二)MyBatis源码解析之配置文件
- dubbo源码:配置文件加载自定义标签解析
- Swift的Podfile文件创建与使用规范
- Spring源码解析(八)——实例创建(下)
- Wireshark的Pcap文件格式分析及解析源码