由于早期使用redis时,没有指定key过期时间,导致大量内存浪费,需要修改合理指定过期时间,并对历史数据进行清理
方案1:使用Linux的xargs命令以及keys+del批量删除 Redis 中有删除单个 Key 的指令 DEL,但好像没有批量删除 Key 的指令,不过我们可以借助 Linux 的 xargs 指令来完成这个动作
1 2 3 redis-cli keys "base*" | xargs redis-cli del // 如果redis-cli没有设置成系统变量,需要指定redis-cli的完整路径 // 如:/opt/ redis/redis-cli keys "base*" | xargs / opt/redis/ redis-cli del
如果要指定 Redis 数据库访问密码,使用下面的命令
1 redis-cli -a password keys "base*" | xargs redis-cli -a password del
如果要访问 Redis 中特定的数据库,使用下面的命令
1 2 redis-cli -n 0 keys "base*" | xargs redis-cli -n 0 del
删除所有Key,可以使用Redis的flushdb和flushall命令
1 2 3 4 // 删除当前数据库中的所有Key flushdb // 删除所有数据库中的key flushall
此方案有两个问题:
方案2:使用Linux的xargs命令以及scan+del批量删除 参考redis官方手册,使用scan命令查找key不会阻塞
1 2 3 4 5 begin redis -cli -h localhost -p 6379 -a password scan 0 match "base*" count 1000 | xargs redis-cli -h localhost -p 6379 -a password delend
此方案的问题:
count小的话要执行次数太多,需要脚本化循环处理才有可能实施
count大的话xargs拼接del命令的时候也会超出参数的长度限制
方案3:使用shell脚本及scan+del批量删除 参考网友现成的方案,考虑key多执行时间长以及日志较多,不挂起执行脚本实现批量删除,并删除不挂起执行日志文件防止日志文件过大
参数1:需要删除key的匹配字符串
参数2:redis的host
参数3:redis的端口
参数4:redis的db
参数5:每次删除的个数
参数6:每次批量删除的间隔秒数,支持小数
脚本执行的linux必须安装有redis客户端
脚本内容:
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 29 30 31 32 33 34 35 36 37 38 39 40 41 #!/bin/bash if [ "$# " -lt 3 ]then echo "Scan keys in Redis matching a pattern using SCAN (safe version of KEYS)" echo "Usage: $0 [pattern] <host> [port] [database] [count] [second]" exit 1fi pattern=${1:-} host=${2:-} port=${3:-6379} database=${4:-0} count=${5:-5000} second=${6:-1} if [ ! -n "$pattern " ] ;then echo "pattern shoud not be empty!" fi cursor=-1 keys='' while [ $cursor -ne 0 ]; do if [ $cursor -eq -1 ] then cursor=0 fi reply=`redis-cli -h "$host " -p "$port " -n "$database " SCAN $cursor MATCH $pattern COUNT $count ` cursor=`expr "$reply " : '\([0-9]*[0-9]\)' ` keys=${reply#[0-9]*[[:space:]]} redis-cli -h "$host " -p "$port " -n "$database " DEL $keys sleep $second done
执行脚本:
1 2 3 4 5 6 7 begin sudo nohup sh scantodel.sh *pattern* 127.0.0.1 6379 0 5000 1 rm -f nohup.out end
方案4:使用shell脚本及scan+del批量删除-方案3脚本优化
相当于是对方案3脚本的另一种实现方式,也算是对方案3中脚本的优化
当count比较大,这两个计算时可能出现错误:
cursor=expr "$reply" : '\([0-9]*[0-9]\)'
keys=${reply#[0-9]*[[:space:]]}
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #!/bin/bash redis_url=${1:-} redis_port=${2:-6379} redis_db=${3:-0} scan_patten=${4:-} scan_count=${5:-1000} redis_pass=${6:-} if [ "X${redis_pass} " == "X" ];then redis_info="redis-cli -h $redis_url -p $redis_port -n $redis_db " else redis_info="redis-cli -h $redis_url -p $redis_port -a $redis_pass -n $redis_db " fi yb=0 counter=0while 1>0do counter=$((counter+1 )) array=(`$redis_info scan $yb match $scan_patten count $scan_count `) yb=${array[0]} arrLen=${#array[@]} keysNum=`expr $arrLen - 1` if [ $keysNum -gt 0 ]; then start=`date +"%Y%m%d %H:%M:%S" ` $redis_info del ${array[@]:1:$keysNum} end=`date +"%Y%m%d %H:%M:%S" ` echo "counter: [$counter ] yb: [$yb ] keysNum: [$keysNum ]" echo "del time: [$start ] - [$end ]" else echo "counter: [$counter ] yb: [$yb ] keysNum: [$keysNum ]" echo "no keys to del" fi if [ $yb -eq 0 ]; then break fi unset arraydone
蚂蚁🐜再小也是肉🥩!