redis如何优雅删除大量的key?

当我们需要批量删除redis的key时,很多时候都是依赖redis的client加上linux的xargs来做。
比较常见的像是,通过keys匹配数据,然后进行del。
相应的删除语句就是:
redis-cli -h 地址 -p 6379 -a 密码 keys "匹配内容" | xargs ./redis-cli -h 地址 -p 6379 -a 密码 del
但是如果是在线上服务器里,假设是百万、千万个key里面去进行keys匹配,很明显会引起阻塞可能CPU使用率就会上升很快。
如何在不影响线上环境使用的前提下进行操作,很自然的想到的就是通过使用scan来提到keys的匹配扫描。
redis-cli -h 地址 -a 密码 -n 操作DB scan 0 match "匹配内容" count 扫描数量 | xargs -t  redis-cli -h 地址 -a 密码 -n 操作DB del
但是scan命令的这个游标,只靠这行脚本可能就扫不完全整个库了。
看到有些文章是通过如下形式进行操作:
redis-cli --scan --pattern “testkey-*” | xargs -L 1000 redis-cli del
但是xargs -L 1000似乎并不能很好的使用scan。所扫描的结果也不能发挥scan的作用。
我们知道scan命令会返回2个值。第一个为游标移动后的新位置,第二个是匹配到的key值。
第一个值为0时说明扫描完成了一遍。
经过尝试,最后选择用shell来处理。具体代码参考如下:
第一个返回值存入游标变量作为下一次的扫描入参。
第二个返回值是需要删除的key值,用数组保存。
#!/bin/bash
#定义变量《根据个人需要填写》
redis_url=地址
redis_pass=密码
redis_db=操作DB
scan_patten=匹配字符串
scan_count=扫描数量

yb=0
#0:循环获取游标进行遍历
while 1>0
do

count=0
declare -a array

#1:扫描获取结果
declare -a result
for i in `redis-cli -h $redis_url -a $redis_pass -n $redis_db scan $yb match $scan_patten count $scan_count`;do
		result[${count}]=${i}
    count=$(expr ${count} + 1)
done

#2:设置游标值
yb=${result[0]}

#3:赋值array,打印寻找到的key值
for j in ${!result[@]}
do		
		if [ $j -gt 0 ]
    then echo ${result[$j]}
    array[${count}]=${result[$j]}
    fi
done    

#4:批量删除key值
		if [ ${#array[@]} -gt 0 ]
    then 
    #${result[$j]}
    echo ${array[@]} | xargs -t redis-cli -h $redis_url -a $redis_pass -n $redis_db del 
    fi

#5:判断条件结束循环
if [ $yb -eq 0 ]
then break
fi

unset result
unset array    
    
done
测试有效,以下是返回结果:

redis如何优雅删除大量的key?_第1张图片

Warning: Using a password with ‘-a’ or ‘-u’ option on the command line interface may not be safe.
这行命令是redis-cli时提示不要在控制台使用-u -a 不安全,防范密码泄漏的风险。

你可能感兴趣的:(redis,redis,运维)