从MySQL提取每日数据变更同步至Druid时序库并实现去重的方案咨询
首先回答你的核心问题:存在成熟的落地方案可以实现binlog读取过程中去重、仅保留指定时间段内最新变更的需求,不需要复杂的定制开发,整体可以分为三层实现:
1. 利用binlog原生属性做去重依据
MySQL binlog的行变更事件本身自带了三个可以直接用来做版本判断的字段,不需要额外加业务埋点:
- 对应数据行的唯一主键:用来区分不同的业务数据行,是去重的核心标识
- 全局事务ID(
GTID)或者binlog文件名+偏移量:是binlog事件的全局唯一标识,数值越大代表事件生成时间越晚 - 事件执行时间戳:对应变更在MySQL中实际执行的时间,用来匹配你要筛选的每日/指定时间范围
2. 消费链路中间层做聚合去重
在binlog消费链路中加一层轻量缓存做聚合,即可直接过滤掉中间的重复变更:
- 先按时间戳过滤出你指定时间范围内的事件,超出范围的直接丢弃
- 缓存中按主键存储对应数据行的最新记录,每次收到新的同主键变更时,对比binlog偏移量/GTID的大小,只有更新的事件才会覆盖缓存中的旧记录
- 到你设定的时间窗口截止时间(比如每日0点),把缓存中所有主键对应的最新记录批量写入Druid即可,这一批数据就是指定时间段的全量最新快照
3. Druid存储层兜底去重
即使消费链路出现重试、重复投递的异常,Druid本身的特性也可以保证存储层不会有重复数据:
- 写入时把主键设为Druid的维度字段,同时开启
rollup聚合,设置MAX(binlog_offset)/MAX(gtid)作为聚合指标,查询时只要过滤出每个主键对应的最大偏移量记录,就是对应的最新版本 - 如果你使用Druid 0.19及以上版本,还可以直接开启唯一键约束,写入时自动覆盖相同主键的旧记录,直接从存储层保证单主键只有最新一条记录
现有工具的现成支持
常用的开源binlog消费工具已经内置了相关能力,不需要自己从零实现:
- Canal可以配置时间范围过滤+增量聚合规则,直接输出每个主键的最新变更记录
- Debezium可以开启
ExtractNewRecordState转换器,自动过滤中间变更,只保留每个主键在指定时间窗口内的最终状态
内容的提问来源于stack exchange,提问作者sankar
相关产品推荐
相关产品推荐

