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的配置文件,跟上面我们举例的配置类似。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐