分享

swift的部分代码解析

nettman 发表于 2014-2-26 21:58:04 [显示全部楼层] 只看大图 回帖奖励 阅读模式 关闭右栏 0 9800
可以带着下面问题来阅读
1.swift的对象信息存储在什么位置?
2.集群中发生存储节点宕机、新增(删)存储节点、新增(删)zone等必须改变partition和node间的映射关系时需要对哪个文件更新?




swift是openstack的object storage service。
关于代码目录
下图是它的代码目录
1345555657_5784.png

其中可以看到几个重要的文件夹:Accout、Ring、Container、obj、proxy。
在物理主机上安装完成的目录为:
  1. /usr/lib/python2.7/dist-packages/swift# ls  
  2. account  common  container  __init__.py  __init__.pyc  obj  proxy  
复制代码
关于使用到的第三方
swift的对象信息使用是SQLite数据库。SQLite,是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源世界著名的数据库管理系统来讲,它的处理速度比他们都快。
可以通过下面的方法来输出数据库包含的表
  1. import sqlite3  
  2. cx=sqlite3.connect("./test.db")  
  3. cu=cx.cursor()  
  4. cu.execute("select name from sqlite_master where type='table'")  
  5. print cu.fetchall()  
复制代码
如果需要查看某个数据库的某个表的内容,可以通过下列语句来实现,利于我需要查看test.db内container的内容:
  1. import sqlite3  
  2. cx=sqlite3.connect("./test.db")  
  3. cu=cx.cursor()  
  4. cu.execute("select * from container")  
  5. print cu.fetchall()  
复制代码
可以通过打开官网的链接详细了解感兴趣的每一个函数,其实可以当做手册来用:http://docs.openstack.org/developer/swift/py-modindex.html但是其中代码并不是全部,如果需要全部的代码,还是需要下载swift的源代码。

关于ring
对于ring的分析有一篇博客分析的比较好:http://www.cnblogs.com/yuxc/archive/2012/06/22/2558312.html#2438073,它的原文在http://greg.brim.net/page/building_a_consistent_hashing_ring.html
Ring的Rebalance机制
  当集群中发生存储节点宕机、新增(删)存储节点、新增(删)zone等必须改变partition和node间的映射关系时,就需要对Ring文件进行更新,也就是在swift文档中见到的rebalance一词。
在源码中对rebalance的定义如下:swift/Common/Ring/Builder.py
  1. def rebalance(self):  
  2.         """
  3.         Rebalance the ring.
  4.         This is the main work function of the builder, as it will assign and
  5.         reassign partitions to devices in the ring based on weights, distinct
  6.         zones, recent reassignments, etc.
  7.         The process doesn't always perfectly assign partitions (that'd take a
  8.         lot more analysis and therefore a lot more time -- I had code that did
  9.         that before). Because of this, it keeps rebalancing until the device
  10.         skew (number of partitions a device wants compared to what it has) gets
  11.         below 1% or doesn't change by more than 1% (only happens with ring that
  12.         can't be balanced no matter what -- like with 3 zones of differing
  13.         weights with replicas set to 3).
  14.         :returns: (number_of_partitions_altered, resulting_balance)
  15.         """  
  16.         self._ring = None  
  17.         if self._last_part_moves_epoch is None:  
  18.             self._initial_balance()  
  19.             self.devs_changed = False  
  20.             return self.parts, self.get_balance()  
  21.         retval = 0  
  22.         self._update_last_part_moves()  
  23.         last_balance = 0  
  24.         while True:  
  25.             reassign_parts = self._gather_reassign_parts()  
  26.             self._reassign_parts(reassign_parts)  
  27.             retval += len(reassign_parts)  
  28.             while self._remove_devs:  
  29.                 self.devs[self._remove_devs.pop()['id']] = None  
  30.             balance = self.get_balance()  
  31.             if balance < 1 or abs(last_balance - balance) < 1 or \  
  32.                     retval == self.parts:  
  33.                 break  
  34.             last_balance = balance  
  35.         self.devs_changed = False  
  36.         self.version += 1  
  37.         return retval, balance  
复制代码
在基于原有的Ring来构造新Ring时,swift-ring-builder首先要重新计算每个设备所需的partition数量。然后,将需要重新分配的partition收集起来。取消分配给被移除设备上的partition并把这些partition添加到收集列表。从拥有比当前所需的partition数多的设备上随机地取消分配多出的partition并添加到收集列表中。最后,将收集列表中的partition使用与初始化分配时类似的方法重新分配。

  在本地执行swift-ring-builder命令行来生成新的ring文件,然后把这些文件复制到集群的每个节点的/etc/swift目录中,所有需要使用ring的server进程会每15秒(默认值)检查一遍ring文件的修改时间mtime,如果发现和内存中的不一致,则重新加载ring文件到内存中去。、

  举例说明

  现在再增加一台存储节点node4并作为zone5,使用相同权重的devcie。那么每个存储节点上的partition数是52428.8。需要从每台存储节点上随机地移除13107.2个partition到收集列表,然后再重新分配这些parttion到node4上。当有partition的replica被重分配时,重分配的时间将被记录。在RingBuilder类内使用min_part_hours来限制在规定时间内,同一个partition不会被移动两次。

  由于收集用来重新分配的partition是基于随机的,rebalacne进程并不能一次就可以完美地重平衡ring。为了达到一个较为平衡的ring,rebalacne进程被重复执行直到接近完美(小于1%)或者当rebalacne的提升达不到最小值1%。

  具体的操作如下,首先移除旧的ring文件:
rm -f account.builder account.ring.gz backups/account.builder backups/account.ring.gz
.......

  然后,重新平衡ring文件:
  1. swift-ring-builder account.builder create 18 3 1
  2. swift-ring-builder account.builder add z1-192.168.1.50:6002/sdc 100
  3. swift-ring-builder account.builder add z2-192.168.1.51:6002/sdc 100
  4. swift-ring-builder account.builder add z3-192.168.1.52:6002/sdc 100
  5. swift-ring-builder account.builder add z4-192.168.1.54:6002/sdc 100
  6. swift-ring-builder account.builder add z5-192.168.1.53:6002/sdc 100
  7. swift-ring-builder account.builder rebalance
  8. swift-ring-builder container.builder create 18 3 1
  9. swift-ring-builder container.builder add z1-192.168.1.50:6001/sdc 100
  10. swift-ring-builder container.builder add z2-192.168.1.51:6001/sdc 100
  11. swift-ring-builder container.builder add z3-192.168.1.52:6001/sdc 100
  12. swift-ring-builder container.builder add z4-192.168.1.54:6001/sdc 100
  13. swift-ring-builder container.builder add z5-192.168.1.53:6001/sdc 100
  14. swift-ring-builder container.builder rebalance
  15. swift-ring-builder object.builder create 18 3 1
  16. swift-ring-builder object.builder add z1-192.168.1.50:6000/sdc 100
  17. swift-ring-builder object.builder add z2-192.168.1.51:6000/sdc 100
  18. swift-ring-builder object.builder add z3-192.168.1.52:6000/sdc 100
  19. swift-ring-builder object.builder add z4-192.168.1.54:6000/sdc 100
  20. swift-ring-builder object.builder add z5-192.168.1.53:6000/sdc 100
  21. swift-ring-builder object.builder rebalance
复制代码
最后,复制account.ring.gz、container.ring.gz、object.ring.gz到集群的各节点的/etc/swift目录下。这样我们就完成了Ring的重平衡(rebalance)。


加微信w3aboutyun,可拉入技术爱好者群

没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条