在redis集群的维护中,我们可能需要批量删除某个固定前缀的key。来降低redis的内存使用空间或者是清理无用的垃圾数据。
在一次维护工作中,我就接收到这样的工作,当时就写了两个脚本来完成的,下面给大家介绍一下。
一、首先是找出指定前缀的key
********操作时候注意脚本中写死的路径,根据你自己的情况调整*******
1、先将指定的key查询出来,每个主节点都查一下,将查询结果保存在指定文件中
a>查询key使用这个脚本:findFixKey.sh
b>进入findFixKey.sh所在目录中去,执行下面这个命令
nohup ./findFixKey.sh "TEAMINFO_2018*" "TEAMINFO_2018" >>findFixKey.log 2>&1 &
说明:
TEAMINFO_2018* 是指查找 以 TEAMINFO_2018 开头的key
TEAMINFO_2018 将查询出来的key保存在以 TEAMINFO_2018 开头的文件中
findFixKey.log 将脚本中echo的输出,以及脚本中命令执行结果的输出,都保存进findFixKey.log日志文件中
c>然后可以滚动查看脚本执行日志
tail -f findFixKey.log
d>生成文件如下
-rw-r----- 1 bigdata bigdata 2632599 Sep 19 11:25 TEAMINFO_2018#10.126.165.202_6379
-rw-r----- 1 bigdata bigdata 2623482 Sep 19 11:25 TEAMINFO_2018#10.126.165.203_6380
-rw-r----- 1 bigdata bigdata 2625382 Sep 19 11:25 TEAMINFO_2018#10.126.165.203_6381
-rw-r----- 1 bigdata bigdata 2632637 Sep 19 11:25 TEAMINFO_2018#10.126.165.203_6383
-rw-r----- 1 bigdata bigdata 2622722 Sep 19 11:25 TEAMINFO_2018#10.126.165.204_6379
-rw-r----- 1 bigdata bigdata 2611320 Sep 19 11:25 TEAMINFO_2018#10.126.165.204_6380
-rw-r----- 1 bigdata bigdata 2620669 Sep 19 11:25 TEAMINFO_2018#10.126.165.205_6381
-rw-r----- 1 bigdata bigdata 2630738 Sep 19 11:25 TEAMINFO_2018#10.126.165.206_6382
-rw-r----- 1 bigdata bigdata 2613829 Sep 19 11:25 TEAMINFO_2018#10.126.165.206_6383
脚本findFixKey.sh,内容如下:
#!/bin/bash
##随便登录集群中的一个节点,然后识别出所有的主节点
my_array=`/usr/local/bin/redis-cli -c -h 10.126.165.202 -p 6379 cluster nodes |grep master |awk '{print $2}'`
echo "master node is as follows:"
echo "$my_array"
echo "-------------------------------------"
##计数使用
num=1
##循环每个主节点, 找出指定的key
for a in $my_array
do
echo "第$num个master node: $a"
##将 10.126.165.202:6379 拆成 10.126.165.202 与 6379
OLD_IFS="$IFS"
IFS=":"
arr=($a)
IFS="$OLD_IFS"
##echo "${arr[0]}=${arr[1]}"
##$1 传递key名称的模糊查询 $2 传递文件名称,可以用key做文件名称的前缀
/usr/local/bin/redis-cli -c -h "${arr[0]}" -p ${arr[1]} KEYS "$1" >>/home/bigdata/$2#${arr[0]}_${arr[1]}
num=$((num+1))
done
二、删除已经找出的key
1、文件找出来之后,我们就循环处理,挨个读取文件中的行数据(key)进行删除
a>删除使用这个脚本文件:forFileDelKey.sh
b>进入forFileDelKey.sh所在目录中去,执行下面这个命令
nohup ./forFileDelKey.sh "TEAMINFO_2018*" >>forFileDelKey.log 2>&1 &
说明:
TEAMINFO_2018* 是查找key那步操作生成文件名称的开头部分
forFileDelKey.log 将脚本中echo的输出,以及脚本中命令执行结果的输出,都保存进forFileDelKey.log 日志文件中
c>然后可以滚动查看脚本执行日志
tail -f forFileDelKey.log
脚本forFileDelKey.sh,内容如下:
#!/bin/bash
##根据传递的模糊文件名查找匹配的所有文件
my_array=(`ls $1`)
echo "-----${my_array[@]}"
count="${#my_array[*]}"
if [ $count -gt 0 ];then
for a in ${my_array[@]}
do
TODAY=`date "+%Y-%m-%d %H:%M:%S"`
echo "----------------------------------$TODAY-------------------------------start"
echo "The filename is: $a"
#TEAMINFO_2018#10.126.165.202_6379
#截取文件名中的 ip 和 端口,以达到key在哪个主节点中就进入哪个主节点中删除
ipV=`echo $a |awk -F "#" '{print $NF}'|awk -F "_" '{print $1}'`
portV=`echo $a |awk -F "#" '{print $NF}'|awk -F "_" '{print $2}'`
##计数使用
num=1
while read line
do
echo "---文件$a---的第$num个key:$line"
if [ $line ];then
echo "第$num行key为:$line"
/usr/local/bin/redis-cli -c -h $ipV -p $portV del "$line" ##删除命令
else
echo "第$num行为空"
fi
num=$((num+1))
done < $a
echo "----------------------------------$TODAY-------------------------------end"
done
else
echo "没有以$1开头的文件,请核实..."
fi