Spring 分批处理 + 冷热数据分离:历史订单高效迁移与数据清理实战

在实际业务中,随着时间推移,订单量持续增长,若未及时进行数据治理,会造成数据库膨胀、查询缓慢、性能下降等问题。为了实现数据分层管理和系统高性能运行,我们在项目中采用了“冷热数据分离 + 分批迁移 + 数据清理”的综合方案。

本文将围绕以下几个核心点展开:

  • ✅ 为什么要进行冷热数据分离?

  • ✅ 如何用分批分页迁移历史订单?

  • ✅ 如何在迁移完成后安全删除同步表数据?


🔍 一、为什么要冷热数据分离?

随着订单业务增长,即使采用分库分表,数据总量依旧快速膨胀。对历史订单的访问热度远远低于进行中订单。因此我们有必要:

  • 热数据(15日内未完成订单)保存在主订单表,供高频访问;

  • 冷数据(15日前完成订单)归档到历史订单表,减少主库压力;

  • 提升整体系统性能和数据库查询效率。

❗注意:虽然阿里云 OSS 等对象存储价格低,但不支持复杂查询操作(如 SQL 聚合、分页、统计),无法满足用户和运营的历史订单检索与分析需求,因此必须选择支持查询的数据库,如分布式数据库 TiDB。


🔄 二、分批分页迁移:保证性能和稳定性

✨ 核心思想:

  • 一次迁移 1000 条数据,控制内存和 SQL 压力;

  • 使用 offset + limit 实现分页;

  • 按天定时迁移前一天完成的订单;

  • 保证数据完整性,支持失败重试。

🔧 迁移代码示例:

@Override
public void migrate() {
    log.debug("历史订单迁移开始...");
    int offset = 0, perNum = 1000;

    LocalDateTime startTime = DateUtils.getDayStartTime(DateUtils.now().minusDays(1));
    LocalDateTime endTime = DateUtils.getDayEndTime(DateUtils.now().minusDays(1));

    Integer total = historyOrdersSyncService.countBySortTime(startTime, endTime);
    if (total <= 0) return;

    while (offset < total) {
        baseMapper.migrate(startTime, endTime, offset, perNum);
        offset += perNum;
    }

    log.debug("历史订单迁移结束。");
}

🧹 三、迁移完成后,如何安全删除同步表数据?

在实现冷热分离过程中,我们使用中间同步表(用于异步迁移),为避免数据重复、节省空间,迁移完成后需及时删除同步表中已处理的数据。

为了防止误删或未迁移完全,我们加入了删除前校验机制

🛡 删除逻辑及校验示例:

@Override
public void deleteMigrated() {
    LocalDateTime startTime = DateUtils.getDayStartTime(DateUtils.now().minusDays(1));
    LocalDateTime endTime = DateUtils.getDayEndTime(DateUtils.now().minusDays(1));

    // 1. 检查是否存在可删除数据
    Integer totalOfDelete = historyOrdersServeSyncService.countBySortTime(startTime, endTime);
    if (totalOfDelete <= 0) {
        log.debug("无迁移服务单数据需要删除");
        return;
    }

    // 2. 校验迁移是否完整
    Integer totalMigrated = lambdaQuery()
        .between(HistoryOrdersServe::getSortTime, startTime, endTime)
        .count();

    if (NumberUtils.null2Zero(totalMigrated) <= 0 || totalOfDelete > totalMigrated) {
        log.error("服务单未完全迁移,同步数据删除失败");
        return;
    }

    // 3. 删除同步表中已迁移数据
    historyOrdersServeSyncService.deleteBySortTime(startTime, endTime);
}

⚠️ 删除保障机制:

校验项描述
数量比对同步表中“待删除数量”必须 ≤ 历史表中“已迁移数量”
分时间段删除与迁移都按天执行,避免大批量误删
日志记录失败及时报警,便于排查

🧠 四、架构补充说明

🔗 为什么不直接删除主表而使用同步表?

  • 避免直接影响主库性能;

  • 支持异步、可重试的迁移策略;

  • 可配合 binlog + MQ 实现实时同步机制。

💽 使用 TiDB 存储历史数据的优势:

  • 支持 MySQL 协议,易于对接;

  • 同时支持 OLTP 和 OLAP 查询(HTAP);

  • 分布式架构,水平扩展,适合大规模数据归档。


✅ 总结

历史订单迁移不仅是技术优化,更是数据治理的关键环节。

本方案通过以下几个方面保证效率与稳定:

  • 使用分页迁移,避免性能瓶颈;

  • 同步表中间态设计,解耦迁移流程;

  • 增加数据完整性校验与清理逻辑;

  • 结合 定时任务 实现每日自动迁移与清理;

  • 历史数据存储选择 支持 SQL 的分布式数据库(如 TiDB),满足查询与统计需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值