定时任务删除MongoDB历史数据

前言

MongoDB数据过多,导致存储成本飙升,为了降低成本,需要将历史数据删除。

删除逻辑

添加配置文件控制删除逻辑

XML 复制代码
syncconfig:
  deleteMongoConfig:
    #同步状态,true同步,false不同步
    syncStatus: true
    #删除数据的时间,一个月前
    deleteDays: 31
    #分布式锁key
    lockRedisKey: order.sync.deleteMongo
    #每次删除数量
    limit: 2

配置类

java 复制代码
@ConfigurationProperties(prefix = "syncconfig")
@Configuration
@RefreshScope
@Data
public class SyncConfig {
    private DeleteMongoDto deleteMongoConfig;

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class DeleteMongoDto {
        /**
         * 同步状态,true同步,false不同步
         */
        Boolean syncStatus = false;
        /**
         * 删除的天数(createTime)
         */
        Integer deleteDays = 186;
        /**
         * locakRedisKey,用于做分布式锁,防止定时任务执行时间较长,两个任务重叠执行
         */
        String lockRedisKey;
        /**
         * 每次数量
         */
        Integer limit = 1000;
    }
}

核心代码

java 复制代码
    @PostMapping("/deleteMongo")
    public BaseResponse<String> deleteMongo() {
        return orderService.deleteMongo();
    }
java 复制代码
 @Override
    public BaseResponse<String> deleteMongo() {
        //获取配置信息
        SyncConfig.DeleteMongoDto deleteMongoDto = syncConfig.getDeleteMongoConfig();
        //判断同步是否开启
        if (deleteMongoDto == null || !deleteMongoDto.getSyncStatus()) {
            log.info("deleteMongosyncStatus=false,not sync");
            return ResponseUtils.success("deleteMongosyncStatus=false,not sync");
        }
        Boolean lockStatus = false;
        try {
            lockStatus = redisLockService.acquireLock(deleteMongoDto.getLockRedisKey());
            if (!lockStatus) {
                log.info("deleteMongo get lock fail,not sync");
                return ResponseUtils.fail("deleteMongo get lock fail,not sync");
            }
            //根据时间获取orderId
            Long orderId = getOrderId(deleteMongoDto.getDeleteDays());
            Query query = new Query(Criteria.where("orderId").lt(orderId));
            query.limit(deleteMongoDto.getLimit());
            // 使用投影来只选择orderId字段
            query.fields().include("orderId");
            // 这里不用分页是因为分页会查询total效率较低,数据量大的时候耗费资源
            /*Pageable pageable = PageRequest.of(0, deleteMongoDto.getLimit());
            Page<orderDao> page = orderDao.findByOrderIdLessThan(orderId, pageable);
            List<Order> list = page.getContent();*/
            List<Order> list=mongoTemplate.find(query,Order.class);
            for (Orderitem :
                    list) {
                orderDao.deleteById(item.getOrderId());
            }
            int count = 0;
            if (CollectionUtils.isNotEmpty(list)) {
                count = list.size();
            }
            return ResponseUtils.success("deleteMongo success,count:" + count);
        } catch (Exception ex) {
            log.error("deleteMongo Exception:" + ex.getMessage());
            return ResponseUtils.fail(ex.getMessage());
        } finally {
            //释放分布式锁
            if (lockStatus) {
                redisLockService.releaseLock(deleteMongoDto.getLockRedisKey());
            }
        }
    }
    //生成半年前的orderId
    private Long getOrderId(Integer deleteDays) {
        LocalDateTime deleteTime = LocalDateTime.now().minusDays(deleteDays);
        // 将LocalDateTime转换为毫秒值
        ZonedDateTime utcZonedDateTime = deleteTime.atZone(ZoneId.systemDefault());
        long milliseconds = utcZonedDateTime.toInstant().toEpochMilli();
        Long orderId = (milliseconds / 1000) << 32;
        return orderId;
    }

总结

这里是简单的删除历史数据逻辑,可以参考执行,分布式锁是为了防止重复调用,实际使用的时候也可以不用分布式锁。然后定时调用这个删除接口即可不断的删除历史数据了

相关推荐
塔能物联运维5 分钟前
存量机房低成本改造:塔能两相液冷实现投入与效益双赢
大数据·数据库·人工智能
2401_850491656 分钟前
PHP 中处理会话数组时的类型错误解析与修复指南
jvm·数据库·python
ㄟ留恋さ寂寞9 分钟前
如何修改数据库实例名_ORACLE_SID环境变量重命名实战
jvm·数据库·python
专注API从业者15 分钟前
Open Claw 实战:用淘宝商品 API 实现自动化监控选品系统
大数据·运维·数据库·自动化
2401_8504916518 分钟前
使用 curl 调用 Go 标准库 RPC 服务(JSON-RPC 协议详解)
jvm·数据库·python
CLX050536 分钟前
SQL排查JOIN查询中索引失效的常见情况_数据类型隐式转换
jvm·数据库·python
onebound_noah40 分钟前
1688商品获取全解析:API与爬虫双轨实战指南
大数据·数据库·爬虫
treacle田1 小时前
达梦数据库-物理备份与还原-(DISQL联机全备+增量备份+归档进行不完全恢复或完全恢复-实践示例)-记录总结
数据库·达梦数据库物理备份还原恢复
许长安1 小时前
Redis 渐进式 rehash:为什么要分批搬迁哈希表
数据库·redis·散列表
测试员周周1 小时前
【Appium 系列】第09节-数据驱动测试 — YAML 数据 + parametrize
服务器·数据库·人工智能·python·测试工具·语言模型·appium