TFS集群支持异地机房容灾,一个逻辑集群包含分布在多个机房的物理集群,其中一个是主集群,其他的是备份集群。客户端写文件时,都会写到主集群,主集群的Dataserver(DS)异步将数据同步到多个备集群;客户端在读取数据时,会选择离自己最近的物理集群读取数据,如果读不到数据,就重试逻辑集群里的其他物理集群。

对集群同步的期望

1. 所有的文件都能被同步到备集群 
2. 文件尽快同步到备集群 
3. 文件尽量从DS本地同步到备集群 
4. 文件在多个集群中数据及状态保持一致

同步实施方案

写文件时,DS会记录同步日志(binlog),并在后台不断重放binlog,将文件同步到备集群,binlog记录在DS本地系统盘。由于日志本身是不可靠的存储,可能出现同步日志丢失的情况,每天夜间对整个集群会有一次定期的增量同步,以确保所有的文件都写到备集群。

由于文件数据通常很大,所以不能像mysql那样,把数据都记录在binlog,tfs的binlog里只包含文件的blockid、fileid等信息。重放日志时,DS先尝试从本地读取文件,并写到备集群;block可能在同步前被迁移到其他DS上,故如果本地读取不到,需要通过网络尝试读取其他副本来同步数据。

当部署多个备份集群时,为了避免往多个备份集群的同步相互影响,TFS为每个备份集群单独维护一份binlog,针对每份binlog,启动一个后台线程来重放。对于binlog里同步失败的文件,为了避免影响到后续文件的同步,失败的文件会写入到一个失败队列(持久化),有专门的后台线程定期的重试同步失败队列里的文件直到成功,然后将其移出失败队列。

多机房部署

在主集群的所有DS上配置备份集群Nameserver(NS)的地址

# edit ns.conf in master cluster  
slave_nsip = slave_cluster_ns_ip_port(eg: 192.168.1.100:3100)

如果备份集群在搭建主集群的时候就已经配置好,那么非常轻松,主备集群从零开始就一直保持数据一致;但实际上,很多是先部署了单个集群,运行了一段时间,才开始张罗容灾的事情,也就是说准备搭建备份集群的时候,主集群里已经写入了很多数据,此时就会相对麻烦一些。

1. 搭建好备份集群 
2. 在t1时间用ssm工具dump出所有block(可以过滤掉空的block) 
3. 将上述block,使用sync_by_block工具同步到备份集群 
4. 在t2时间,在主集群的DS上配置上备份集群的NS地址(需要重启DS), 从t2时间起写入主集群的数据都会被同步到备份集群

此时,备份集群还比主集群还少t1-t2写入的文件数据,可采取以下方式来补偿:

1. 再次dump主集群上所有的block,采用sync_by_block同步到备份集群。 
或者 2. 从日志里找出t1-t2时间段写入的所有文件,使用sync_by_file将这些文件同步到备份集群

初看起来,第2种补偿反感应该快很多,实际上,sync_by_block时,如果文件已经同步到备份集群了,sync_by_block是不会再次重复同步的(会先对比下元信息,确定是否需要同步),所以规模不大时上述2种方案效率差别不大,更推荐第1种方案,实施起来比较简单(第2种方案需要了解TFS的日志文件的格式,找出写文件记录,并从这条记录解析出TFS文件名)。