(六)FastDFS 高可用集群架构学习---后期运维--组内机器间数据同步(摘录)

一、Binlog同步概述

FastDFS中为了维护文件的多个副本,会在同组的Storage之间互相同步文件,也就是一个备份过程,若一组有三台机器,那么互相备份后,一个文件就有三个副本。本篇将主要描述Binlog同步的相关概念,与同步逻辑,以及一些注意事项。

1、Binlog结构

  1)目录结构

    在Storage.conf配置文件中,有一个配置如下:base_path=/data/zcs/fdfs_Storage_base

    在Storaged程序启动时会创建一个 base_path/data/sync 目录,该目录中的文件都是和Storaged之间的同步相关的,如:

      10.0.1.1_23000.mark10.0.1.2_23000.mark binlog.000binlog.index

      binlog.index ##记录当前使用的Binlog文件序号,如为1,则表示使用binlog.001

      binlog.000##真实地Binlog文件

      10.0.1.1_23000.mark##同步状态文件,记录本机到10.0.1.1的同步状态

  2)Mark文件内容描述

    对于10.0.1.1_23000.mark文件,本篇相关的内容有如下两项:

      binlog_index=0##表示上次同步给10.0.1.1机器的最后一条binlog文件索引

      binlog_offset=116##表示上次同步给10.0.1.1机器的最后一条binlog偏移量,若程序重启了,也只要从这个位置开始向后同步即可。

  3)Binlog文件内容描述

    对于binlog.000文件,是有一条条binlog日志组成的,如下:

1627025362 C M00/00/00/wKgDFGD6b9KALiDLAAYevEPlQIk376.jpg
1627025372 c M00/00/00/wKgDM2D6b9yAQJZxAAT4rd1P2iI703.jpg
1627025617 C M01/00/00/wKgDFGD6cNGAXGzwAAT4rd1P2iI215.jpg
1627025656 C M00/00/00/wKgDFGD6cPiAQED_AAT4rd1P2iI586.jpg
1627025654 c M01/00/00/wKgDM2D6cPaAC_vJAAT4rd1P2iI108.jpg
1627025657 c M00/00/00/wKgDM2D6cPmAZy_TAAT4rd1P2iI773.jpg
1627025658 C M01/00/00/wKgDFGD6cPqACGJNAAT4rd1P2iI332.jpg

    其中的每一条记录都是使用空格符分成三个字段,分别为:

    第一部分: 1627025362     表示文件upload时间戳

    第二部分:表示文件创建方式

      C表示源创建、c表示副本创建

      A表示源追加、a表示副本追加

      D表示源删除、d表示副本删除 

      T表示源Truncate、t表示副本Truncate

      注:源表示客户端直接操作的那个Storage即为源,其他的Storage都为副本,如客户端向10.0.1.1主机Upload一个文件,那么在10.0.1.1机器上记录的就是C,当10.0.1.1机器将该条binlog的操作同步给10.0.1.2时,在10.0.1.2上记录的binlog就是c,其他几种操作同理。

    第三部分:文件的FileID :M01/00/00/wKgDFGD6cPqACGJNAAT4rd1P2iI332.jpg  其中的M01为storepath索引,紧接着00/00/为路径,后面wKgDFGD6cPqACGJNAAT4rd1P2iI332.jpg为文件系统中实际的文件名(不采用合并存储时,若采用合并存储并不是一个实际的文件名)。

      注:文件名组成:CgAHl1SJUR6AZqSHAAAF1vgN0rw59.conf,这个文件名中,除了conf 为文件后缀,CgAHl1SJUR6AZqSHAAAF1vgN0rw59 这部分是一个base64编码缓冲区,组成如下:

        1、Storage_id(ip的数值型)

        2、timestamp(创建时间)

        3、file_size(若原始值为32位则前面加入一个随机值填充,最终为64位)

        4、crc32(文件内容的检验码)

二、Binlog同步过程

在FastDFS之中,每个Storaged之间的同步都是由一个独立线程负责的,该线程中的所有操作都是以同步方式执行的。比如一组服务器有A、B、C三台机器,那么在每台机器上都有两个线程负责同步,如A机器,线程1负责同步数据到B,线程2负责同步数据到C。

 

1、获取组内的其他Storage信息,并启动同步线程

  在Storage.conf配置文件中,只配置了Tracker的IP地址,并没有配置组内其他的Storage。因此同组的其他Storage必须从Tracker获取。具体过程如下:

    1)Storage启动时为每一个配置的Tracker启动一个线程负责与该Tracker的通讯。

    2)默认每间隔30秒,与Tracker发送一次心跳包,在心跳包的回复中,将会有该组内的其他Storage信息。

    3)Storage获取到同组的其他Storage信息之后,为组内的每个其他Storage开启一个线程负责同步。

2、同步线程执行过程

  每个同步线程负责到一台Storage的同步,以阻塞方式进行。

  1)打开对应Storage的mark文件,如负责到10.0.1.1的同步则打开10.0.1.1_23000.mark文件,从中读取binlog_index、binlog_offset两个字段值,如取到值为:1、100,那么就打开binlog.001文件,seek到100这个位置。

  2)进入一个while循环,尝试着读取一行,若读取不到则睡眠等待。若读取到一行,并且该行的操作方式为源操作,如C、A、D、T(大写的都是),则将该行指定的操作同步给对方(非源操作不需要同步),同步成功后更新binlog_offset标志,该值会定期写入到10.0.1.1_23000.mark文件之中。

  3、同步前删除

  假如同步较为缓慢,那么有可能在开始同步一个文件之前,该文件已经被客户端删除,此时同步线程将打印一条日志,然后直接接着处理后面的Binlog。

 

三、Storage的最后最早被同步时间

  这个标题有点拗口,先举个例子:一组内有Storage-A、Storage-B、Storage-C三台机器。对于A这台机器来说,B与C机器都会同步Binlog(包括文件)给他,A在接受同步时会记录每台机器同步给他的最后时间(也就是Binlog中的第一个字段timpstamp)。比如B最后同步给A的Binlog-timestamp为100,C最后同步给A的Binlog-timestamp为200,那么A机器的最后最早被同步时间就为100.

  这个值的意义在于,判断一个文件是否存在某个Storage上。比如这里A机器的最后最早被同步时间为100,那么如果一个文件的创建时间为99,就可以肯定这个文件在A上肯定有。为什呢?一个文件会Upload到组内三台机器的任何一台上:

    1)若这个文件是直接Upload到A上,那么A肯定有。

    2)若这个文件是Upload到B上,由于B同步给A的最后时间为100,也就是说在100之前的文件都已经同步A了,那么A肯定有。

    3)同理C也一样。

  Storage会定期将每台机器同步给他的最后时间告诉给Tracker,Tracker在客户端要下载一个文件时,需要判断一个Storage是否有该文件,只要解析文件的创建时间,然后与该值作比较,若该值大于创建创建时间,说明该Storage存在这个文件,可以从其下载。

  Tracker也会定期将该值写入到一个文件之中,Storage_sync_timestamp.dat,内容如下:

group1,10.0.0.1,0,1408524351,1408524352
group1,10.0.0.2,1408524353,0,1408524354
group1,10.0.0.3,1408524355,1408524356,0

    每一行记录了,对应Storage同步给其他Storage的最后时间,如第一行表示10.0.0.1同步给10.0.0.2的最后时间为1408524351,同步给10.0.0.3的最后时间为1408524352;同理可以知道后面两行的含义了。每行中间都有一个0,这个零表示自己同步给自己,没有记录。按照纵列看,取非零最小值就是最后最早同步时间了,如第三纵列为10.0.0.1被同步的时间,其中1408524353就是其最后最早被同步时间。

 

四、注意事项

1、由于到每台机器的同步都是有单线程负责的,因此即使主机上有很多个磁盘也不能加快同步速度,因此单线程并不能最大化磁盘IO,最大的速度也就是一个磁盘的速度。

2、对于重要文件,为了防止机器宕机或者坏磁盘的文件丢失,及时的同步备份是必须得。若同步太慢,还可能导致Tracker不能正确估计可用空间,而导致空间溢出。

3、同步性能,由于Linux系统的文件缓存机制,若一个刚写入的文件马上读,那么很可能就命中在系统缓存上,此时读数据几乎不耗费时间,若不能命中缓存,从磁盘读,将耗费很长时间。因此写入速度,最好与同步速度相当,这样可以保证及时同步。若写入速度超过同步速度,从某个时刻开始,将会使得所有的读无法命中缓存,同步性能将大幅下滑。

 

上一篇:如何使用PHP实现一个WebService


下一篇:Mariadb 通过binlog恢复删除(drop table)的数据