swift是openstack的object storage service。最近结合着一些文章大致梳理了一下它的源代码。致谢牛皮糖的博客的深入讲解。
关于代码目录
下图是它的代码目录
其中可以看到几个重要的文件夹:Accout、Ring、Container、obj、proxy。
在物理主机上安装完成的目录为:
/usr/lib/python2.7/dist-packages/swift# ls account common container __init__.py __init__.pyc obj proxy
关于使用到的第三方
swift的对象信息使用是SQLite数据库。SQLite,是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源世界著名的数据库管理系统来讲,它的处理速度比他们都快。
可以通过下面的方法来输出数据库包含的表
import sqlite3 cx=sqlite3.connect("./test.db") cu=cx.cursor() cu.execute("select name from sqlite_master where type='table'") print cu.fetchall()
如果需要查看某个数据库的某个表的内容,可以通过下列语句来实现,利于我需要查看test.db内container的内容:
import sqlite3 cx=sqlite3.connect("./test.db") cu=cx.cursor() cu.execute("select * from container") 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
def rebalance(self): """ Rebalance the ring. This is the main work function of the builder, as it will assign and reassign partitions to devices in the ring based on weights, distinct zones, recent reassignments, etc. The process doesn't always perfectly assign partitions (that'd take a lot more analysis and therefore a lot more time -- I had code that did that before). Because of this, it keeps rebalancing until the device skew (number of partitions a device wants compared to what it has) gets below 1% or doesn't change by more than 1% (only happens with ring that can't be balanced no matter what -- like with 3 zones of differing weights with replicas set to 3). :returns: (number_of_partitions_altered, resulting_balance) """ self._ring = None if self._last_part_moves_epoch is None: self._initial_balance() self.devs_changed = False return self.parts, self.get_balance() retval = 0 self._update_last_part_moves() last_balance = 0 while True: reassign_parts = self._gather_reassign_parts() self._reassign_parts(reassign_parts) retval += len(reassign_parts) while self._remove_devs: self.devs[self._remove_devs.pop()['id']] = None balance = self.get_balance() if balance < 1 or abs(last_balance - balance) < 1 or \ retval == self.parts: break last_balance = balance self.devs_changed = False self.version += 1 return retval, balance
参考文献:http://docs.openstack.org/developer/swift/index.htm
牛皮糖的:http://www.cnblogs.com/yuxc/archive/2012/06/28/2568584.html