最近有个项目需要把大量的空间数据从postgis同步到elasticsearch中,我采用了JPA分页读取的方式把表中所有的记录读取出来,通过saveAll保存到elasticsearch索引中,数据量少的时候,发现一切都好,但是当数据量很大的时候,发现elasticsearch索引的记录跟数据库中的记录不一致,刚开始以为是elasticsearch的问题,是不是elasticsearch哪里没有配置好,或者是因为负载太大,出现了数据丢失,花了大量时间找elasticsearch的原因。后来发现,在插入记录的时候,会有大量的记录状态为deleted,而deleted+count正好等于数据库表中的记录之和(类似下图)。
一定是我的ID出现重复了,使得插入操作变成更新操作了,但是elasticsearch的ID使用的是数据库表中的主键,是不可能重复的。没办法,在代码中加入了一个Set用于保存主键,如果主键有重复就抛出异常,还真是抛出了异常,问题终于找到了,是因为我使用了JPA的findAll进行分页读取,findAll如果不对主键进行排序,就会出现不同页中会有重复记录的现象!!!修改了代码,用findAllByOrderByUuid进行读取,问题解决。网上查了一下,用findAll读取Oracle数据库也会出现相同的情况,MySQL没有试过,不知道。在此做个记录,希望对大家有所帮助。
评论区