菜鸟笔记
提升您的技术认知

redis集群批量删除模糊key shell脚本

1. 命令删除:

1. 1批量删除Key

Redis 中有删除单个 Key 的指令 DEL,但好像没有批量删除 Key 的指令,不过我们可以借助 Linux 的 xargs 指令来完成这个动作

redis-cli keys "*" | xargs redis-cli del

//如果redis-cli没有设置成系统变量,需要指定redis-cli的完整路径
//如:/opt/redis/redis-cli keys "*" | xargs /opt/redis/redis-cli del

1.2 模糊删除:

./redis-cli keys "*lz*"|xargs ./redis-cli del

1.3 需要密码

如果要指定 Redis 数据库访问密码,使用下面的命令

redis-cli -a password keys "*" | xargs redis-cli -a password del

1.4 指定数据库

如果要访问 Redis 中特定的数据库,使用下面的命令
//下面的命令指定数据序号为0,即默认数据库

redis-cli -n 0 keys "*" | xargs redis-cli -n 0 del

1.5 删除所有Key

删除所有Key,可以使用Redis的flushdb和flushall命令
//删除当前数据库中的所有Key
flushdb
//删除所有数据库中的key
flushall
注:keys 指令可以进行模糊匹配,但如果 Key 含空格,就匹配不到了,暂时还没发现好的解决办法。

 

2. shell 脚本删除

2.1. 方法1:

网上查的资料

redis_list=("redis-cluster:16301" "redis-cluster:16302" "redis-cluster:16303")
password='password'
redis_comm=/home/woapp/middleware/redis-cluster/redis-3.2.1/src/redis-cli
read -p "请输入要删除的key格式:" searchkey
read -p "是否显示查询的所有key(Y/N): " searchFlag

if [ $searchFlag = "Y" ] || [ $searchFlag = "y" ]; then
    for info in ${redis_list[@]}
    do
        echo "开始查询:$info"
        ip=`echo $info | cut -d : -f 1`
        port=`echo $info | cut -d : -f 2`
        $redis_comm -c -h $ip -p $port -a $password  keys $searchkey
    done
fi

read -p "确定删除(Y/N):" runCommand
if [ $runCommand = "Y" ] || [ $runCommand = "y" ]; then
    for info in ${redis_list[@]}
    do
        echo "开始执行:$info"
        ip=`echo $info | cut -d : -f 1`
        port=`echo $info | cut -d : -f 2`
     $redis_comm -c -h $ip -p $port -a $password  keys $searchkey | xargs -i ./redis-cli -h $ip -p $port -a $password  del {}
    done
    echo "完成"
fi

缺点:集群节点写入了shell,改起来麻烦

 

2.2 方法2:

1、说明

redis cluster集群上有时候会需要删除多个key,就必须需要登录到每个节点上,而且有可能这个key不在这个节点,删除起来就比较麻烦,测试的时候极不方便。于是就自己动手写了一个支持模糊删除key的脚本,分享给大家。

2、新建del_redis.sh,内容如下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

#!/bin/bash

 

# 配置redis-cli地址

redis_cmd=redis-cli

# 配置reids集群IP地址

host=192.168.1.2

# 配置reids集群节点端口

ports=(6380 6381 6382 6383 6384 6385)

# 配置reids密码

password="test"

 

for port in ${ports[@]}

do

    $redis_cmd -c -h $host -p $port -a $password 2>/dev/null keys $1 | xargs -i $redis_cmd -h $host -p $port -a $password 2>/dev/null del {}

done;

echo "success"

ps:参数说明

1

2

3

4

5

6

-c # 启动集群模式进入redis集群服务

-h # redis主机地址

-p # redis节点的端口

-a # redis的密码

2>/dev/null # 过滤使用密码连接redis时报的警告:Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.

xargs -i # -i 选项告诉 xargs 可以使用{}代替传递过来的参数

3、执行脚本

1

sh del_redis.sh test:*

这样就删除了所有以test开头的key了

2.3 方法3:

      有很多场景,我们都需要删除redis中某些具有相似特征的key,即使是线上环境也是。如果key数量很小容易处理,如果这些key很 多很多,必须通过scan命令循环扫描一一删除,如果直接执行keys命令会堵死redis服务。下面这个脚本就是通过循环扫码key再删除,直至结束。

redis-del-keys.sh

#!/bin/bash
##redis主机IP
host=$1
##redis端口
port=$2
##key模式
pattern=$3
##游标
cursor=0
##退出信号
signal=0

##循环获取key并删除
while [ $signal -ne 1 ]
    do
        echo "cursor:${cursor}"
        sleep 2
        ##将redis scan得到的结果赋值到变量
        re=$(redis-cli -h $host -p $p -c  scan $cursor count 1000 match $pattern)
        ##以换行作为分隔符
        IFS=$'\n' 
        #echo $re
        echo 'arr=>'
        ##转成数组
        arr=($re)
        ##打印数组长度
        echo 'len:'${#arr[@]}
        ##第一个元素是游标值
        cursor=${arr[0]}
        ##游标为0表示没有key了
        if [ $cursor -eq 0 ];then
            signal=1
        fi
        ##循环数组
    for key in ${arr[@]}
        do
            echo $key
            if [ $key != $cursor ];then
                echo "key:"$key
                ##删除key
                redis-cli -h $host -p $port -c del $key >/dev/null  2>&1
            fi
    done
done
echo 'done'

使用方式:

./redis-del-keys.sh localhost 6379 user:*

表示删除本机6379端口的redis中user:开头的所以key。

 

2.4 方法4:

明确知道master的ip和端口

#!/bin/bash
redis_comm=/home/zhongcy/redis/bin/redis-cli
redis_ser01=10.106.157.104
redis_ser02=10.105.179.236
redis_ser03=10.105.179.236

$redis_comm -c -h $redis_ser01 -p 9001 keys "$1" | xargs -i $redis_comm -c -h $redis_ser01 -p 9001 del {}
$redis_comm -c -h $redis_ser02 -p 9001 keys "$1" | xargs -i $redis_comm -c -h $redis_ser02 -p 9001 del {}
$redis_comm -c -h $redis_ser03 -p 9002 keys "$1" | xargs -i $redis_comm -c -h $redis_ser03 -p 9002 del {}

 

3 我的优化版本

#!/bin/bash
redis_comm=/home/zhongcy/redis/bin/redis-cli

#从当前节点查询集群信息, 查询所有master节点 生成数组
redis_list=$($redis_comm -p 9001 cluster nodes | grep master |  awk '{print $2}' |  awk -F['@'] '{print $1}')

#用临时文件也行 
#$redis_comm -p 9001 cluster nodes | grep master |  awk '{print $2}' |  awk -F['@'] '{print $1}' > tmp
#i=0
#while read line
#do
#    redis_list[i]=$line
#    i=$(($i+1))
#done < ./tmp


read -p "请输入要删除的key格式: " searchkey
read -p "是否显示查询的所有key(Y/N): " searchFlag

if [ $searchFlag = "Y" ] || [ $searchFlag = "y" ]; then
    for info in ${redis_list[@]}
    do
        echo "开始查询: $info"
        ip=`echo $info | cut -d : -f 1`
        port=`echo $info | cut -d : -f 2`
        $redis_comm -c -h $ip -p $port keys "$searchkey"
    done
fi

read -p "确定删除(Y/N): " runCommand
if [ $runCommand = "Y" ] || [ $runCommand = "y" ]; then
    for info in ${redis_list[@]}
    do
        echo "开始执行: $info"
        ip=`echo $info | cut -d : -f 1`
        port=`echo $info | cut -d : -f 2`
        $redis_comm -c -h $ip -p $port keys "$searchkey" | xargs -i $redis_comm -h $ip -p $port del {}
    done
    echo "完成"
fi

后面有时间可以优化用scan命令循环扫描。