为什么写入ReplicatedMergeTree引擎表里的数据少了?

问题现象

使用JDBC接口向Clickhouse数据库中批量写入数据,数据表使用ReplicatedMergeTree引擎,写入完成后统计条数,发现比文件实际条数少了几条,多次测试均发现有此问题,且clickhouse日志中未发现错误信息。

  • clickhouse版本:21.9.2.1.
  • 写入数据量:>1000w条

原因排查

首先能想到的是数据问题,但是通过实验,发现同一批数据多次写入,每次丢失的条数还不一致,而且将数据表引擎切换为MergeTree后,数据一条没少,因此可以排除是数据本身的问题。然后在github上查找是否有人遇到过类似的问题,确实也有相关的issue:

  1. Data loss when using jdbc batch insert to ReplicatedMergeTree engine#5027
  2. Merge parts cause data loss #35704

通过评论区的只言片语中发现一点思路,那就是可能和数据去重有关,但是如何能验证呢?直到看到如下这篇文章:Insert Deduplication / Insert idempotency

总结一下要点:

  • Replicated*系列的表有一个插入去重的开关,且是默认开启状态,MergeTree引擎则是默认关闭;
  • 此去重是针对数据块级别的去重,即两个数据块如果有相同的记录,且顺序一致,则只会写入一次;这种设计是为了避免由于网络不稳定,导致同一批数据多次重复写入的问题;
  • 发生此现象在日志中的关键字是:Block with ID ... already exists locally as part ... ignoring it
  • 避免出现此现象的方法:在服务器配置中增加insert_deduplicate = 0的选项,关闭插入去重。

然后我在我自己的日志中检索了一下关键字,确实发现了如上所述的“证据”:
在这里插入图片描述
关闭插入去重的选型后,再次进行写入测试,发现数据不再丢失。

最后,是否真的有必要关闭这个选项呢?这个就要看你实际的应用场景了,其实仔细想想也许默认开启也是合理的,毕竟大部分情况数据重复录入是我们更不希望看到的。还有需要注意的就是这个开关只是控制块级别的数据去重的,即使开着,也无法保证写入的数据中一定不存在重复的记录,比如这些重复的记录出现在不同的数据块中的时候。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

普普通通程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值