0 SeaweedFS的使用方式
以存放文件为例来讲述目前使用方式跟官网的区别
SeaweedFS官网使用方式时序图
目前存放数据的时序图
采用这种方式的原因是:可以自己来设定文件的Key值,不要中间服务器来记录并转变文件到Key值之间的映射关系。
读取文件时,跟存放文件采用相同的方式。
官网给的方式仍是通过Master获取文件真正存放地址,然后再次访问获取文件内容。
目前使用的是直接访问Volume获取文件内容。如果从Master获取会出现301情况。
1 整个文件系统的UML图
磁盘管理UML图
SeaweedFS文件管理主要分为两个部分:
对于文件实体的管理(Needle类)
对于索引文件的管理(根据储存方式分为InMemory、LevelDb、BoltDb、Btree)
对于文件实体的管理,都存放在.dat文件中。
对于索引文件的管理,目前项目采用的方式为InMemory。
对于三个类要特别注意一下:
Needle类(分为四部分Header、Body、CRC、Padding)
成员名
类型
所属部分
说明
Cookie
uint32
Header
用于存放随机访问码,目前所有文件为0
Id
uint64
Header
文件的唯一性编号,目前使用方式为1z0x0y
Size
uint32
Header
用于记录整个NeedleBody的大小
DataSize
uint32
Body
用于记录所要存储文件的大小,文件最大为4G
Data
[]byte
Body
用于记录文件内容
Flags
byte
Body
用于记录Body各种属性,例如gzip等
NameSize
uint8
Body
用于记录文件名称大小
Name
[]byte
Body
用于记录文件名称
MimeSize
uint8
Body
用于Mime的大小
Mime
[]byte
Body
用于记录上传时的文件头部内容,例如 Content-Type
LastModified
uint64
Body
文件的最后修改时间,.dat文件只保留5个字节
Ttl
*TTL
Body
文件有效期
PairsSize
uint16
Body
用于记录Pairs大小
Pairs
[]byte
Body
使用JSON格式来存放文件的其他信息
Checksum
CRC
CRC
仅对Data进行crc32的校验
Padding
[]byte
Padding
保证每个Needle实体符合8字节对其规范
使用InMemory模式管理索引文件时,使用的NeedleValue类
成员名
类型
说明
Key
uint64
文件的唯一性ID
Offset
uint32
对应的文件实体Needle在.dat文件中的偏移量(按8字节对其方式计算),因此.dat文件的最大值为32G
Size
uint32
存放的Needle中Body部分的大小
每个Volume使用的SuperBlock类,这个类用来记录卷的信息。
存在问题:
由于Offset大小为uint32,限制卷文件的大小。
成员名
类型
使用字节数
说明
version
uint8
1
卷所使用的版本,目前都是2版本
ReplicaPlacement
*ReplicaPlacement
1
卷的副本数量
Ttl
TTL
2
卷的有效期
CompactRevision
uint16
2
卷被紧缩的次数
2 卷文件
SeaweedFS中每个卷分为两个文件:
.dat文件,用于存放源文件内容(由Needle类构成)
.idx文件,用于存放源文件的索引(由NeedleValue类构成)
.dat文件图示如下:
.dat文件格式
.dat文件中前8个字节由SuperBlock类构成,后面的内容由Needle按照8字节对齐的方式进行拼装组成
.idx文件图示如下:
.idx文件格式
.idx文件由NeedleValue类拼装组成。由offset字段来指出对应的Needle在.dat文件中的位置。
3 卷文件同步
对于卷同步,从两个角度来看待这个问题:
上传文件时,卷与卷之间的同步
新增机器时,机器之间卷的同步
对于第一点,SeaweedFS所采用处理方式如下:
询问Master,需要同步的卷所在位置(URL)
组装HTTPRequest,依次向需要同步的卷发送HTTP请求
问题:
这里就存在一个卷数据的一致性问题。如果需要同步的卷网络暂时出现问题,则消息无法进行同步。
上传速度较慢,每一个文件组成一个HTTP请求。对于大量的瓦片数据需要较长时间上传完成。目前3796640个瓦片数据(0-14级),需要4.5个小时左右才能上传完成。
对于第二点,SeaweedFS官网给出的处理方式如下:
复制对应的.dat和.idx文件到新机器上,从而使其卷数据一致。
问题:这种方式非常不利于系统的水平扩展。
4 目前服务器开发方向
最终目的:联合切片一起,做到从切片过程到发布过程的自动化处理。
目前面临的问题:
上传数据耗时过长。
卷数据一致性问题。
系统的水平扩展后数据同步的问题。
扩展到18级时,目前使用的Key值无法继续使用。
卷大小超过32G时产生的问题。
目前想到处理方式:
对于上传耗时过长的问题,准备采用直接产生卷文件的方式来解决。
卷数据一致性问题,准备采用改变volume的同步方式,使用raft协议保证数据一致性。
系统水平扩展,准备采用volume的一致性方案看是否能够解决。
扩展到18级瓦片的问题,准备改变key值的生成方式来完成。
卷大小超过32G时,采用将瓦片分在不同卷中,并且通过卷的collection来判断是否是同一批数据。
已经完成的测试工作:
已经完成从切片到生成大文件的联调工作,完成了生成大文件的C++代码。
分布式切片生成的大文件归并代码已经完成,并自测完成。
编写代码并测试本地机器卷与卷之间的同步,120W左右的文件大概需要9分钟左右同步完成。(此同步使用的是HTTP请求)
了解raft协议的工作原理,查看了goraft的代码。
上传时,采用多个文件一个HTTP请求发送。但速度提升较小,放弃这种方式。
整个工作流程图示如下:
流程图示