定时任务删除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;
    }

总结

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

相关推荐
wu8587734574 分钟前
向量数据库不是银弹:从枚举漏检到 ReACT 多轮召回的实践路径
前端·数据库·react.js
hsg7739 分钟前
简述:Jensen Huang‘s Footsteps网站全内容分析
前端·javascript·数据库
yuezhilangniao40 分钟前
MySQL 8.0.32 二进制安装脚本 和初始化 操作系统版本rocky86
数据库·mysql·adb
Trouvaille ~1 小时前
【Redis篇】Redis 主从复制:数据同步的原理与实现
数据库·redis·缓存·中间件·高可用·主从复制·后端开发
真实的菜1 小时前
Redis 从入门到精通(五):哨兵模式(Sentinel)—— 自动故障转移的完整原理与实战
数据库·redis·sentinel
唔661 小时前
(二)补充完整的数据库、中间件、MQTT、JAR后台和Web前端的部署脚本,全部一键自动化。
数据库·中间件·jar
六月雨滴2 小时前
Oracle 内存优化
数据库·oracle
学代码的真由酱2 小时前
MySQL数据库进阶-数据库设计实践-Java
数据库·mysql·数据库设计
遇事不決洛必達2 小时前
【数据库系列】本地映射云服务器Mysql的方法
服务器·数据库·mysql·定时任务
海鸥-w2 小时前
用python (fastapi)做项目第一天创建项目结构,数据建表,ORM配置安装,写第一个接口
数据库·python·fastapi