业务数据会重复上报和更新,用 ReplacingMergeTree 能保证查询绝对不重复吗?
我的判断
ReplacingMergeTree 只在后台合并时按排序键保留版本,不能保证刚写完或未 FINAL 的查询绝对无重复。
我会把业务唯一键放进 ORDER BY,再指定版本列,例如更新时间或单调版本。重复上报时写入新版本,后台 merge 最终可能清掉旧版本。但 merge 何时发生不确定,因此普通查询在一段时间内会同时看到多个版本。
FINAL 可以在查询时做去重,但对大范围扫描成本很高,不能所有线上报表都默认加。更稳妥的做法按场景选:
- 展示允许短暂重复:普通查询,等待后台合并;
- 小范围精确查询:带 FINAL,并严格限制分区;
- 统计必须准确:查询中按版本
argMax,或构建已去重的物化层; - 上游能幂等:尽量在写入前就减少重复。
删除旧版本还依赖相同排序键落在可合并范围内。分区键或排序键设计错了,ReplacingMergeTree 也不会跨分区神奇去重。
容易答偏踩坑误区
- 把最终一致去重理解成唯一约束。 写入阶段不会拒绝重复。
- 全表使用 FINAL。 查询成本可能随数据量显著上升。
- 版本列不单调。 乱序事件可能留下错误版本。