SpringBoot集成Redis业务功能 02、定时任务+Redis删除特定前缀key的优雅实现

简介: SpringBoot集成Redis业务功能 02、定时任务+Redis删除特定前缀key的优雅实现

方案思路


之前重置玩家每日积分3次是采用redis来实现的,每位玩家在进行重置积分操作时,就会进行存储reids的键值对,key时拼接玩家uid的字符串,value则是每日次数,在set时是设置24小时也就是1天过期。


基于此方案上,我想了想那么就使用定时任务+批量删除redis前缀key来实现比较合适。


其中的批量删除redis的前缀key有两种方案实现:


直接使用keys命令来进行匹配所有的key,然后进行批量delete删除(不推荐)。【问题:数据量达到几百万,keys这个指令就会导致 Redis 服务卡顿,因为 Redis 是单线程程序,顺序执行所有指令,其它指令必须等到当前的 keys 指令执行完了才可以继续 。】

使用scan渐进式遍历获取到所有的key,实现keys的效果,需要进行多次scan**(推荐)**。【好处:采用渐进式遍历的方式来解决keys命令可能带来的阻塞问题,每次scan命令的时间复杂度是 O(1) ,但是要真正实现keys的功能,需要执行多次scan。】

redis+lua脚本(暂未使用)。

当前实现方案中就是使用的scan渐进式遍历来进行获取。


实现方案


批量删除redis的key


关于SpringBoot如何集成Redis见:SpringBoot整合篇 04、Springboot整合Redis


在下面代码中我们使用到了MultiKeyCommands,这个类是jedis里的,那么我们就需要将redis启动器中的lettuce替换为jedis,如下来进行排除依赖并添加jedis依赖:


<!--redis配置-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <exclusions>
        <exclusion>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!--  排除lettuce,使用jedis      -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <scope>compile</scope>
</dependency>



下面scan方法已经封装好了,使用方式:调用方法,直接传入要匹配的前缀key即可使用scan返回所有匹配到的key。


一轮是获取1000个的。
/**
 * redis工具类
 */
@SuppressWarnings(value = { "unchecked", "rawtypes" })
@Component
public class RedisCache {
   /**
     *
     * @param key 要匹配的key前缀
     * @return 匹配到的批量key值
     */
    public Set<String> scan(String key) {
        return (Set<String>) redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
            HashSet<String> keys = new HashSet<>();
            JedisCommands commands = (JedisCommands) connection.getNativeConnection();
            MultiKeyCommands multiKeyCommands = (MultiKeyCommands) commands;
            //组装scan请求参数(匹配内容+请求数量)
            ScanParams scanParams = new ScanParams();
            scanParams.match("*" + key + "*");
            scanParams.count(1000);
            //执行scan命令(批量去获取)
            ScanResult<String> scan = multiKeyCommands.scan("0", scanParams);
            while (scan.getCursor() != null) {
                keys.addAll(scan.getResult());
                if ("0".equals(scan.getCursor())) {
                    break;
                }
                scan = multiKeyCommands.scan(scan.getCursor(), scanParams);
            }
            return keys;
        });
    }
}


定时任务


定时任务使用Spring给我们提供的,按照如下进行配置即可:


1、在启动器上开启定时任务注解


@EnableScheduling //开启定时任务


2、注册Bean对象,在指定的方法上添加定时任务注解


对于定时任务的cron表示式可用在线工具生成:cron表达式生成工具


生成的是7位,而@Scheduled中的cron要求是6位,我们只需要把最后一位表示年的去年即可。

package com.chuangmeng.horserace.tasks;


import com.chuangmeng.horserace.constant.RedisKeyConstant;
import com.chuangmeng.horserace.utils.RedisCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import java.util.Set;
@Component
@Slf4j
public class PlayerTask {
    @Autowired
    private RedisCache redisCache;
    /**
     * 每天晚上12点重置玩家积分
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void resetPlayerIntegral() {
        String key = "xxx";
        Set<String> keys = redisCache.scan(key);
        log.info("相关重置积分的key为:" + keys);
        if (!ObjectUtils.isEmpty(keys)) {
            redisCache.deleteObject(keys);
            log.info("重置玩家积分完成!");
        }
    }
}



完成重置操作也很简单,就是调用下scan()方法,然后拿到所有的key,执行删除命令就好。


测试

使用redis手动来去进行匹配前缀key:


# 方式一:使用keys来进行匹配
keys "chuangmeng:horserace:resetimtegral:*"
# 方式二:使用scan来进行渐进式获取,第一次设置游标为0,会响应过来两个数据,一个是下一次你要进行遍历开始的游标,以及一组匹配的数据。若是下一组游标为0,那么就无需进行scan获取了,已经获取了全部
scan 0 match "chuangmeng:horserace:resetimtegral:*"
scan 17 match "chuangmeng:horserace:resetimtegral:*"
# 删除key
del chuangmeng:horserace:resetimtegral:3334322232  chuangmeng:horserace:resetimtegral:12364322232


对于程序的话我们测试可以设置个1分钟定时任务或者直接在test中调用方法测试即可!

相关文章
|
XML 测试技术 API
利用C#开发ONVIF客户端和集成RTSP播放功能
利用C#开发ONVIF客户端和集成RTSP播放功能
5041 123
|
测试技术 数据处理 调度
Dataphin功能Tips系列(57)「预览」vs「运行」:离线集成的神奇按钮
在数据开发过程中,使用Dataphin处理离线集成任务时,可能遇到数据过滤和字段计算组件配置正确性的验证问题。通过「预览」功能,可快速验证处理逻辑而不影响目标表;对于需要调度的任务,担心资源占用和耗时超出预期时,可使用「运行」功能进行全流程测试,评估实际耗时与资源消耗。「预览」适合逻辑验证,「运行」用于真实环境模拟,两者结合助力高效开发与调试。
426 5
|
SQL Java 关系型数据库
Dataphin功能Tips系列(53)-离线集成任务如何合理配置JVM资源
本文探讨了将MySQL数据同步至Hive时出现OOM问题的解决方案。
502 5
|
SQL 运维 关系型数据库
【产品升级】Dataphin V5.0版本发布:助力出海业务、增全量一体集成、异步调用API等更多功能等你发现
Dataphin是瓴羊推出的智能数据建设与治理平台,基于阿里巴巴内部实践,提供一站式数据建设与治理能力。V5.0版本研发新增支持Databricks作为离线计算引擎、支持MySQL数据库一键增全量同步、支持管理Hudi、Delta Lake表等;资产运营与消费持续提效,支持批量编辑目录名称及描述、Quick BI仪表板的上架管理等功能,增加资产可用性与盘点效率。
542 8
|
存储 JSON 前端开发
Django集成图片验证码功能:基于django-simple-captcha实现
在Web应用开发中,验证码是防止恶意攻击、自动化脚本滥用的重要手段。本文将介绍如何使用django-simple-captcha库在Django项目中快速集成图片验证码功能,包括安装配置、核心实现代码及使用方法。
327 0
|
传感器 供应链 物联网
农业单亩价值创造功能技术集成的概念与内涵
农业单亩价值创造的技术集成,通过系统性创新打破传统单一模式,融合现代科技与生态理念,提升资源效率、经济效益和生态价值。其核心在于技术协同,实现精准农业、智能装备和生物强化等多维联动,推动经济、生态和社会价值统一。同时,注重资源集约化与循环化利用,延伸产业链并升级价值链,从短期高产转向长期可持续发展。政策与制度创新支撑技术普惠,未来需因地制宜解决技术适配性和成本收益平衡问题,重塑农业评价体系,实现高质量发展。
|
存储 分布式计算 供应链
Dataphin功能Tips系列(51)-支持增全量一体实时集成
本文介绍了基于增全量一体实时集成的库存管理与分析解决方案。通过将业务中台的库存表同步至MaxCompute Delta表,实现离线与实时分析的统一支持。相比传统方案,该方法确保数据一致性,优化存储成本,降低维护复杂度,并大幅提升实时性,满足高效库存管理需求。
346 5
|
资源调度 安全 数据安全/隐私保护
Cyber Triage 3.14 发布,带来全新用户界面、Hayabusa 集成、基线设定等功能
Cyber Triage 3.14 发布,带来全新用户界面、Hayabusa 集成、基线设定等功能
295 0
Cyber Triage 3.14 发布,带来全新用户界面、Hayabusa 集成、基线设定等功能
|
监控 安全 Java
Java 开发中基于 Spring Boot 3.2 框架集成 MQTT 5.0 协议实现消息推送与订阅功能的技术方案解析
本文介绍基于Spring Boot 3.2集成MQTT 5.0的消息推送与订阅技术方案,涵盖核心技术栈选型(Spring Boot、Eclipse Paho、HiveMQ)、项目搭建与配置、消息发布与订阅服务实现,以及在智能家居控制系统中的应用实例。同时,详细探讨了安全增强(TLS/SSL)、性能优化(异步处理与背压控制)、测试监控及生产环境部署方案,为构建高可用、高性能的消息通信系统提供全面指导。附资源下载链接:[https://pan.quark.cn/s/14fcf913bae6](https://pan.quark.cn/s/14fcf913bae6)。
2824 0
|
缓存 前端开发 API
(网页系统集成CAD功能)在线CAD中配置属性的使用教程
本文介绍了Mxcad SDK在线预览和编辑CAD图纸的功能及配置方法。通过Vite、CDN或Webpack实现集成,用户可自定义设置以满足项目需求。主要内容包括:1)`createMxCad()`方法的初始属性配置,如画布ID、WASM文件路径、字体加载路径等;2)`MxFun.setIniset()`方法提供的更多CAD初始配置;3)`McObject`对象API用于动态调整视图背景色、浏览模式等。此外,还提供了在线Demo(https://demo2.mxdraw3d.com:3000/mxcad/)供用户测试实时效果。

热门文章

最新文章