SpringBoot中RedisCluster的scan命令实践

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 线上环境redis key过期一直很头疼,自动过期用户可能会给用户展示过期数据无法忍受,可是又无法掌握固定的key,redis给我们提供了高性能的scan操作,可千万不能用keys * 了!SpringBoot2.0升级使用lettuce替换了jedis为默认的reids连接工具。

为什么要用 scan 获取key

redis作为缓存服务应用非常广泛,保证应用有较强的响应性能缓存是会大量使用的,同时也就造成了redis中的缓存key非常之多,集群中几十万key更是常有,由于redis是单线程模型应用(redis并不是单线程,只是某个阶段只有一个线程,命令接收、命令处理、结果响应都是各一个线程)一个复杂操作直接会阻塞后续命令的执行,于是诞生了scan命令。

什么场景使用

对缓存key进行批量过期但是无法知道具体的key值,此时可以使用scan扫描出具体key后进行统一过期。

如何使用

之前在网上找了很多关于springboot reidsTemplete的scan操作代码,遗憾的是有很多操作都是无法在集群环境进行scan操作的。

上面咱们有有说到springboot2.0后使用lettuce作为redis连接工具,lettuce十分强大并且已经实现RedisCluster的scan操作(底层实现是逐个扫描分片),已阅读源代码,同时支持单机、主从及集群模式。

直接上代码

Set<String> keys = redisTemplate.execute((RedisConnection connection) -> {
    Set<String> keySet = CollUtil.newHashSet();
    //定义起始游标,获取lettuce原生引用,定义scan参数
    ScanCursor scanCursor = ScanCursor.INITIAL;
    RedisKeyAsyncCommands commands = (RedisKeyAsyncCommands) connection.getNativeConnection();
    ScanArgs scanArgs = ScanArgs.Builder.limit(1000).match(patternKey);
    try {
        do {
            //最少scan一次,当返回不为空时将扫描到的key添加到统一key列表中
            KeyScanCursor<byte[]> keyScanCursor = (KeyScanCursor) commands.scan(scanCursor, scanArgs).get();
            if (keyScanCursor != null) {
                if (CollUtil.isNotEmpty(keyScanCursor.getKeys())) {
                    keyScanCursor.getKeys().forEach(b -> keySet.add(new String(b)));
                }
                scanCursor = keyScanCursor;
            } else {
                scanCursor = ScanCursor.FINISHED;
            }
        } while (!scanCursor.isFinished());
    } catch (Exception e) {
        LOG.error("redisClient scanKey fail patternKey:[{}]", patternKey, e);
    }
    return keySet;
});
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
9月前
|
消息中间件 弹性计算 数据可视化
SpringBoot 整合 Elastic Stack 最新版本(7.14.1)分布式日志解决方案,开源微服务全栈项目【有来商城】的日志落地实践
SpringBoot 整合 Elastic Stack 最新版本(7.14.1)分布式日志解决方案,开源微服务全栈项目【有来商城】的日志落地实践
|
1月前
|
Java Unix Shell
springboot项目重启的shell命令
springboot项目重启的shell命令
16 0
|
4月前
|
Java Spring
spring boot aop 实践---记录日志
spring boot aop 实践---记录日志
28 0
|
9月前
|
NoSQL 前端开发 Java
redis的发布/订阅(命令、普通工程、springboot实现)
小美老师给五年级三班上数学课的时候,实现给所在班级进行实时推送数学课程的活动(广播通信)
|
4月前
|
Java Spring 容器
Spring Boot启动命令参数详解及源码分析
Spring Boot启动命令参数详解及源码分析
154 1
|
6月前
|
Java 编译器 数据格式
SpringBoot快速实践
启动一个SpringBoot项目 如果你觉得使用官网来创建太慢了,那你直接把以前项目的依赖粘过来就行了: 一个是父工程的依赖: <!--指定了一个父工程,父工程中的东西在该工程中可以继承过来使用--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.0</version> </parent> <!--JDK 的版本-->
20 0
|
8月前
|
存储 缓存 安全
|
8月前
|
Java 应用服务中间件 Docker
Spring Boot入门(二十七) 之 Docker常用命令
Spring Boot入门(二十七) 之 Docker常用命令
|
10月前
|
缓存 JSON NoSQL
低版本SpringBoot Redis缓存旁路设计改造方案实践
低版本SpringBoot Redis缓存旁路设计改造方案实践
278 0
|
存储 设计模式 NoSQL
Springboot集成Tile38客户端之Set命令实现
Springboot集成Tile38客户端之Set命令实现
77 0