本文将对同一组的不同storage server
之间的同步以及新增storage server
的同步进行介绍。
fastdfs
文件系统结构
fastdfs
文件系统原理**从fastdfs
文件系统结构中我们可以看出不管是上传文件、删除文件、修改文件及新增storager server
,文件的同步都是同组内多台storager server
之间进行的。**下面我们看fastdfs
文件系统开发者是怎么描述同步机制的(来源于chinaunix):
tracker server
的配置文件中没有出现storage server
,而storage server
的配置文件中会列举出所有的tracker server
。
这就决定了storage server
和tracker server
之间的连接由storage server
主动发起,storage server
为每个tracker server
启动一个线程进行连接和通讯。
tracker server
会在内存中保存storage
分组及各个组下的storage server
,并将连接过自己的storage server
及其分组保存到文件中,以便下次重启服务时能直接从本地磁盘中获得storage
相关信息。storage server
会在内存中记录本组的所有服务器,并将服务器信息记录到文件中。tracker server
和storage server
之间相互同步storage server
列表:
如果一个组内增加了新的storage server
或者storage server
的状态发生了改变,tracker server
都会将storage server
列表同步给该组内的所有storage server
。以新增storage server
为例,因为新加入的storage server
主动连接tracker server
,tracker server
发现有新的storage server
加入,就会将该组内所有的storage server
返回给新加入的storage server
,并重新将该组的storage server
列表返回给该组内的其他storage server
;
如果新增加一台tracker server
,storage server
连接该tracker server
,发现该tracker server
返回的本组storage server
列表比本机记录的要少,就会将该tracker server
上没有的storage server
同步给该tracker server
。
同一组内的storage server
之间是对等的,文件上传、删除等操作可以在任意一台storage server
上进行。**文件同步只在同组内的storage server
之间进行,采用push方式,即源服务器同步给目标服务器。**以文件上传为例,假设一个组内有3台storage server A、B
和C
,文件F
上传到服务器B,由B将文件F同步到其余的两台服务器A和C。我们不妨把文件F上传到服务器B的操作为源头操作,在服务器B上的F文件为源头数据;文件F被同步到服务器A和C的操作为备份操作,在A和C上的F文件为备份数据。同步规则总结如下:
只在本组内的storage server
之间进行同步;
源头数据才需要同步,备份数据不需要再次同步,否则就构成环路了;
上述第二条规则有个例外,就是新增加一台storage server
时,由已有的一台storage server
将已有的所有数据(包括源头数据和备份数据)同步给该新增服务器;
storage server
有7个状态,如下:
# FDFS_STORAGE_STATUS_INIT :初始化,尚未得到同步已有数据的源服务器
# FDFS_STORAGE_STATUS_WAIT_SYNC :等待同步,已得到同步已有数据的源服务器
# FDFS_STORAGE_STATUS_SYNCING :同步中
# FDFS_STORAGE_STATUS_DELETED :已删除,该服务器从本组中摘除(注:本状态的功能尚未实现)
# FDFS_STORAGE_STATUS_OFFLINE :离线
# FDFS_STORAGE_STATUS_ONLINE :在线,尚不能提供服务
# FDFS_STORAGE_STATUS_ACTIVE :在线,可以提供服务
当storage server
的状态为FDFS_STORAGE_STATUS_ONLINE
时,当该storage server
向tracker server
发起一次heart beat
时,tracker server
将其状态更改为FDFS_STORAGE_STATUS_ACTIVE
。
组内新增加一台storage server A
时,由系统自动完成已有数据同步,处理逻辑如下:
storage server A
连接tracker server
,tracker server
将storage server A
的状态设置为FDFS_STORAGE_STATUS_INIT
。
storage server A
询问追加同步的源服务器和追加同步截至时间点,如果该组内只有storage server A
或该组内已成功上传的文件数为0,则没有数据需要同步,storage server A
就可以提供在线服务,此时tracker将其状态设置为FDFS_STORAGE_STATUS_ONLINE
,否则tracker server
将其状态设置为FDFS_STORAGE_STATUS_WAIT_SYNC
,进入第二步的处理;
假设tracker server
分配向storage server A
同步已有数据的源storage server
为B。同组的storage server和tracker server通讯得知新增了storage server A,将启动同步线程,并向tracker server询问向storage server A追加同步的源服务器和截至时间点。
storage server B将把截至时间点之前的所有数据同步给storage server A;而其余的storage server从截至时间点之后进行正常同步,只把源头数据同步给storage server A。到了截至时间点之后,storage server B对storage server A的同步将由追加同步切换为正常同步,只同步源头数据;
storage server B
向storage server A
同步完所有数据,暂时没有数据要同步时,storage server B
请求tracker server
将storage server A
的状态设置为FDFS_STORAGE_STATUS_ONLINE
;
当storage server A
向tracker server
发起heart beat
时,tracker server
将其状态更改为FDFS_STORAGE_STATUS_ACTIVE
。
从上面的描述,我觉得作者描述的非常的清楚,让我们这些使用者能够非常容易理解。
刚刚我们从上面了解了fastdfs
文件系统中组内的多个storage server
之间同步的机制,那文件同步是什么时候进行呢?是文件上传成功后,其它的storage server
才开始同步,其它的storage server
怎么去感知,tracker server
是怎么通知storage server
呢?
当一个文件上传成功后,客户端马上发起对该文件下载请求(或删除请求)时,tracker
是如何选定一个适用的存储服务器呢?
其实每个存储服务器都需要定时将自身的信息上报给tracker
,这些信息就包括了本地同步时间(即,同步到的最新文件的时间戳)。
而tracker根据各个存储服务器的上报情况,就能够知道刚刚上传的文件,在该存储组中是否已完成了同步。在storage server
中这些信息是以Binlog
文件的形式存在的。
Binlog
文件当Storaged server
启动时会创建一个 base_path/data/sync
同步目录,该目录中的文件都是和同组内的其它 Storaged server
之间的同步状态文件,如192.168.1.2_33450.mark 192.168.1.3_33450.mark binlog.100(binlog.index);
192.168.1.2_33450.mark 192.168.1.3_33450.mark binlog.000 binlog.index
binlog.index
记录当前使用的Binlog
文件序号,如为10
,则表示使用binlog.010
binlog.100
真实地Binlog
文件192.168.1.2_33450.mark
同步状态文件,记录本机到192.168.1.2_33450
的同步状态在Mark
文件中内容:由binlog_index
和binlog_offset
两项组成,以192.168.1.2_33450.mark
为例其中binlog_index
表示上次同步192.168.1.2
机器的最后一条binlog
文件索引,binlog_offset
表示上次同步192.168.1.2
机器的最后一条binlog
偏移量,如果程序重启了,也只要从这个位置开始向后同步。
Binlog
文件内容:在该文件中是以binlog
日志组成,比如:
1470292943 c M00/03/61/QkIPAFdQCL-AQb_4AAIAi4iqLzk223.jpg
1470292948 C M00/03/63/QkIPAFdWPUCAfiraAAG93gO_2Ew311.png
1470292954 d M00/03/62/QkIPAFdWOyeAO3eUAABvALuMG64183.jpg
1470292959 C M00/01/23/QUIPAFdVQZ2AL_o-AAAMRBAMk3s679.jpg
1470292964 c M00/03/62/QkIPAFdVOsCAcxeQAAGTdbQsdVs062.jpg
1470292969 c M00/03/62/QkIPAFdVOnKAXu1NAABq9pkfsms63.jpeg
1470293326 D M00/03/62/QkIPAFdVMnGAZYSZAABq9pkfsms33.jpeg
其中的每一条记录都是使用空格符分成三个字段,分别为:
第一个字段 表示文件upload
时间戳 如:1470292943
第二个字段 表示文件执行操作,值为下面几种
C表示源创建、c表示副本创建
A表示源追加、a表示副本追加
D表示源删除、d表示副本删除
T表示源Truncate
、t表示副本Truncate
其中源表示客户端直接操作的那个Storage
即为源,其他的Storage
都为副本
第三个字段 表示文件 如M00/03/61/QkIPAFdQCL-AQb_4AAIAi4iqLzk223.jpg
Storage server
具体同步过程从fastdfs
文件同步原理中我们知道Storaged server
之间的同步都是由一个独立线程负责的,这个线程中的所有操作都是以同步方式执行的。比如一组服务器有A、B、C三台机器,那么在每台机器上都有两个线程负责同步,如A机器,线程1负责同步数据到B,线程2负责同步数据到C。每个同步线程负责到一台Storage
的同步,以阻塞方式进行。
以IP为192.168.1.1
的Storaged severe
的服务器为例,它的同步目录下有192.168.1.2_33450.mark 192.168.1.3_33450.mark binlog.100
等文件现在Storaged severe
将会从ip为192.168.1.2
的Storaged severe
的存储里面同步数据。
1)打开对应Storage server
的mark
文件,如负责到192.168.1.1
的同步则打开192.168.1.2_33450.mark
文件,从中读取binlog_index
、binlog_offset
两个字段值,如取到值为:100、1000
,那么就打开binlog.100
文件,seek
到1000
这个位置。
2)进入一个while
循环,尝试着读取一行,若读取不到则睡眠等待。若读取到一行,并且该行的操作方式为源操作,如C、A、D、T(大写的都是),则将该行指定的操作同步给对方(非源操作不需要同步),同步成功后更新binlog_offset
标志,该值会定期写入到192.168.1.2_33450.mark
文件之中。
同步过程中可能因为同步较为缓慢,导致可能在同步一个文件之前,文件已经被客户端删除,此时同步线程将打印一条日志,然后直接处理后面的Binlog
。