OpenStack之Swift:容器服务器(Container Server)源码分析
2.1.Xattr介绍官方描述:Extended attributes extend the basic attributesof files and directories in the file system. They are stored as name:data pairsassociated with file system objects (files, directorie
2.1.Xattr介绍
官方描述:
Extended attributes extend the basic attributesof files and directories in the file system. They are stored as name:data pairsassociated with file system objects (files, directories, symlinks, etc).
Extended attributes are currently only availableon Darwin 8.0+ (Mac OS X 10.4) and Linux 2.6+. Experimental support is includedfor Solaris and FreeBSD.
在xattr部分,主要涉及到listxattr,getxattr, setxattr, removexattr这几个方法的使用,下面分别操作说明:
如读取一个对象文件的元数据,截图如下:
完整显示元数据截图:
由上图元数据的完整,可以看出包括的元数据项有:
X-Timestamp:1319697631.38769(为python客户端上传时候的时间戳)
Content-Length:1024000
ETag:475c73190561051159c2c2d443b32cd6
Content-Type:application/octet-stream
name:/AUTH_482774c0-c171-4273-b218-600e17918129/myfiles_segments/1G_.rar/1319167623.0/1214049974/00000489
其中账户名:AUTH_482774c0-c171-4273-b218-600e17918129
容器名:myfiles_segments
对象名:1G_.rar/1319167623.0/1214049974/00000489
其中:1319167623.0为时间戳;1214049974文件大小;00000489段编号
2.2.时间同步问题
96,97两台机器的时间不同步,因为数据对象文件名是以时间戳命名,导致3份数据对象名字不一样,
对于对象hash
find /mnt/ -name94d5f563bb40a133a4efae58a1db3bd8
在96上执行:
在97上执行:
而查找数据对象 在96上是1319175353.92109.data,97上是1319176251.18341.data
删除对象后,96上面:
为一个墓碑了。
97上面:
也为一个墓碑了。
2.3.文件的上传
文件的上传下载,是swift云存储会涉及到的主要操作之一,下面就具体讲解。
上传的命令举例:
上图为将路径/etc/swift/account-server/下所有的文件上传,包括子文件夹下的文件
下图将单个文件上传
下图为文件对象分段上传
下面对文件上传源码进行分析:
当程序判断该执行上传操作,则程序会进入st_upload(options, args,print_queue, error_queue)执行。在该方法中,首先是进行权限认证,通过则获得其url,token:
通过url,token等创建连接:
通过队列,连接,上传对象的方法初始化上传对象的线程:
由上图可看出,初始化线程数目为10,
然后开启线程。
然后会判断命令传入的参数,如果容器不存在,会创建容器,如果分段上传,会将分的段放到专门的分段容器里面,每一个容器只对应一个分段容器:如容器名位360buy,则其分段容器名为360buy_segments,代码截图如下:
上图的args[0]代表容器
然后判断路径,如果为目录,遍历目录,将目录下的文件及其子目录的文件加入到加入到对象队列当中,如果为文件,直接将文件加入到对象队列当中,准备让_object_job方法将其上传到对象服务器中,代码截图如下:
上图的args[1:]代表路径
在上图中,程序调用到了_upload_dir方法,它的作用就是循环遍历文件夹,将所用的文件路径添加到对象队列中去,截图如下:
上传中也会用到_object_job,它的作用就是上传对象,如果上传的文件要分段,将文件分段再上传,分段文件的上传要调用_segment_job方法。
在_object_job内部,首先判断上传的路径是否为目录,如果为目录且目录为空,再判断是否有change标志,如果有,则判断容器中该对象是否已经存在,如果存在就直接返回,如果不存在就上传目录对象,关键代码截图如下:
由上图可以看出,上传的该对象路径为空,长度为0,类型为目录,且带了头信息。
当路径不为空目录时:
首先进行change检查,如果对象服务器中该对象已经存在,则直接返回,否则向下执行,截图如下:
如果进行了分段,且分段长度小于文件大小,则首先初始化队列,和线程,截图如下:
在段线程初始化中,用方法_segment_job进行段的上传,段数据存于segment_queue队列内,然后循环,根据segment_size计算每一个段的segment_start,然后将这些参数放入段队列内,关键代码如下:
上传完文件后,再上传manifest,manifest是一个0字节对象,它的信息存在在头中,截图如下:
由上图可看出manifest内容长度为0,而其头中包括的信息为:
当分段长度小于文件大小,或者没有分段的情况下,直接将对象上传:
由上图可知:文件以二进制方式上传,长度为文件的大小。
最后当分段的manifest与之前上传相同对象分段的manifest不同时候,将之前上传的分段信息删除,截图如下:
当分段上传的时候会调用到方法_segment_job.
在方法内部:
首先判断是否队列中的delete标志位true,如果为true,则执行删除操作,否则忽略继续向下执行,执行上传操作,关键代码截图如下:
如果上传尝试次数大于1,将信息也会打印到屏幕:
2.4.对象下载
下载命令举例:
下载某个账户下面的所有容器中的对象
下载下来后,如果没有相应的文件夹,会先创建文件夹,再下载
在该图中,会创建文件夹etc,swift,myfiles等文件夹,分段文件,只创建分段容器名的文件夹。
下载指定对象到指定的文件内:
下面进行下载部分的源码分析:
当程序判断该执行上传操作,则程序会进入st_upload(options, args,print_queue, error_queue)执行。在该方法中,首先是进行权限认证,通过则获得其url,token:
通过url,token等创建连接:
上图为容器线程
如果没有带参数,有命令-all,则会下载该账户下的所有容器内的对象。
上面已经提及到,下载容器中所有的对象,会调用_download_container方法,下载某个具体对象的时候,会调用_download_object方法。
在_download_container内部:
查询出容器内的所有对象名,将他们加入到对象队列,关键代码如下:
然后从容器服务器取得对象:
下面是我们试验的md5()对象的 update方法,其实就是不断更新传入数据的hash值,如:
Update2次,分别为liuhong和is a china 跟一次更新liuhong is achina,2次得到的hash值应该是一样的,如下面的m,m1的结果是一样的:
当分段上传对象的情况下,temp文件夹生成的临时文件的情况:
可以看到最长为1024000,即为分段的长度。
默认情况下,ext3,ext4的xattr没有打开,打开ext3,ext4的xattr属性方法如下:
首先使用
mkfs.ext3 /dev/sda1
格式化
然后使用
tune2fs -o user_xattr /dev/sda1
打开xattr特性。
接下来,在/etc/fstab加入下面这行:
/dev/sda1 /var/fscache ext3 defaults,user_xattr 0 0
查看是否打开:dumpe2fs –h /dev/sda1
截图如下:
上图即为打开了可扩展属性
如果打开后,依然swift不能运行成功,卸载后再挂载一次,则swift的运行就能成功。
2.5对象复制
从ring文件中读取出本机设备相关的信息;
读取出本机设备对象文件夹下的所有分区号,并且用分区号从ring文件中查处其他节点设备的相关信息;
将查询出的其他节点设备信息放入jobs列表
从jobs列表中读取出信息,并进行同步操作
对象审计:
遍历本机对象目录下面的对象,将其实际长度与元数据中记录的长度进行比较,如果相同,则审计通过,否则审计失败,将其隔离
对象hash.pkl文件内容解析:
操作:
键7cd为613ba02d3565a8f086d1d2b27dc847cd的后三位;value暂时还不清楚。
3.配置文件解析
配置文件通过ConfigParser包进行解析:例子如下:
import ConfigParser
import string, os, sys
cf =ConfigParser.ConfigParser()
cf.read("swift.conf")
# 返回所有的section
s = cf.sections()
print 'section:',
o =cf.options("db")
print 'options:', o
对swift.conf内容解析如下:
section: ['db', 'concurrent']
options: ['db_host','db_port', 'db_user', 'db_pass']
db: [('db_host','127.0.0.1'), ('db_port', '3306'), ('db_user', 'root'), ('db_pass','password')]
如,上面就是proxy server的配置文件,跟上面我们举例的配置类似。
更多推荐
所有评论(0)