OpenStack Swift源码分析(一)builder文件的生成

最近开始Swift源码分析,无非就是不想纸上谈兵,究竟是用什么算法,和方法实现的功能,所以决定开始写源码分析。

    当你安装完swift,你需要做的第一件事情就是创建ring文件,而你用的第一个命令就是swift-ring-builder。swift-ring-builder文件位于源码的bin目录下,是swift最基本的命令,它与swift/common/ring/下的文件一起实现ring文件创建,添加,平衡,等操作。

    对于初学者(比如说我)重写源码片段,可以更加深入的了解源码的原理,同时还能对python语言以及相关的库有更深的了解,swift-ring-builder中主要的功能实现就是在Commands类中,比如default(),create(),add(),rebalance()等, 然后main方法会根据你提供的相应参数,来提供执行相应的方法,然后其中的方法会调用/swift/common/ring/下的builder.py中相应的方法最终实现相应的操作,

当我们通过create创建account.builder文件的时候,commod == argv[2] 也就是create 然后执行create来创建account.builder。之后的操作,只要是存在account.builder文件,就会打开这个文件,生产builder实例,来进行相应的操作。其中的 default方法是显示当前的builder信息,可以用来在rebalance之前 检查add的device 。

其中reblance是最重要的方法,当中会涉及到/swift/common/ring下的ring.py builder.py utils.py文件,涉及到了一致性哈希算法和策略的实现,下个博客会具体分析。

代码片段:基本就是把源码抽出来,没写什么注释和异常处理,生成的builder文件,可以通过diff命令,比较是否跟使用swift-ring-builder命令创建的builder文件一样(答案当然是肯定的)。

 

001 #! /usr/bin/env python
002  
003 from sys import argv, exit, modules
004 import cPickle as pickle
005 from os.path import basename, dirname, exists, join as pathjoin
006 from itertools import islice, izip
007  
008 from builder import RingBuilder
009  
010  
011 MAJOR_VERSION = 1
012 MINOR_VERSION = 3
013 EXIT_SUCCESS = 0
014 EXIT_WARNING = 1
015 EXIT_ERROR = 2
016  
017  
018 class Commands:
019  
020     def unknown():
021         print 'Unknown command: %s' % argv[2]
022         exit(EXIT_ERROR)
023      
024     def create():
025         """
026         my-ring-builder <builder_file> create <part_power> <replicas>
027                                                 <min_part_hours>
028         """
029  
030         if len(argv) < 6:
031             print Commands.create.__doc__.strip()
032             exit(EXIT_ERROR)
033         builder = RingBuilder(int(argv[3]), int(argv[4]), int(argv[5]))
034         pickle.dump(builder.to_dict(), open(argv[1], 'wb'), protocol=2)
035         exit(EXIT_SUCCESS)
036  
037     def default():
038         """
039         Shows information about the ring and the devices within.
040         """
041         print '%s, build version %d ' % (argv[1], builder.version)
042         zones = 0
043         balance = 0
044         if builder.devs:
045             zones = len(set(d['zone'for in builder.devs if is not None))
046             #blance = builder.get_balance()
047         print '%d partitions, %d replicas, %d zones, %d devices' \
048                 % (builder.parts, builder.replicas, zones,
049                     len([d for in builder.devs if d]))
050         print 'The minimun number of hours before a partition can be' \
051                 'reassigned is %s' % builder.min_part_hours
052         if builder.devs:
053             print 'Devices:    id  zone      ip  address  port    name' \
054                     'weight partition'
055             weighted_parts = builder.parts * builder.replicas / \
056                     sum(d['weight'for in builder.devs if is not None)
057             for dev in builder.devs:
058                 if dev is None:
059                     continue
060                 if not dev['weight']:
061                     if dev['parts']:
062                         blance = 999.99
063                     else:
064                         blance = 0
065                 else:
066                     blance = 100.0 * dev['parts'/ \
067                             (dev['weight'* weighted_parts) - 100.0
068                 print '        %5d %5d %15s %5d %9s %6.02f %10s' % \
069                         (dev['id'], dev['zone'], dev['ip'], dev['port'],
070                          dev['device'], dev['weight'], dev['parts'])
071         exit(EXIT_SUCCESS)
072  
073     def add():
074         """
075         .......
076         """
077  
078         dev_and_weights = izip(islice(argv, 3len(argv), 2),
079                                islice(argv, 4len(argv), 2))
080         for devstr, weightstr in dev_and_weights:
081             if not devstr.startswith('z'):
082                 print 'Invalid add value: %s' % devstr
083                 exit(EXIT_ERROR)
084             = 1
085             while i < len(devstr) and devstr[i].isdigit():
086                 += 1
087             zone = int(devstr[1:i])
088             rest = devstr[i:]
089  
090             = 1
091             while i < len(rest) and rest[i] in '0123456789.':
092                 += 1
093             ip = rest[1:i]
094             rest = rest[i:]
095             print ip
096             = 1
097             while i < len(rest) and rest[i].isdigit():
098                 += 1
099             port = int(rest[1:i])
100             rest = rest[i:]
101  
102             = 1
103             while i < len(rest) and rest[i] != '_':
104                 += 1
105             device_name = rest[1:i]
106             rest = rest[i:]
107  
108             meta = ''
109             if rest.startswith('_'):
110                 meta = rest[1:]
111             weight = float(weightstr)
112             for dev in builder.devs:
113                 if dev is None:
114                     continue
115                 if dev['ip'== ip and dev['port'== port and \
116                         dev['device'== device_name:
117                     print 'already uses %s'
118                     exit(EXIT_ERROR)
119  
120             next_dev_id = 0
121             if builder.devs:
122                 next_dev_id = max(d['id'for in builder.devs if d) + 1
123             builder.add_dev({'id': next_dev_id, 'zone': zone, 'ip': ip,
124                              'port': port, 'device': device_name,
125                              'weight': weight, 'meta': meta})
126             print 'Device z%s-[%s]:%s/%s_"%s" with %s weight got id %s' % \
127                     (zone, ip, port, device_name, meta, weight, next_dev_id)
128         pickle.dump(builder.to_dict(), open(argv[1], 'wb'), protocol=2)
129         exit(EXIT_SUCCESS)
130  
131     def rebalance():
132         """
133         Attempts to rebalance the ring by reassigning partitions
134         """
135  
136         devs_changed = builder.devs_changed
137              
138         last_balance = builder.get_balance()
139         parts, balance = builder.rebalance()
140          
141         builder.validate()
142         print 'Reassigned %d (%.02f%%) partitions. Balance is now %.02f.' % \
143                 (parts, 100.0*parts / builder.parts, balance)
144         status = EXIT_SUCCESS
145         if balance > 5:
146             print'NOTE: Balance of %.02f indicates you should push the' % \
147                     balance
148             status = EXIT_WARNING
149         builder.get_ring().save(ring_file)
150         pickle.dump(builder.to_dict(), open(argv[1], 'wb'), protocol=2)
151         exit(status)
152 if __name__ == '__main__':
153      
154     if exists(argv[1]):
155         builder = pickle.load(open(argv[1], 'rb'))
156         if not hasattr(builder, 'devs'):
157             builder_dict = builder
158             builder = RingBuilder(111)
159             builder.copy_from(builder_dict)
160     ring_file = argv[1]
161     if ring_file.endswith('.builder'):
162         ring_file = ring_file[:-len('.builder')]
163     ring_file += '.ring.gz'
164     if len(argv) == 2:
165         command = "default"
166     else:
167         command = argv[2]
168     Commands.__dict__.get(command, Commands.unknown)()

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值