在使用数据传输服务(DTS)同步/迁移包含TTL(Time-To-Live)索引的MongoDB集合时,可能会遇到任务产生延迟和数据不一致问题。本方案通过在同步/迁移期间临时修改目标端TTL索引的过期时间,确保数据同步/迁移的效率与一致性。
业务场景说明
在业务发展或架构升级中,需要将一个包含大量使用TTL索引的集合(例如,用户会话、日志、临时缓存数据)的MongoDB实例,通过DTS进行全量和增量数据同步/迁移至新的MongoDB实例。核心目标是确保同步/迁移过程平滑、高效,无数据丢失,且对业务影响最小。
然而,TTL索引的自动删除机制与DTS的数据同步机制存在冲突,可能导致同步/迁移任务产生延迟和数据不一致问题。原因分析如下:
增量写入时DELETE未命中数据,影响同步/迁移效率:源端TTL索引在删除过期数据时,会在Oplog中生成DELETE记录,DTS会同步该DELETE行为。如果此时目标端的TTL索引已删除相应的数据,将导致DTS在批量写入时出现DELETE未命中数据的情况,即MongoDB引擎返回的影响行数与预期行数不符,从而进入异常处理逻辑分支,影响迁移效率。
TTL索引非实时删除过期数据导致数据不一致:MongoDB的TTL索引删除数据并非实时执行,因此可能出现过期数据在源端依然存在,而在目标端已被删除的情况。这将导致数据不一致的现象。
示例案例:
由于MongoDB的Oplog/ChangeStream中对于UPDATE操作只记录被更新的字段,不记录数据更新前后所有字段的值,因此当UPDATE未命中数据时采用忽略此次UPDATE的策略。
时序
源端
目标端
1
业务INSERT数据
2
DTS同步INSERT数据
3
数据已过期但未被TTL索引删除
4
业务UPDATE数据(如:UPDATE了TTL索引字段,修改过期时间)
5
TTL索引删除数据
6
DTS同步UPDATE未命中数据,忽略此次操作
此时目标端MongoDB实例上会缺少这条数据。
最佳实践
为规避目标端MongoDB的TTL索引在删除过期数据时对DTS数据同步产生的影响,核心逻辑是在DTS同步/迁移的整个过程中(包括全量和增量同步/迁移)暂时停用目标端数据库的TTL索引功能,待同步/迁移切换完成后再行恢复。
流程如下:
同步/迁移前准备:在源端数据库,通过脚本识别并备份所有含TTL索引的集合及其过期时间配置。
检查并修改目标端配置:
请首先检查目标端是否已包含待同步/迁移的集合以及TTL索引。
若无:请先使用结构迁移将集合同步至目标端,并连接到目标端数据库,将已识别的TTL索引的过期时间修改为一个数据库允许的最大值,使其在同步/迁移期间不会触发自动删除。
若有:在启动DTS任务前,连接到目标端数据库,将已识别的TTL索引的过期时间修改为一个数据库允许的最大值,使其在同步/迁移期间不会触发自动删除。
执行DTS同步/迁移并监控:正常配置并启动DTS的全量及增量同步任务,并持续监控关键指标以确保同步/迁移过程的稳定性和健康度。由于目标端的TTL索引已失效,DTS可以无冲突地同步源端的所有插入、更新和删除操作,避免了效率下降和数据不一致的风险。
在DTS控制台创建并启动数据同步/迁移任务。
在同步/迁移过程中,重点监控以下指标:
DTS任务延迟:在DTS控制台任务详情页查看,确保增量同步延迟处于较低水平。
目标端实例存储空间使用率:在目标端MongoDB实例中查看。由于目标端数据不会过期,存储空间使用量会持续增长,需确保空间充足。
同步/迁移后恢复:在DTS完成同步且业务流量切换至新实例后,使用同步/迁移前备份的配置,将目标端数据库的TTL索引恢复至原始的过期时间。恢复后,MongoDB的后台线程会开始清理在同步/迁移期间积压的过期文档。
注意事项:
在DTS增量同步/迁移过程中,源端TTL索引删除过期数据的行为将被DTS同步至目标端。
在延长目标端TTL索引的过期时间后,若在DTS全量同步/迁移期间或DTS增量同步/迁移存在延迟,目标端MongoDB将会出现源端已过期的数据。因此,需根据源端的写入量适当扩大目标端MongoDB实例的存储空间。
若同步对象中的TTL索引过期时间较短(例如在临时数据或日志场景中),则不建议进行存量数据的同步/迁移。在极端情况下,可能会出现全量同步/迁移的数据在目标端迅速过期,从而导致目标端数据为空的现象。业务方面可考虑采用双写或仅进行增量同步/迁移的方案。