集群间同步队列阻塞问题

集群数据对比功能的添加对TFS DS做了修改,在把DS上到日常测试环境前对其进行了一次回归测试,测试用例都通过,但checkserver检查到有大量block未同步到辅集群,查看dataserver的日志发现同步队列已经阻塞住了,一直重复retry。


主备集群的数据同步是由主集群的DS在后台进行,其将成功的写、删等操作记录在本地日志,并启动后台线程将日志重放到备集群,DS没重放一条日志,如果失败会一直重试,这个重试会阻塞同步队列。理论上在主集群上能成功的操作序列,在辅集群上也能成功,但偶尔也会有一些特殊情况会导致同步一直不成功,从而阻塞同步队列,这时就需要进行人工干预,疏通同步队列。


分析主集群上DS的日志发现,DS阻塞在一个隐藏文件的操作上,往前看DS的日志,发现前面有写、读、删除等记录,综合分析得出如下结论:

  1. DS同步阻塞主要由写、隐藏、删除的操作序列导致(回归测试用例可能存在这样的序列)。
  2. 对于文件A,客户端先后进行写文件、隐藏文件、删除文件的操作,三个操作均成功,并写了同步日志。同步过程是异步进行的,从DS日志发现,同步写文件操作是在删除文件成功之后开始做的。


同步写文件操作时,因为文件的删除标记,导致同步过程读不到源文件信息,则认为不需要同步了,并认为写文件同步成功。 此时,写文件的操作没有被同步到备集群。


接下来,同步线程同步隐藏操作,因为备集群上没有该文件,同步隐藏操作将失败,此时,会先把文件同步到备集群上去再隐藏,这里同步的效果跟上面同步写的过程是一样的,结果是写文件的操作没有被同步到备集群,并且认为同步成功了。接下来的隐藏操作仍会失败,因为文件并没有同步到备集群,这时返回错误,同步线程会重试,重复上述过程,从而阻塞同步队列。(问题主要出现在对同步隐藏操作的处理上.. 隐藏失败,并且结果为文件不存在,因直接忽略,返回成功,详细分析见解决方案)。


由于同步是异步进行的,如何能保证异步重放能和在主上一样成功,考虑文件可能被隐藏,可以在同步读时加强制标记。同时,文件可能被删除,删除后可能被压缩掉,这样就不能保证主上的序列一定能在备上重放成功。


日志同步的解决方案

  1. 保证我们的异步重放每次都得到跟主上一样的效果,即在日志中记录操作数据,即使数据删除,对同步没有影响;这样就能保证在主上正确的操作序列,一定能在备上也同样正确。但由于日志需要记录所有文件的数据,开销太大,所以这种方案不考虑。
  2. 合并,假如一个操作序列中包含一个删除操作,那么之后对文件的同步,包括写、隐藏等操作都认为是不需要同步的。(这里的合并不是指分析日志进行合并,而是同步时发现文件不存在或已删除,则忽略之)。目前,TFS采用这种方案来同步日志,但由于实现时的bug,导致产生上述问题。
posted @ 2013-04-19 14:13  ydzhang  阅读(507)  评论(0编辑  收藏  举报