【疑难杂症03】数据同步遇到的坑

  这是发生在我身上的一个bug,困扰了我三天,已经让我屡次怀疑人生。由于我这个工做是数据准备阶段,后续还有一系列工做须要依赖我这些初始数据,压力很大,感谢某人在这个时候给个人鼓励,虽然只是寥寥几句。这件事记起来仅为往后提醒本身再也不犯相同的错误。工具

1、问题通过

  简单来讲,我作的是一个数据同步任务,将数据从es的一个type通过转换和操做同步到另外一个type中,下面统一说A同步到B,并且这个同步是周期性执行的,下面经过一个流程图:测试

  循环的部分的流程图不标准,你们懂意思就能够,程序其实很简单,除了引用的工具类,我就用了一个类就完成了上面的操做,每个过程是一个方法,方法结束后也会打印相应日志,并且测试网通过测试也是没问题的(这句话是否是很熟悉,若是你常常这么说,那就当心了),结果到了生产网就出事了,具体两个奇怪现象:spa

  1. 首次同步的时候,B端少数据
  2. 再次同步的时候,B端有重复数据

  由于B端开始是没数据的,因此出现上面两个问题只多是我程序的问题。日志

2、解决通过

  出现问题后,我直接蒙了,心想绝对不可能,而后一遍一遍的看程序,由于就一个类,因此看了好多遍,由于重复数据我是绝对认为不可能的,因此个人关注点就放在了怎么可能有重复,个人思路是两边所有查出来,以主机名加ip为key,value为自己,放到Map中。而后进行比较的。code

  1. 我把整个处理类从新写了一遍,去掉了其中用到的lambda表达式,如今想一想有点好笑,我怀疑lambda表达式有bug。
  2. 我把全部处理路径打印上日志,数量也都打印出来。

  通过这样后,依然没有发现问题,数据无缘无故丢失,重复数据出现的莫名其妙,由于生产网不能随意测试,因此每次出错都很难过,而测试网又复现不了(测试网数据是伪造的),心都碎了,最后又从新看代码,决定打印最详细的日志。主要是两个地方:blog

  1. Map的put操做前,先containsKey一下,若是有,打印日志说已有数据
  2. 以前打印数量日志的,所有打印实际内容

  第二步,按我以前的风格,是绝对不会这么作的,感受过低级,可是这么实在是没有办法了,而后从新测试,仔细看日志,发现一个异常现象,数据实际内容没有看,太多了,异常的是出现大量的已有数据的日志,这点引发个人注意,我核实过数据源,我这边提示重复的数据,在数据源处只有一个,而后我就去看个人工具类,查询工具类,发现了问题,程序以下:ip

batchSize在前边定义的为1000,及1000个批次查询一次
================================
public static List<String> queryAll(String[] index,String types){
  long count=count(index,types);
  List<String> result=new ArrayList<>();
  while(count>0){
    int from=0; <========== int size=0;
    if(count>batchSize){
      size=batchSize;
      count-=batchSize;
    }else{
      size=(int) count;
      count=0;
    }
    //经过 from 和 size 查询数据 并放到result中
    from +=size;
  }
  return result;
}

  仔细看标红那一行,我终于找到错误缘由了,个人同步类没有错,查询es的工具类写错了,改了之后重试才能够。开发

3、教训总结

3.1 工具类的使用

  平时积累一些工具类,确实能够大大减小通常开发的工做量,可是必定要通过严格的测试,否则基于对工具类的信任,不多会怀疑工具类会出错。同步

3.2 数据处理

  对于数据处理,若是假定不会有相同数据,也要containsKey一些,由于每每会有意想不到的数据产出,这种状况下出错了还很差查询。class

相关文章
相关标签/搜索