Redis批量操作--增加,删除,模糊查询

批量匹配删除redis缓存 使用spring boot2.x cache —— redis作为数据缓存方案时,可以采用@CacheEvict用来清除相应的数据缓存,但是@CacheEvict底层使用的redis的keys命令来遍历查找,但是keys太过暴力,不支持offset、limit参数,而且是遍历算法,复杂度为O(n),当redis中的数据量较大时,很容易造成服务卡顿阻塞,所以在正式环境keys这个命令是禁用的,那么@... 阅读详情

需求来源

虽然说redis是纯内存操作,效率非常高,但是一次插入或者删除千万级或者亿级的操作,如果采用单条处理的api,整体处理效率还是很低的;另外,如果处理的数据量过大,稍有不慎可能就会导致client端的内存溢出或者服务端的负载过高,基于此,下面提供几种优雅的批量操作的jedis api供批量操作场景使用

具体实现

下面将从批量添加,批量查询以及批量删除三个方面提供例子:

批量添加

批量添加有两种方式,即使用jedis自带的api进行操作,以及使用jedis的Pipeline api来进行操作

jedis自带api:

可以使用jedis自带的zadd(zset),sadd(set)和hmset(hash)方法来进行批量操作处理,其中sadd方法value可以传入一个可变长度的string,具体实现的时候可以传一个数组,通过List的toArray方法实现,zadd方法传入一个存放Key以及Score方法的map,hmset方法传入一个存放KV的map即可,但是上述方法有一个问题需要注意,需要控制数组或者map的大小,如果是循环插入数据,防止数据过大导致client端OOM

sadd:

List<String> list = new ArrayList<>(100);
for (int i = 0; i < 100; i++) {
  list.add(i+"");
}
jedis.sadd("testSet",list.toArray(new String[list.size()]));

zadd:

Map<String,Double> map = new HashMap<>();
for (int i = 0; i < 100; i++) {
  map.put(i+"",Double.valueOf(i));
}
jedis.zadd("testZSet",map);

hmset:

Map<String,String> map = new HashMap<>();
for (int i = 0; i < 100; i++) {
  map.put(i+"",i+"");
}
jedis.hmset("testHash",map);

Pipeline:

redis的管道(Pipelining)操作是一种异步的访问模式,一次发送多个指令,不同步等待其返回结果。这样可以取得非常好的执行效率,具体代码如下:

jedis = jedispool.getResource();
Pipeline pip = jedis.pipelined();
long startTime = System.currentTimeMillis();
for (int i = start; i < end; i++) {
  pip.set((10000000 + i) + "", (10000000 + i) + "");
}
pip.sync();

批量删除

批量删除即使用jedis自带的api操作即可(zset按照score来删除使用专用的api,不在此文讨论范围之内),只是value参数传递一个可变长度的字符串来处理,具体实现的时候可以传一个数组,通过List的toArray方法实现,同样需要控制数组或者map的大小,如果是循环插入数据,防止数据过大导致client端OOM,具体代码如下:

//kv
jedis.del(list.toArray(new String[list.size()]));
//hash
jedis.hdel("testHash",list.toArray(new String[list.size()]));
//set
jedis.srem("testSet",list.toArray(new String[list.size()]));
//zset
jedis.zrem("testZSet",list.toArray(new String[list.size()]));

模糊查询

理论上来说有两种方式可以实现模糊查询,一种是jedis的keys方法,另外一种是使用scan方式来迭代处理模糊查询,但是keys方法只是理论上的实现方式,无法在生产环境的大数据量场景下使用,所以scan就成了唯一通用的靠谱选择:

jedis的keys(不建议使用):

该方法返回所有匹配表达式的key:

KEYS * 匹配数据库中所有 key 。
KEYS j?va 匹配单一字符:如 java , jeva 和 juva 等。
KEYS j*va 匹配0-那个字符:如 jva 和 jaaaaava 等。
KEYS j[ae]va 匹配给定的单个字符:如 java 和 jeva ,但不匹配 juva 。

功能看起来比较丰富,但是实际应用中有时候会出现需要遍历redis中的所有键值的需求,比如清理没用的键等等。但是keys这个命令性能真的很差,而且会使相关数据加锁,从而影响其他操作,按照redis官方的说法:

Warning: consider KEYS as a command that should only be used in production environments with extreme care. It may ruin performance when it is executed against large databases. This command is intended for debugging and special operations, such as changing your keyspace layout. Don’t use KEYS in your regular application code. If you’re looking for a way to find keys in a subset of your keyspace, consider using SCAN or sets.

由于执行keys命令,redis会锁定数据,如果数据庞大的话可能需要几秒或更长,对于生产服务器上锁定几秒这绝对是灾难了,所以不建议在生产服务器上使用keys命令,尤其是大数据量的场景下。

scan(建议使用):

说完不建议使用的,再来说说建议使用的scan,从redis的官方文档上看,2.8版本之后SCAN命令已经可用,允许使用游标从keyspace中检索键。对比KEYS命令,虽然SCAN无法一次性返回所有匹配结果,但是却规避了阻塞系统这个高风险,从而也让一些操作可以放在server节点上执行。

需要注意的是,SCAN 命令是一个基于游标的迭代器。SCAN 命令每次被调用之后, 都会向用户返回一个新的游标,用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数, 以此来延续之前的迭代过程。同时,使用SCAN,用户还可以使用keyname模式和count选项对命令进行调整。SCAN相关命令还包括SSCAN 命令、HSCAN 命令和 ZSCAN 命令,分别用于集合、哈希键及有续集等。

下面是样例代码:

String cursor = ScanParams.SCAN_POINTER_START;
ScanParams scanParams = new ScanParams();
scanParams.match(prefix);
scanParams.count(10000);
while (true) {
  //使用scan命令获取数据,使用cursor游标记录位置,下次循环使用
  ScanResult<String> scanResult = jedis.scan(cursor, scanParams);
  cursor = scanResult.getStringCursor();// 返回0 说明遍历完成
  List<String> list = scanResult.getResult();
  for(String s : list){
    //TODO 业务逻辑
  }
  if ("0".equals(cursor)) {
    break;
  }
}

总结

虽然redis是一个基于内存的缓存神器,操作速度奇快,但是单次操作奇快也架不住数以千万甚至亿级的操作,此时如果还是用迭代的单条操作可能带来灾难性的后果,所以除了单条操作外,建议在实现中尽量使用批量操作。至于这几种批量操作叠加,如批量删除某些模糊匹配的key(数据量是千万级或者亿级)等相关场景,后续我会单独写一篇文章来说明该问题,敬请期待!

零基础玩转NILM:用nilmtk提取UKDALE电器数据的保姆级教程 本文为零基础用户提供了一份详细的NILM入门指南,重点讲解如何使用nilmtk工具包从UKDALE数据集中提取电器级用电数据。教程涵盖环境搭建、核心概念解析、数据提取实战及常见问题排查,帮助读者快速掌握非侵入式负荷监测的数据预处理关键步骤。 阅读详情

相关推荐

HAL库STM32CubeMX+DHT11温湿度传感器模块化驱动与OLED显示实战

本文详细介绍了基于HAL库和STM32CubeMX开发DHT11温湿度传感器模块化驱动的实战过程。通过精确的时序控制和模块化封装,实现了传感器数据采集,并结合OLED显示模块实时展示温湿度信息,为嵌入式开发者提供了完整的解决方案。

h6j7k8l9p0的博客 1131

Redis 批量删除指定模糊的key

Redis 批量删除指定模糊的key

一碗清深的博客 6422

KEIL5编译报错L6200E:__stdout重定义问题分析与解决

本文深入分析KEIL5编译报错L6200E中__stdout重定义问题的根源,指出因未完整定义__stderr导致与标准库stdio_streams.o冲突。提供完整重定义标准流、启用MicroLIB库等解决方案,帮助开发者彻底解决Symbol multiply defined错误,提升嵌入式开发效率。

uran的专栏 952

Redis

文章目录Redis一、Resid操作命令1.1启动1.2沟通命令1.3查看当前数据库中 key 的数目1.4切换库1.5删除当前库的数据1.6退出连接二、Redis Key命令2.1、keys 查看key值2.2、exists 判断是否存在2.3、expire 设置存活时间2.4、ttl 查看存活时间2.5、type 查看value数据类型2.6、del 删除key三、Redis数据类型3.1、String 字符串类型3.1.1基本命令(1)set get 插入 获取(2)incr decr i++ i--

qq_45414532的博客 2984

基于deepseek本地模型的本地知识库构建

通过以上步骤,你已经成功构建了一个基于 AnythingLLM 和 LM Studio 的本地知识库。这个系统不仅能够高效地存储和检索知识,还能结合强大的语言模型生成准确的回答。你可以根据自己的需求进一步扩展和优化这个系统,比如增加更多的文档格式支持、优化检索算法等。

qq_30178745的博客 1381

ESP32学习,驱动LED点阵屏,SD卡播放GIF动图

搬运就可以实现效果,如果有不足,请批评指正。下步该学一下如何文章上视频了,老是截图不方便展示效果。

u011625956的博客 1868

redis集群批量删除模糊key shell脚本

1. 命令删除: 1. 1批量删除Key Redis 中有删除单个 Key 的指令 DEL,但好像没有批量删除 Key 的指令,不过我们可以借助 Linux 的 xargs 指令来完成这个动作 redis-cli keys "*" | xargs redis-cli del //如果redis-cli没有设置成系统变量,需要指定redis-cli的完整路径 //如:/opt/redis/r...

zzhongcy的专栏 5629

保姆级教程:用中移ML307模组对接高德/OneOS定位服务,从配置apikey到解析+MLBSLOC状态码

本文详细介绍了如何使用中移ML307系列模组对接高德/OneOS定位服务,从配置apikey到解析+MLBSLOC状态码的全过程。涵盖高德定位服务和OneOS定位服务的配置步骤、常见错误处理及性能优化技巧,帮助开发者快速实现基站定位功能,提升物联网项目的定位精度和稳定性。

weixin_30632089的博客 504

Redis命令:列表模糊删除详解

在Redis中,列表(List)是一种非常常用的数据结构,允许存储多个有序的元素。然而,在实际应用中,可能会遇到需要删除列表中符合某种模式的元素的需求。本文将详细介绍如何在Redis中实现列表的模糊删除。由于Redis本身不直接提供模糊删除列表元素的命令,我们需要结合多种操作来实现这一需求。获取列表中所有元素。找出符合模式的元素。逐一删除这些元素。

helloGGGG的博客 591

NVIDIA Omniverse 技术浅析(三):NVIDIA RTX 技术

NVIDIA RTX 技术是 NVIDIA 推出的革命性图形渲染技术,旨在通过硬件加速和软件优化,实现高质量的实时图形渲染。RTX 技术在 NVIDIA Omniverse 平台中扮演着至关重要的角色,为其提供了强大的渲染能力。

m0_75253143的博客 350

Ceph入门到精通-更换osd、扩容osd

【代码】Ceph入门到精通-更换osd、扩容osd。

隔壁老瓦的专栏 1547

redis scan命令的count参数

今天看菜鸟教程对scan的描述 里面写到,count默认值为10。但是下面的示例中,第一次扫描却返回了11个元素。 这是为什么呢? 在看过官方的文档之后,发现描述中有一点。the server will usually return count or a bit more than count.... 服务有可能返回比count多一点的元素。 这是因为,在源码中对全局哈希表的每个哈希槽进行遍历,一旦发现拿到的元素个数大于了count,就停止遍历。当一个桶里有多个元素,这时,返回的元素就有可

weixin_51783482的博客 4721

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

redis-redisTemplate模糊匹配删除 通过key模糊删除,批量删除,批量查询,批量GET,批量设置相关数据

redis-redisTemplate模糊匹配删除 前几天需要一个模糊删除redis中key的功能, 没有多想, 直接         String key = "noteUserListenedPoi:*"; redisTemplate.delete(key); LOGGER.info("redis中用户收听历史被清空"); 结果发现不行...

zhuchunyan_aijia的博客 4万+

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Redis模糊查询及批量删除key

Redis模糊查询及标题批量删除key 一、登录redis,常用操作 登录本机redis服务器:redis-cli 输入密码验证:auth password 查看所有key:keys * 设置key:set key_name value [root@test ~]# redis-cli 127.0.0.1:6379> auth 123456 OK 127.0.0.1:6379> SELECT 4 OK 127.0.0.1:6379[4]> keys * 1) "a" 2) "cccc" 1

XIEXCMARCO的博客 1万+

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

【Redis】批量删除Key的三种方式

Redis 中有删除单个 Key 的指令 del,但好像没有批量删除 Key 的指令,不过我们可以借助 Linux的 xargs 指令来完成这个动作 1.使用命令行批量删除redis的key 语法 ./redis-cli -h IP -p PORT -a PASSWORD -n NUM keys 'key*' | xargs ./redis-cli -h IP -p PORT -a PASSW...

墩墩分墩 3万+

StackExchange.Redis加载Lua脚本进行模糊查询的批量删除和修改

前言 使用StackExchange.Redis没有直接相关的方法进行模糊查询的批量删除和修改操作,虽然可以通过Scan相关的方法进行模糊查询,例如:HashScan("hashkey", "*key*"),然后再使用相关的方法进行相关的批量操作,但是如果缓存数据量比较大,效率低下,那么可以使用Lua脚本进行模糊查询的批量操作:ScriptEvaluate(LuaScript.Prep...

a963508700的博客 713

redis通过key模糊删除,批量删除,批量查询,批量GET,批量设置相关数据

redis-redisTemplate模糊匹配删除 前几天需要一个模糊删除redis中key的功能, 没有多想, 直接 String key = "noteUserListenedPoi:*"; redisTemplate.delete(key); LOGGER.info("redis中用户收听历史被清空"); 结果发现不行, 后来测试发现模糊查询是可以用的, 找了下资料, 改成 Set<String> keys = redisTemplate.keys("noteUserLi..

Chery Qi的博客 1299

go中redis模糊查询到key并且批量删除它

我们在需要删除很多的redis key的时候,我们很有可能是无法知道所有的key的但是我们可以进行模糊查询后,进行逐个删除,(当然你得知道你所有的key都是你自己用的不能删除别人用的key)。这里批量删除也就需要用到反射来进行删除,直接贴代码: func (cf *Func) DelRedisCatchBatch(keys ...string) { for _, redisKey := range keys { keysMatch, err := providers.Redis.D...

tongweizhen的专栏 4371

redis关键字删除_【redis】模糊查询&删除操作

前言本文转载自博客园:1. 预备知识:redis支持的3种模糊查询操作元字符说明*0个或多个匹配?1个匹配[mnl]匹配m,n,l其中之一一、模糊搜索查询redis 默认有16个DB ,分别是 0-15redis-cli: 进入默认是第一个DB 0select n: 切换 DB1. *:0个或多个匹配例1:查找所有的key127.0.0.1:6379> select 9OK127.0.0.1...

weixin_29190573的博客 1272

使用shell批量操作redis-批量删除REDIS中keys *模糊查询的结果-批量执行命令文件及ln更新软链目标路径的问题-覆盖更新目录软链的情况

因为项目使用了多个REDIS实例,而在测试期间会经常需要清空redis里的数据,每次都单独连接几个redis清空数据确实太麻烦,于是想在shell里实现一个命令清除所有REDIS数据。

本博客记录了从2014年以来在工作学习中遇到的技术问题、解决方法以及部分个人人生经历、经验等内容。 2317

Redis 模糊查询删除操作

创建一条测试 数据 查询 创建: set name xiaoming 查询: get name 1、模糊搜索查询 Redis 模糊搜索 keys * select 2 2、删除指定key : # 删除所有以user开头的key 可以这样实现: # redis-cli keys "user*" 1) "user1" 2) "user2" # redis-cli keys "...

那些年的代码 2956

stackexchange.mysql_StackExchange.Redis加载Lua脚本进行模糊查询的批量删除和修改

前言使用StackExchange.Redis没有直接相关的方法进行模糊查询的批量删除和修改操作,虽然可以通过Scan相关的方法进行模糊查询,例如:HashScan("hashkey", "*key*"),然后再使用相关的方法进行相关的批量操作,但是如果缓存数据量比较大,效率低下,那么可以使用Lua脚本进行模糊查询的批量操作:ScriptEvaluate(LuaScript.Prepare(......

weixin_30272849的博客 472

Java 中如何批量删除 Redis 的数据?超详细,无套路

Java 中如何批量删除和查询 Redis 数据

跟着飞哥学编程(全栈联盟) 6898
上一篇: elasticsearch&kibana从6.0升级到7.9完整过程记录
下一篇: Redis集群与插槽分配(动态新增或删除结点)
梦回从前
博客等级 码龄18年 65粉丝 89原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值