

【Redis技术专区】「实战案例」谈谈使用Redis缓存时高效的批量删除的几种方案
source link: https://blog.51cto.com/alex4dream/6021101
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.


之前我们的服务,在上线的时候发现有一些大Key的使用不是很规范,特别是没有设置过期时间,因此导致redis中内存的数据越来越多,目前Redis节点的内存已经快撑不住了。所以根据缓存键的规则去批量删除这些数据,比较常见的就是按前缀去删除。
现在由于不得以为的原因要删除这几百个Key-Value的数据,这个时候我们肯定就要把缓存键全部删除掉。一般情况下在Redis中是可以很容易去实现的。但是如果在不阻塞业务的前提下,并且以高效的方式进行清理内存数据。就需要好好想想办法了。
批量删除redis数据方法
利用的是Linux的xargs命令
我们可以通过redis-cli的模式,进行访问之后登录到了Redis-Server服务,由于是必须要使用Linux的xargs命令,所以必须要连带指令在Linux环境,而不能提前通过redis-cli进行登录到redis-server服务。否则会报错说xargs
无效。
上面的指令主要由三部分连接组成:
- redis-cli -h [ip] -p [port ] -a [password]:主要需要用于登录到redis-cli的只处理操作。
- keys "prefix*":随后主要是通过redis-cli的命令进行 keys指令进行匹配某前缀相关的数据集合。
- | xargs redis-cli -h [ip] -p [port ] -a [password] del:主要是通过管道符进行连接,之后再进行连接redis-server服务,之后进行将之前的参数传入到xargs之后,作为del的参数进行执行删除操作。
xargs指令
xargs:是一条Unix和类Unix操作系统的常用命令;它的作用是将参数列表转换成小块分段传递给其他命令,以避免参数列表过长的问题。可单独使用,也可使用管道符、重定位符等与其他命令配合使用。
xargs:一般是和管道一起使用。
- -a file 从文件中读入作为 stdin
- -e flag ,注意有的时候可能会是-E,flag必须是一个以空格分隔的标志,当xargs分析到含有flag这个标志的时候就停止。
- -p 当每次执行一个argument的时候询问一次用户。
- -n num 后面加次数,表示命令在执行的时候一次用的argument的个数,默认是用所有的。
- -t 表示先打印命令,然后再执行。
- -i 或者是-I,这得看linux支持了,将xargs的每项名称,一般是一行一行赋值给 {},可以用 {} 代替。
- -r no-run-if-empty 当xargs的输入为空的时候则停止xargs,不用再去执行了。
- -s num 命令行的最大字符数,指的是 xargs 后面那个命令的最大命令行字符数。
- -L num 从标准输入一次读取 num 行送给 command 命令。
- -l 同 -L。
- -d delim 分隔符,默认的xargs分隔符是回车,argument的分隔符是空格,这里修改的是xargs的分隔符。
- -x exit的意思,主要是配合-s使用。。
- -P 修改最大的进程数,默认是1,为0时候为as many as it can ,这个例子我没有想到,应该平时都用不到的吧。
使用Lua脚本删除百万/千万级的key
如果以上xargs方法删除不了的,或者执行xargs命令报错的。那么可以使用lua脚本,redis有内置的lua解释器。在lua脚本中使用scan扫描key,并依次删除,当删除数量达到1万时,脚本直接返回,完成本次调用,如果删除的key数量大于0,就循环调用脚本进行删除。
Lua脚本是什么?
Lua是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
Lua脚本的指令格式
有兴趣的小伙伴,可以参考: http://redis.cn/commands/eval.html
- script:待执行的脚本文件
- numkeys:key的个数
Lua脚本执行参数
-
[key …]
:对应的key,可以是一个,可以是多个 -
[arg …]
:与key对应的值,可以是一个,可以是多个
Lua获取传参数据
Lua的下表索引是从1开始的,key的获取方式,KEYS[下标索引],如KEYS[1],取第一个值,值的获取,ARGV[1]
Lua脚本的案例(keys)
- 获取传入的需要批量删除的key的前缀
- 记住 lua的下标索引是从1开始 不是0 不是0 不是0
if( key ~= nil) then
--这里通过keys查询出所有符合条件的数据
local dataList = redis.call('keys',KEYS[1])
--判断是否找到数据
if(dataList ~= nil) then
--循环删除
for i=1,#dataList,1 do
redis.call('del',dataList[i])
end
--返回删除的行数
return #dataList
else
return 0
end
else
return 0
end
推荐使用scan获取数据删除,我们知道redis是一个单线程的,当我们库里面存在大量数据的时候,使用keys * 的方式匹配数据的时候,可能需要好几秒才能处理完,那么在这个几秒的时间里是处于线程阻塞的,其他所有的redis操作都是处于等待状态,这样对系统的可用性是有影响的,因此,这里使用scan的方式匹配数据。
scan介绍
SCAN 命令是一个基于游标的迭代器(cursor based iterator): SCAN 命令每次被调用之后, 都会向用户返回一个新的游标, 用户在下次迭代时需要使用这个新游标作为 SCAN 命
令的游标参数, 以此来延续之前的迭代过程。
Lua脚本的案例(scan)
local batchSize = limitSize -- scan一次最多扫描多少个key
if (batchSize > 10000) then -- 一次扫描不能超过1w条
batchSize = 10000
end
local function scan(key)
local cursor = 0
local keynum = 0
repeat
local res = redis.call("scan", cursor, "match", key, 'COUNT', batchSize)
if (res ~= nil and #res >= 0) then
redis.replicate_commands()
cursor = tonumber(res[1])
local ks = res[2]
local size = #ks
for i=1,size,1 do
redis.call("del", tostring(ks[i]))
keynum = keynum + 1
if (keynum >= limitSize) then -- 已经删除了指定数量的key, 返回
return keynum
end
end
end
until (cursor <= 0)
return keynum
end
local total = scan(KEYS[1])
return total
当 SCAN 命令的游标参数被设置为 0 时, 服务器将开始一次新的迭代, 而当服务器向用户返回值为 0 的游标时, 表示迭代已结束。
通俗点理解就是,基于游标的迭代器redis会慢慢一次次的将数据返回回来,从而防止线程阻塞。
此外还有一个小贴士就是可以使用UNLINK删除,区别于del的是这个是异步执行的,这条指令要版本大于4.0.0 小于4.0.0就使用del
Recommend
-
210
设计实战案例!谈谈网易严选企业购的交互设计 我要投稿 推荐:
-
9
边缘计算部署成功的4个因素 责任编辑:cres 作者:Gordon Haff | 2022-09-09 13:56:30 原创文章 企业网D1Net 当云计算技术最初出现时,一种很流行的观点是它将包含所有计算。一种常见的类比是将其比作电网...
-
9
如何正确进行云迁移 责任编辑:cres 作者:Tim Gasper | 2022-09-16 13:15:33 原创文章 企业网D1Net 亚马逊公司在15年前推出了亚马逊网络服务(AWS)平台,在两年之后,该公司在该平台之上构建了100多个...
-
5
本篇文章主要介绍了Redis的执行的慢查询的功能的查询和配置功能,从而可以方便我们在实际工作中,进行分析Redis的性能运行状况以及对应的优化Redis性能的佐证和指标因素。 在我们5.0左右的版本中Redis使用单线程架构和I/O多路复用模型来实现高性能的内存数据...
-
3
声纹识别进入落地阶段技术仍有发展空间 责任编辑:cres 作者:张晟宁 | 2021-01-06 16:34:30 本文摘自:亿欧网 2020年受疫情影响,消费者需求向线上倾斜,智能客服需求量也随之增加。因此,尽管疫情影响下...
-
4
企业外包数据中心的方式和原因 责任编辑:cres 作者:Tim Keary | 2023-04-25 15:09:44 原创文章 企业网D1Net 数据中心是洞察经济发展的基石。为了保持市场竞争力,企业需要能够以经济高效的方式构建大规模...
-
8
将备份数据迁回内部部署环境的最佳实践 责任编辑:cres 作者:Paul Kirvan | 2023-06-07 14:25:00 原创文章 企业网D1Net 一些企业可能会放弃基于云的备份服务,以恢复内部部署的工作流程。有几个因...
-
4
首席技术官的云原生生态系统导航指南 责任编辑:cres 作者:Jess Lulka | 2023-06-19 14:40:29 原创文章 企业网D1Net 虽然容器和云计算技术日益成熟,但企业的首席技术官必须解决许多不同的软件、人员配...
-
5
企业为云迁移做好准备的8种方法 责任编辑:cres 作者:Sandra | 2023-07-04 13:29:49 原创文章 企业网D1Net 企业将业务从内部部署设施迁移到云平台需要大量时间、艰苦的工作和精心规划,以确保做好准备。...
-
6
对设计师而言,“文...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK