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

用Redis怎么快速搞定远程批量删数据这事儿分享下

行,这事儿我直接给你唠明白,用Redis搞远程批量删数据,说白了就是“让你不用一台服务器一台服务器登录上去手动删,而是写个招儿,一下子清理掉一堆符合条件的数据”,听着挺唬人,其实核心就几步,咱别整那些高大上的术语,就用人话讲怎么弄。

核心思想:别用keys命令,用scan命令

最重要的一点,你要是听说过或者想过用 keys *某个模式* 这个命令来查数据然后删,赶紧打住!这个命令在生产环境(就是正式跑业务的服务器)上绝对是禁忌,因为它会一次性遍历整个数据库的所有键(key),如果你这Redis里存了几百万、几千万个键,这命令一执行,Redis就直接卡死了,短时间内没法响应其他操作,跟宕机了一样,咱们得用更文明、更温柔的方式:SCAN 命令。

SCAN 命令的好处是,它像扫描仪一样,一次只扫一小部分数据给你,然后给你个“游标”(你可以理解成个记号),你拿着这个记号再去扫下一部分,这样就把一个大任务拆成了很多个小任务,中间Redis还能喘口气去处理别的请求,不会卡住。

实操步骤:分情况讨论

用Redis怎么快速搞定远程批量删数据这事儿分享下

批量删数据,一般就两种情况:要么是key的名字有某种规律(比如都以"cacheuser"开头),要么是这些key虽然没规律,但已经过期了(TTL变成-1了)。

按key的规律删(比如删掉所有以"temp:session:"开头的key)

这是最常见的情况,咱们的目标是:找到所有符合这个模式的key,然后一个一个删掉,因为不能用keys,所以用SCAN来找。

  1. 找个地方写脚本:你肯定不能直接在Redis的命令行里手动一遍遍执行SCAN,那得累死,通常是用个脚本,比如用Python、Shell脚本、或者Node.js都行,这里我用Python给你举个例子,因为它读起来像伪代码,好理解。

    用Redis怎么快速搞定远程批量删数据这事儿分享下

  2. 连接Redis:脚本的第一件事就是连上你那个远程的Redis服务器,你需要知道它的IP地址(比如168.1.100)、端口(通常是6379),如果有密码,还得知道密码。

  3. 用SCAN迭代:在Python里,有个叫redis的库(用之前需要安装:pip install redis),这个库很智能,它提供了一个叫scan_iter的方法,帮你自动处理游标,你只需要告诉它你要找的key的模式(比如temp:session:*)。

  4. 逐个删除scan_iter会返回一个迭代器,每次吐出一个匹配的key,你拿到一个key,就立刻用delete命令删一个。

下面是个简单的Python脚本示例:

用Redis怎么快速搞定远程批量删数据这事儿分享下

(来源:基于Redis官方Python客户端库常见用法)

import redis
# 1. 连接到远程Redis
# 替换成你的实际地址、端口和密码
r = redis.Redis(host='192.168.1.100', port=6379, password='你的密码', decode_responses=True)
# 2. 定义你要删的key的模式
pattern = "temp:session:*"
# 3. 用一个变量来计数,看删了多少个
count = 0
# 4. 使用scan_iter安全地遍历所有匹配的key
for key in r.scan_iter(match=pattern):
    # 打印一下正在删的key,方便看进度(如果数据太多,可能刷屏,可以注释掉)
    print(f"正在删除键: {key}")
    # 执行删除
    r.delete(key)
    count += 1
print(f"批量删除完成!共删除 {count} 个键。")

清理已经过期的key

你可能想清理那些本该过期但因为Redis的过期删除策略(惰性删除+定期删除)而暂时还残留在内存里的key,注意,Redis本身最终是会删掉这些过期key的,但如果你等不及想立刻释放内存,可以主动扫描。

这个方法要格外小心,因为SCAN命令默认会扫出所有的key,包括没过期的,所以思路是:扫出key,然后检查每个key的剩余存活时间(TTL),如果TTL是-1(表示永不过期)或者正数(表示还没到期),我们就跳过;如果TTL是-2(表示已经过期了,但还没被Redis内部机制清理),我们就删掉它。

(来源:基于Redis TTL命令的含义和常见运维技巧)

import redis
r = redis.Redis(host='192.168.1.100', port=6379, password='你的密码', decode_responses=True)
# 这次不需要match模式了,我们扫描所有key
count_expired = 0
for key in r.scan_iter():
    ttl = r.ttl(key)  # 获取这个key的剩余生存时间
    # 如果ttl == -2, 说明这个key已经过期了
    if ttl == -2:
        print(f"发现过期键并删除: {key}")
        r.delete(key)
        count_expired += 1
print(f"过期键清理完成!共清理 {count_expired} 个键。")

重要提醒和注意事项

  • 备份!备份!备份!:在执行任何批量删除操作之前,强烈建议你对Redis数据库做个备份(用BGSAVE命令生成RDB文件),万一你脚本里的匹配模式写错了,把不该删的删了,还有后悔药吃。
  • 先在测试环境试:别直接上生产环境操作,找个测试的Redis,灌点类似的数据,确保你的脚本按你想象的方式运行。
  • 控制速度(可选):如果你要删的数据量特别特别巨大,上亿级别,为了避免对网络和Redis造成太大压力,可以在删除循环里加个小小的延时,比如time.sleep(0.001),让删除操作慢一点点。
  • 考虑用Lua脚本(进阶):如果你追求极致的速度,并且删除逻辑不复杂,可以把SCAN和DEL的命令写成一个Lua脚本,让它在服务器端执行,减少网络往返时间,但这个对新手有点复杂,上面给的脚本方法已经能解决90%的问题了。
  • 云服务商可能有好用的工具:如果你用的是阿里云、腾讯云这些云服务商的Redis,他们自己的控制台里可能提供了可视化的“批量删除”或“按前缀删除”工具,可能比自己写脚本更方便,可以看看。

远程批量删数据的核心就是 “SCAN迭代 + 逐个DEL” ,避开KEYS命令这个坑,方法不复杂,关键是细心,做好安全措施,希望这个分享能帮你快速搞定这事儿。