广告位联系
返回顶部
分享到

使用Redis缓存时高效的批量删除的几种方案

Redis 来源:互联网 作者:佚名 发布时间:2023-01-27 14:52:22 人浏览
摘要

前因后果 之前我们的服务,在上线的时候发现有一些大Key的使用不是很规范,特别是没有设置过期时间,因此导致redis中内存的数据越来越多,目前Redis节点的内存已经快撑不住了。所

前因后果

之前我们的服务,在上线的时候发现有一些大Key的使用不是很规范,特别是没有设置过期时间,因此导致redis中内存的数据越来越多,目前Redis节点的内存已经快撑不住了。所以根据缓存键的规则去批量删除这些数据,比较常见的就是按前缀去删除。

现在由于不得以为的原因要删除这几百个Key-Value的数据,这个时候我们肯定就要把缓存键全部删除掉。一般情况下在Redis中是可以很容易去实现的。但是如果在不阻塞业务的前提下,并且以高效的方式进行清理内存数据。就需要好好想想办法了。

批量删除redis数据方法

利用的是Linux的xargs命令

我们可以通过redis-cli的模式,进行访问之后登录到了Redis-Server服务,由于是必须要使用Linux的xargs命令,所以必须要连带指令在Linux环境,而不能提前通过redis-cli进行登录到redis-server服务。否则会报错说??xargs??无效。

1

redis-cli -h [ip] -p [port ] -a [password] keys "prefix*" | xargs redis-cli -h 127.0.0.1 -p 6379 -a '123' del

上面的指令主要由三部分连接组成:

  • 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操作系统的常用命令;它的作用是将参数列表转换成小块分段传递给其他命令,以避免参数列表过长的问题。可单独使用,也可使用管道符、重定位符等与其他命令配合使用。

1

xargs [ -p ] [ -t] [ -e[ EOFString ] ] [ -EEOFString ] [ -i[ ReplaceString ] ] [ -IReplaceString ] [ -l [ Number ] ] [ -L Number ] [ -n Number [ -x ] ] [ -s Size ] [ Command [ Argument ... ] ]

命令格式

xargs:一般是和管道一起使用。

1

somecommand |xargs -item command

参数:

  • -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,就循环调用脚本进行删除。

1

Warning: a NUL character occurred in the input. It cannot be passed through in the argument list. Did you mean to use the --null option?

Lua脚本是什么?

Lua是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。

Lua脚本的指令格式

有兴趣的小伙伴,可以参考:? ?http://redis.cn/commands/eval.html??

1

EVAL script numkeys key [key …] arg [arg …]

  • script:待执行的脚本文件
  • numkeys:key的个数

Lua脚本执行参数

  • ??[key …]??:对应的key,可以是一个,可以是多个
  • ??[arg …]??:与key对应的值,可以是一个,可以是多个

Lua获取传参数据

Lua的下表索引是从1开始的,key的获取方式,KEYS[下标索引],如KEYS[1],取第一个值,值的获取,ARGV[1]

示例

1

eval “return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}” 2 key1 key2 first second

Lua脚本的案例(keys)

  • 获取传入的需要批量删除的key的前缀
  • 记住 lua的下标索引是从1开始 不是0 不是0 不是0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

local key = KEYS[1]

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介绍

1

SCAN cursor [MATCH pattern] [COUNT count]

SCAN 命令是一个基于游标的迭代器(cursor based iterator): SCAN 命令每次被调用之后, 都会向用户返回一个新的游标, 用户在下次迭代时需要使用这个新游标作为 SCAN 命
令的游标参数, 以此来延续之前的迭代过程。

Lua脚本的案例(scan)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

local limitSize = tonumber(ARGV[1]) -- 最多删除多少个key

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

1

redis.call("UNLINK",key)


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://blog.51cto.com/alex4dream/6021101
相关文章
  • Redis脑裂导致数据丢失的解决

    Redis脑裂导致数据丢失的解决
    1 案例 主从集群有1个主库、5个从库和3个哨兵实例,突然发现客户端发送的一些数据丢了,直接影响业务层数据可靠性。 最终排查发现是主
  • 使用Redis缓存时高效的批量删除的几种方案
    前因后果 之前我们的服务,在上线的时候发现有一些大Key的使用不是很规范,特别是没有设置过期时间,因此导致redis中内存的数据越来越
  • Redis+Hbase+RocketMQ实际使用问题案例介绍

    Redis+Hbase+RocketMQ实际使用问题案例介绍
    需求 将Hbase数据,解析后推送到RocketMQ。 redis使用list数据类型,存储了需要推送的数据的RowKey及表名。 简单画个流程图就是: 分析及确定方
  • 实现在线 + 离线模式进行迁移Redis数据实战指南

    实现在线 + 离线模式进行迁移Redis数据实战指南
    redis-full-check的使用背景 在经历了之前的文章内容章节内容,已完成Redis迁移后,可能会存在以下问题需要进行数据迁移之后的对比。例如,
  • RedisTemplate访问Redis的更好方法
    开始准备 开始之前我们需要有Redis安装,我们采用本机Docker运行Redis, 主要命令如下 1 2 3 4 docker pull redis docker run --name my_redis -d -p 6379:6379 re
  • redis保存session信息的代码

    redis保存session信息的代码
    1、新建一个maven web 工程名为 session-redis 如下: 目录结构如下: 2、修改配置文件内容 pom.xml 中依赖如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1
  • 用redis setNX命令来加锁的教程

    用redis setNX命令来加锁的教程
    用redis setNX命令来加锁 加锁和释放锁,都需要原子操作,不然在中途中断就会发生异常, 删锁的时候也只能删除自己对应线程的锁。 下面是
  • spring boot集成redis基础入门实例介绍
    redis 支持持久化数据,不仅支持key-value类型的数据,还拥有list,set,zset,hash等数据结构的存储。 可以进行master-slave模式的数据备份 更多
  • redis批量操作pipeline管道操作方法

    redis批量操作pipeline管道操作方法
    redis | pipeline(管道) 背景 Redis是一种基于客户端-服务端模型以及请求/响应的TCP服务。这意味着通常情况下一个请求会遵循以下步骤: 客户
  • springboot整合使用云服务器上的Redis方法

    springboot整合使用云服务器上的Redis方法
    一、前提条件 修改redis.conf配置文件 1、protected-mode yes(默认的) 修改成 protected-mode no,解除保护模式 2、注释掉绑定ip ,绑定ip的话,使得
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计