当前位置:首页 > 问答 > 正文

用Redis怎么远程一次删好多数据,感觉挺实用的办法分享下

先找到要删哪些,然后再删。

Redis本身没有直接提供一个叫“按模式删除一批key”的单一命令(除了非常有限的 DEL key1 key2 key3...,但一次能跟的key数量有限制,而且你得先知道key的名字),我们的操作一般都是分两步走:扫描(SCAN)删除(DEL)

在服务器上用redis-cli的--scan选项(最推荐、最常用)

这是最经典、也是官方推荐的方法,你不需要写脚本,直接一行命令搞定,前提是你能登录到Redis服务器,或者能从你的电脑远程连接到Redis服务器。

命令长这样:

redis-cli -h your_redis_host -p your_redis_port -a your_password --scan --pattern "your_pattern*" | xargs redis-cli -h your_redis_host -p your_redis_port -a your_password DEL

别怕,我们把它拆开看:

  1. redis-cli -h ... -p ... -a ...:这是连接Redis的必要信息,-h 是主机IP(远程就是远程服务器IP,本地就是127.0.0.1),-p 是端口(默认6379),-a 是密码(如果没密码可以去掉这部分)。注意: 在真实环境中,把密码写在命令行可能不安全,容易泄露,更安全的方式是使用 --askpass 选项让CLI提示你输入,或者把密码写在配置文件中。
  2. *`--scan --pattern "your_pattern"**:这是关键。--scan告诉CLI使用扫描模式,避免使用会阻塞服务的KEYS命令。--pattern后面跟的就是你要匹配的模式,你的所有用户session的key都叫session:12345,那么模式就可以写成"session:",星号` 是通配符,代表任意字符。
  3. :这是一个管道符,意思是把前面命令的输出,作为输入传给后面的命令。
  4. xargs:这个命令的作用是,把前面传过来的一长串key的名字(每行一个),转换成后面 redis-cli DEL 命令的参数,比如前面扫描出 key1key2key3,经过 xargs 处理,就变成了执行 DEL key1 key2 key3
  5. 最后一部分 redis-cli ... DEL:这就是最终执行删除动作的命令了。

举个例子: 假设你的Redis在 168.1.100 上,端口 6379,密码是 mypassword,你想删除所有以 cache:product: 开头的key。

你的命令就是:

redis-cli -h 192.168.1.100 -p 6379 -a mypassword --scan --pattern "cache:product:*" | xargs redis-cli -h 192.168.1.100 -p 6379 -a mypassword DEL

执行这行命令,它会先扫描出所有匹配的key,然后一个个(或者一批批)地删除掉,这个方法效率很高,而且因为用了 SCAN,不会对服务器性能造成太大影响。

小提示: 如果你的key名称里有空格或者特殊字符,上面的命令可能会出问题,更健壮的写法是给 xargs 加个 -0 选项,同时前面的扫描命令用 --print0(用空字符分隔key),但大多数情况下用不着。

写一个简单的脚本(更灵活)

你可能想在删除前做点别的事情,比如先确认一下key的值,或者记录一下日志,这时候,写个小脚本就更灵活了,这里用Python举例,因为Redis的Python库(redis-py)非常常用。

import redis
# 连接到远程Redis
r = redis.Redis(host='your_redis_host', port=your_redis_port, password='your_password', decode_responses=True)
# 定义一个模式
pattern = "your_pattern*"
# 用于计数的变量
count = 0
# 使用scan_iter,它是一个迭代器,分批获取key,不会阻塞服务
for key in r.scan_iter(match=pattern, count=100): # count是每次扫描的数量,可调整
    # 在真正删除前,你可以在这里做任何操作,比如打印一下
    # print(f"Deleting key: {key}")
    # 执行删除
    r.delete(key)
    count += 1
print(f"All done! Deleted {count} keys.")

这个脚本的好处是:

  • 可控性强: 你可以在循环里加 try...except 来捕获异常,避免一个key删除失败导致整个脚本中断。
  • 可扩展: 可以轻松加入日志功能,把删除的key记录到文件里,方便后续排查。
  • 可预处理: 比如你先 r.get(key) 看一下值,再决定删不删。

运行这个脚本,你只需要在本地电脑上安装好Python和redis库(pip install redis),然后修改连接信息和模式,直接 python script.py 运行就行了。

使用Lua脚本(高级玩法,保证原子性)

这个方法稍微进阶一点,Redis支持Lua脚本,脚本里的操作是原子性的,也就是说在执行脚本的过程中,不会夹杂其他客户端的命令。

你可以把一个“扫描并删除”的逻辑写进Lua脚本,然后用 EVAL 命令执行,但这里有个小坑,Redis的Lua脚本里不支持 SCAN 命令!所以通常的写法是,把匹配模式作为参数传进去,然后用 redis.call(‘KEYS’, ARGV[1]) 获取所有key,再循环删除。

示例:

redis-cli -h your_redis_host -a your_password --eval clear_keys.lua , "your_pattern*"

clear_keys.lua 文件的内容是:

local keys = redis.call('KEYS', ARGV[1])
for i=1, #keys do
    redis.call('DEL', keys[i])
end
return #keys

请特别小心这个方法! 因为Lua脚本里用了 KEYS 命令,KEYS 命令在生产环境是不推荐使用的,当你的Redis中key的数量非常巨大时,KEYS 命令会一次性遍历所有key,导致Redis服务阻塞一段时间,在这期间无法响应其他任何请求,可能会引起服务雪崩。

除非你非常确定你要操作的key的数量很少,或者是在业务低峰期操作,并且能接受短暂的服务不可用,否则不建议使用Lua脚本+KEYS的方式,方法一和方法二使用的 SCAN 是更安全的选择。

总结与重要提醒

  1. 首选方法一: 对于绝大多数远程批量删除的场景,直接在命令行使用 redis-cli --scan | xargs del 是最简单、高效且安全的选择。
  2. 备份!备份!备份! 在执行任何批量删除操作前,如果数据重要,请务必先对Redis数据进行备份(例如使用 BGSAVE 命令生成RDB快照),删错了可就追悔莫及了。
  3. 先预览再动手: 在执行删除命令前,可以先把删除命令换成只是打印,看看是不是你想要的key,比如方法一的命令,你可以先只运行 --scan 部分:
    redis-cli -h your_host -a your_pass --scan --pattern "your_pattern*"

    确认输出的key列表无误后,再接上 | xargs ... DEL 执行删除。

  4. 避开业务高峰: 批量删除操作虽然用了非阻塞的SCAN,但DEL操作本身还是会消耗CPU和网络资源,尽量选择在夜深人静、用户量少的时候进行。
  5. 注意通配符: 模式里的通配符要写对, 代表任意数量任意字符, 代表一个任意字符。user:* 会匹配 user:1001user:profile:1001,而 user:? 只会匹配像 user:A 这种后面只有一个字符的key。

希望这些实实在在的方法能帮到你,操作数据无小事,谨慎总是没错的。

用Redis怎么远程一次删好多数据,感觉挺实用的办法分享下