数据同步
更新: 11/3/2025 字数: 0 字 时长: 0 分钟
第一阶段:全量同步
- 需求:定期将公司的订单数据从业务库同步到数据分析仓库。
- 方案:使用定时任务,每天将订单表的所有数据查询出来,然后全部插入到数据仓库。
- 问题:
- 性能瓶颈:随着数据量从 1 万增加到 10 万,同步时间从 3 小时增加到 30 小时,呈线性增长,无法满足时效性。
- 不可靠:如果因网络等原因同步失败,任务会中断,且问题可能到第二天才被发现。
第二阶段:增加容错机制
- 需求:当同步任务失败时,需要能及时感知并处理,保证数据不错乱。
- 改进:
- 错误感知:增加错误日志记录,并通过邮件通知管理员。
- 数据一致性:引入事务,如果同步失败,将数据库回滚到同步前的状态,避免产生脏数据。
- 问题:虽然能感知失败,但核心的性能问题依然没有解决。
第三阶段:增量同步
- 需求:解决全量同步带来的性能问题,缩短同步任务的执行时间。
- 方案:改造定时任务,约定每天零点执行,只同步前一天新增或变更的数据。
- 改进:
- 初步方案:使用订单的
创建时间作为增量同步的标志。 - 问题发现:该方案只能同步新增订单,无法同步状态发生变化的订单(如付款后又退款)。
- 优化方案:使用
更新时间字段作为增量同步的标志,这样无论是新增还是修改的数据都能被捕获。
- 初步方案:使用订单的
- 问题:在大促期间,单次增量查询的数据量激增,将大量数据一次性加载到内存,导致服务器内存溢出(OOM),服务宕机。
第四阶段:分批处理
- 需求:避免因单次处理数据量过大导致内存溢出。
- 改进:
- 分页查询:将一次性查询改为分批、分页查询。例如,每次只从数据库查询 100 条数据进行同步。
- 优点:显著降低了单次处理的内存压力。如果某一批次失败,只需回滚并重试该批次,而无需全部重来。
- 问题:在分页查询的过程中,如果有新的数据插入或已有数据被更新,会导致分页的
OFFSET发生偏移,从而造成数据丢失。例如,第一页同步完成后,第二页的数据因状态更新导致其更新时间变化,查询下一页时就会跳过某些记录。
第五阶段:游标机制
- 需求:解决动态数据集中使用
OFFSET分页导致的数据丢失问题。 - 改进:
- 自定义分页起点:不使用
OFFSET,而是采用一个稳定且递增的字段(如自增主键ID)作为“游标”。 - 实现:每查询并同步完一批数据后,记录下这批数据的最大 ID 作为新的游标值。查询下一批时,条件变为
WHERE ID > last_max_id。 - 优点:
- 防止数据丢失:ID 是唯一的,不受数据更新影响,保证了分页的稳定性。
- 提升性能:避免了
OFFSET深度分页带来的性能问题。 - 断点续传:游标可以作为同步进度的断点,任务失败后可以从上次记录的 ID 处继续同步。
- 自定义分页起点:不使用
第六阶段:性能优化(并发 + 批量)
- 需求:随着业务量增长到百万级,老板要求每两小时同步一次,任务执行速度需要进一步提升。
- 改进:
- 批量写入 (Batch Insert):将之前一条一条插入数据的方式,改为执行一条批处理 SQL 语句,一次性插入同一批次内的多条数据,大幅减少与数据库的通信次数。
- 并发执行 (Multi-Threading):启动多个线程,每个线程独立负责一个批次的数据同步。变串行执行为并行执行,充分利用服务器的多核 CPU 资源,大幅提升整体效率。
第七阶段:实时同步(CDC + 消息队列)
- 需求:老板希望给投资人展示实时业务监控,数据同步需要达到“实时”级别。
- 改进:
- 引入 CDC (Change Data Capture):通过 Canal、Debezium 等工具监听数据库的
binlog,实时捕获数据的任何增、删、改操作。 - 引入消息队列 (Message Queue):
- CDC 捕获到的变更消息被发送到消息队列(如 Kafka)。
- 同步程序作为消费者,从中转站(消息队列)拉取数据并写入数据仓库。
- 优点:
- 实时性:用户下单后,百毫秒内即可在监控大屏看到。
- 解耦与削峰:消息队列作为缓冲,即使在订单洪峰期,也能保证数据不丢失,平滑处理。
- 引入 CDC (Change Data Capture):通过 Canal、Debezium 等工具监听数据库的
第八阶段:企业级方案完善
- 需求:在双十一大促期间,实时同步系统面临巨大流量冲击,出现了数据重复、乱序和消息堆积等问题。
- 问题与解决方案:
- 数据重复:
- 问题:消息系统可能重复投递消息。
- 解决:引入幂等机制。为每条消息生成唯一编号,消费端记录已处理的消息编号,遇到重复编号则直接丢弃。
- 消息乱序:
- 问题:同一个订单的状态变更消息顺序错乱(如“已付款”先于“已下单”被处理)。
- 解决:引入分区机制。通过订单 ID 等业务标识进行哈希,将相关消息发送到同一个消息队列分区,保证分区内消息的顺序性。
- 消息堆积:
- 问题:消费速度跟不上生产速度,导致数据同步延迟。
- 解决:搭建消费集群和动态扩容。增加消费者实例,并根据消息堆积情况自动扩缩容,提升整体处理能力。
- 数据校验缺失:
- 问题:缺乏最终一致性的校验手段。
- 解决:引入数据对账机制。定期检查同步前后的数据是否一致,确保数据同步的准确性。
- 重复造轮子:
- 反思:上述大部分复杂问题,都可以通过使用成熟的企业级数据同步工具(如 DataX, Canal, Debezium)来避免,无需自己从零开始编写所有代码。
- 数据重复:
