由于应用 bug 造成某些特定前缀的缓存出错,需要批量清理。
Redis 日常运维脚本 中的 redis-tools.sh
仅支持删除单个 key 和 全部清理,并未实现匹配特定前缀批量删除的功能。
1$ redis-cli --scan --pattern "party*" | xargs -L 1 redis-cli del
* Version 0.0.2 2020/05/16 * 修正 inputYN 多次回车,导致参数丢失问题 * 修正 部分描述信息,调整格式等 * 增加 “批量删除 key,支持正则表达式” 方法
* Version 0.0.1 2020/04/26 * 创建 Redis 集群情况查询、key 查询、key 删除等功能脚本
1sh ${SCRIPT_NAME} [options] <value> ...
2
3 -h<value>, --host=<value> Redis IP,可设置默认值参数:HOST
4 -p<value>, --port=<value> Redis 端口,可设置默认值参数:PORT
5 -a<value>, --password=<value> Redis 密码,可设置默认值参数:PASSWORD
6 -c<value>, --cluster=<value> 集群相关命令,如:nodes, info
7 -k<pattern>, --keys=<pattern> 查询 key,支持正则表达式
8 -g<value>, --get=<value> 获取指定 key 的值
9 -d<value>, --del=<value> 删除指定 key,不支持正则表达式,原因:redis 的 del 命令不支持正则表达式
10 -b<pattern>, --bdel=<pattern> 批量删除 key,支持正则表达式
11 -f, --flushall 删除所有 key
12 --help 帮助信息
13 -v, --version 版本信息
1redis key示例数据格式:
2 "party::123"
3 "party::456"
4
51. 查询集群信息,使用默认参数
6sh redis-tools.sh -c info
7
82. 查询集群节点
9sh redis-tools.sh -h 127.0.0.1 -p 8001 -a password -c nodes
10
113. 查询 key,支持正则表达式
12sh redis-tools.sh -k "party::123"
13sh redis-tools.sh -k "party*"
14
154. 获取指定 key 值
16sh redis-tools.sh -g "party::123"
17
185. 删除指定 key,不支持正则表达式,原因:redis 的 del 命令不支持正则表达式
19sh redis-tools.sh -d "party::123"
20
216. 批量删除 key,支持正则表达式
22sh redis-tools.sh -b "party::123"
23sh redis-tools.sh -b "party*"
24
257. 删除所有 key
26sh redis-tools.sh -f
1$ cat redis-tools.sh
2#!/bin/bash
3#================================================================
4# HEADER
5#================================================================
6# Filename redis-tools.sh
7# Revision 0.0.2
8# Date 2020/04/26
9# Author jiangliheng
10# Email jiang_liheng@163.com
11# Website https://jiangliheng.github.io/
12# Description Redis 日常运维脚本
13# Copyright Copyright (c) jiangliheng
14# License GNU General Public License
15#
16#================================================================
17# Version 0.0.2 2020/05/16
18# 修正 inputYN 多次回车,导致参数丢失问题
19# 修正 部分描述信息,调整格式等
20# 增加 “批量删除 key,支持正则表达式” 方法
21#
22# Version 0.0.1 2020/04/26
23# 创建 Redis 集群情况查询、key 查询、key 删除等功能脚本
24#
25#================================================================
26#%名称(NAME)
27#% ${SCRIPT_NAME} - Redis 日常运维脚本
28#%
29#%概要(SYNOPSIS)
30#% sh ${SCRIPT_NAME} [options] <value> ...
31#%
32#%描述(DESCRIPTION)
33#% Redis 日常运维脚本
34#%
35#%选项(OPTIONS)
36#% -h<value>, --host=<value> Redis IP,可设置默认值参数:HOST
37#% -p<value>, --port=<value> Redis 端口,可设置默认值参数:PORT
38#% -a<value>, --password=<value> Redis 密码,可设置默认值参数:PASSWORD
39#% -c<value>, --cluster=<value> 集群相关命令,如:nodes, info
40#% -k<pattern>, --keys=<pattern> 查询 key,支持正则表达式
41#% -g<value>, --get=<value> 获取指定 key 的值
42#% -d<value>, --del=<value> 删除指定 key,不支持正则表达式,原因:redis 的 del 命令不支持正则表达式
43#% -b<pattern>, --bdel=<pattern> 批量删除 key,支持正则表达式
44#% -f, --flushall 删除所有 key
45#% --help 帮助信息
46#% -v, --version 版本信息
47#%
48#%示例(EXAMPLES)
49#% redis key示例数据格式:
50#% "party::123"
51#% "party::456"
52#%
53#% 1. 查询集群信息,使用默认参数
54#% sh ${SCRIPT_NAME} -c info
55#%
56#% 2. 查询集群节点
57#% sh ${SCRIPT_NAME} -h 127.0.0.1 -p 8001 -a password -c nodes
58#%
59#% 3. 查询 key,支持正则表达式
60#% sh ${SCRIPT_NAME} -k "party::123"
61#% sh ${SCRIPT_NAME} -k "party*"
62#%
63#% 4. 获取指定 key 值
64#% sh ${SCRIPT_NAME} -g "party::123"
65#%
66#% 5. 删除指定 key,不支持正则表达式,原因:redis 的 del 命令不支持正则表达式
67#% sh ${SCRIPT_NAME} -d "party::123"
68#%
69#% 6. 批量删除 key,支持正则表达式
70#% sh ${SCRIPT_NAME} -b "party::123"
71#% sh ${SCRIPT_NAME} -b "party*"
72#%
73#% 7. 删除所有 key
74#% sh ${SCRIPT_NAME} -f
75#%
76#================================================================
77# END_OF_HEADER
78#================================================================
79
80# header 总行数
81SCRIPT_HEADSIZE=$(head -200 "${0}" |grep -n "^# END_OF_HEADER" | cut -f1 -d:)
82# 脚本名称
83SCRIPT_NAME="$(basename "${0}")"
84# 版本
85VERSION="0.0.2"
86
87# 默认 host
88HOST=127.0.0.1
89# 默认 port
90PORT=8001
91# 默认 password
92PASSWORD=password
93
94# usage
95usage() {
96 head -"${SCRIPT_HEADSIZE:-99}" "${0}" \
97 | grep -e "^#%" \
98 | sed -e "s/^#%//g" -e "s/\${SCRIPT_NAME}/${SCRIPT_NAME}/g" -e "s/\${VERSION}/${VERSION}/g"
99}
100
101# redis-cli 方法
102cli() {
103 printf "\033[36mredis-cli -c -h %s -p %s -a %s %s \"%s\" \033[0m\n\n" "${HOST}" "${PORT}" "${PASSWORD}" "$1" "$2"
104 eval redis-cli -c -h "${HOST}" -p "${PORT}" -a "${PASSWORD}" "$1" \""$2"\"
105}
106
107# clusterCli 方法
108clusterCli() {
109 printf "\033[36mredis-cli -c -h %s -p %s -a %s cluster %s \033[0m\n\n" "${HOST}" "${PORT}" "${PASSWORD}" "$1"
110 eval redis-cli -c -h "${HOST}" -p "${PORT}" -a "${PASSWORD}" cluster "$1"
111}
112
113# 查询 master 节点
114masterNodes() {
115 masterNodes=$(clusterCli nodes | awk '{if($3=="master" || $3=="myself,master") print $2}' | awk -F@ '{print $1}')
116 printf "\033[36mRedis master nodes: \n%s\n\033[0m" "${masterNodes}"
117}
118
119# 清理所有 key
120flushallCli() {
121 masterNodes
122
123 # 循环清理
124 for master in ${masterNodes}
125 do
126 thost=${master%:*}
127 tport=${master#*:}
128 printf "\033[36m\nredis-cli -c -h %s -p %s -a %s flushall \033[0m\n" "${thost}" "${tport}" "${PASSWORD}"
129 eval redis-cli -c -h "${thost}" -p "${tport}" -a "${PASSWORD}" flushall
130 done
131}
132
133# 查询 key
134keysCli() {
135 masterNodes
136
137 # 循环查询 key
138 for master in ${masterNodes}
139 do
140 thost=${master%:*}
141 tport=${master#*:}
142 printf "\033[36m\nredis-cli -c -h %s -p %s -a %s keys \"%s\" \033[0m\n" "${thost}" "${tport}" "${PASSWORD}" "$1"
143 eval redis-cli -c -h "${thost}" -p "${tport}" -a "${PASSWORD}" keys \""$1"\"
144 done
145}
146
147# 批量删除相同前缀的 key,支持正则表达式
148bdelCli() {
149 masterNodes
150
151 # 循环查询 key
152 for master in ${masterNodes}
153 do
154 thost=${master%:*}
155 tport=${master#*:}
156 printf "\033[36m\nredis-cli -h %s -p %s -a %s --scan --pattern \"%s\" | xargs -L 1 redis-cli -h %s -p %s -a %s del\033[0m\n" "${thost}" "${tport}" "${PASSWORD}" "$1" "${thost}" "${tport}" "${PASSWORD}"
157 eval redis-cli -h "${thost}" -p "${tport}" -a "${PASSWORD}" --scan --pattern \""$1"\" | xargs -L 1 redis-cli -h "${thost}" -p "${tport}" -a "${PASSWORD}" del
158 done
159}
160
161# 操作确认
162inputYN() {
163 read -r -p "是否继续 \"$1\" 操作(y/n):" choose
164 case "${choose}" in
165 [yY])
166 return 0
167 ;;
168
169 [nN])
170 exit 1
171 ;;
172
173 *)
174 inputYN "$1"
175 ;;
176 esac
177}
178
179# 判断参数个数
180if [ $# -eq 0 ];
181then
182 usage
183 exit 1
184fi
185
186# getopt 命令行参数
187if ! ARGS=$(getopt -o vfh:p:a:g:d:c:k:b: --long flushall,help,version,host:,port:,password:,get:,del:,bdel:,password:,cluster:,keys: -n "${SCRIPT_NAME}" -- "$@")
188then
189 # 无效选项,则退出
190 exit 1
191fi
192
193# 命令行参数格式化
194eval set -- "${ARGS}"
195
196while [ -n "$1" ]
197do
198 case "$1" in
199 -a|--password)
200 PASSWORD=$2
201 shift 2
202 ;;
203
204 -h|--host)
205 HOST=$2
206 shift 2
207 ;;
208
209 -p|--port)
210 PORT="$2"
211 shift 2
212 ;;
213
214 -c|--cluster)
215 clusterCli "$2"
216 exit 1
217 ;;
218
219 -g|--get)
220 cli get "$2"
221 exit 1
222 ;;
223
224 -d|--del)
225 # 先显示内容
226 cli get "$2"
227 # 确认是否删除
228 inputYN "del"
229 # 删除
230 cli del "$2"
231 exit 1
232 ;;
233
234 -k|--keys)
235 keysCli "$2"
236 exit 1
237 ;;
238
239 -b|--bdel)
240 # 先显示匹配项
241 keysCli "$2"
242 # 确认是否删除
243 inputYN "batch del"
244 # 删除
245 bdelCli "$2"
246 exit 1
247 ;;
248
249 -f|--flushall)
250 # 确认是否删除
251 inputYN "flushall"
252 # 删除所有 key
253 flushallCli
254 exit 1
255 ;;
256
257 -v|--version)
258 printf "%s version %s\n" "${SCRIPT_NAME}" "${VERSION}"
259 exit 1
260 ;;
261
262 --help)
263 usage
264 exit 1
265 ;;
266
267 --)
268 shift
269 break
270 ;;
271
272 *)
273 printf "%s is not an option!" "$1"
274 exit 1
275 ;;
276
277 esac
278done