百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

Redis 日常运维脚本(增加集群批量删除 key 功能)

mhr18 2024-10-24 11:11 22 浏览 0 评论

需求背景

由于应用 bug 造成某些特定前缀的缓存出错,需要批量清理。


Redis 日常运维脚本 中的 redis-tools.sh 仅支持删除单个 key 和 全部清理,并未实现匹配特定前缀批量删除的功能。

批量删除 key

$ 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 删除等功能脚本


选项

sh ${SCRIPT_NAME} [options] <value> ...
    -h<value>, --host=<value>            Redis IP,可设置默认值参数:HOST
    -p<value>, --port=<value>            Redis 端口,可设置默认值参数:PORT
    -a<value>, --password=<value>        Redis 密码,可设置默认值参数:PASSWORD
    -c<value>, --cluster=<value>         集群相关命令,如:nodes, info
    -k<pattern>, --keys=<pattern>        查询 key,支持正则表达式
    -g<value>, --get=<value>             获取指定 key 的值
    -d<value>, --del=<value>             删除指定 key,不支持正则表达式,原因:redis 的 del 命令不支持正则表达式
    -b<pattern>, --bdel=<pattern>        批量删除 key,支持正则表达式
    -f, --flushall                       删除所有 key
    --help                               帮助信息
    -v, --version                        版本信息

示例

redis key示例数据格式:
       "party::123"
       "party::456"
1. 查询集群信息,使用默认参数
sh redis-tools.sh -c info
2. 查询集群节点
sh redis-tools.sh -h 127.0.0.1 -p 8001 -a password -c nodes
3. 查询 key,支持正则表达式
sh redis-tools.sh -k "party::123"
sh redis-tools.sh -k "party*"
4. 获取指定 key 值
sh redis-tools.sh -g "party::123"
5. 删除指定 key,不支持正则表达式,原因:redis 的 del 命令不支持正则表达式
sh redis-tools.sh -d "party::123"
6. 批量删除 key,支持正则表达式
sh redis-tools.sh -b "party::123"
sh redis-tools.sh -b "party*"
7. 删除所有 key
sh redis-tools.sh -f

脚本

$ cat redis-tools.sh
#!/bin/bash
#================================================================
# HEADER
#================================================================
#    Filename         redis-tools.sh
#    Revision         0.0.2
#    Date             2020/04/26
#    Author           jiangliheng
#    Email            jiang_liheng@163.com
#    Website          https://jiangliheng.github.io/
#    Description      Redis 日常运维脚本
#    Copyright        Copyright (c) jiangliheng
#    License          GNU General Public License
#
#================================================================
#  Version 0.0.2 2020/05/16
#     修正 inputYN 多次回车,导致参数丢失问题
#     修正 部分描述信息,调整格式等
#     增加 “批量删除 key,支持正则表达式” 方法
#
#  Version 0.0.1 2020/04/26
#     创建 Redis 集群情况查询、key 查询、key 删除等功能脚本
#
#================================================================
#%名称(NAME)
#%       ${SCRIPT_NAME} - Redis 日常运维脚本
#%
#%概要(SYNOPSIS)
#%       sh ${SCRIPT_NAME} [options] <value> ...
#%
#%描述(DESCRIPTION)
#%       Redis 日常运维脚本
#%
#%选项(OPTIONS)
#%       -h<value>, --host=<value>            Redis IP,可设置默认值参数:HOST
#%       -p<value>, --port=<value>            Redis 端口,可设置默认值参数:PORT
#%       -a<value>, --password=<value>        Redis 密码,可设置默认值参数:PASSWORD
#%       -c<value>, --cluster=<value>         集群相关命令,如:nodes, info
#%       -k<pattern>, --keys=<pattern>        查询 key,支持正则表达式
#%       -g<value>, --get=<value>             获取指定 key 的值
#%       -d<value>, --del=<value>             删除指定 key,不支持正则表达式,原因:redis 的 del 命令不支持正则表达式
#%       -b<pattern>, --bdel=<pattern>        批量删除 key,支持正则表达式
#%       -f, --flushall                       删除所有 key
#%       --help                               帮助信息
#%       -v, --version                        版本信息
#%
#%示例(EXAMPLES)
#%       redis key示例数据格式:
#%              "party::123"
#%              "party::456"
#%
#%       1. 查询集群信息,使用默认参数
#%       sh ${SCRIPT_NAME} -c info
#%
#%       2. 查询集群节点
#%       sh ${SCRIPT_NAME} -h 127.0.0.1 -p 8001 -a password -c nodes
#%
#%       3. 查询 key,支持正则表达式
#%       sh ${SCRIPT_NAME} -k "party::123"
#%       sh ${SCRIPT_NAME} -k "party*"
#%
#%       4. 获取指定 key 值
#%       sh ${SCRIPT_NAME} -g "party::123"
#%
#%       5. 删除指定 key,不支持正则表达式,原因:redis 的 del 命令不支持正则表达式
#%       sh ${SCRIPT_NAME} -d "party::123"
#%
#%       6. 批量删除 key,支持正则表达式
#%       sh ${SCRIPT_NAME} -b "party::123"
#%       sh ${SCRIPT_NAME} -b "party*"
#%
#%       7. 删除所有 key
#%       sh ${SCRIPT_NAME} -f
#%
#================================================================
# END_OF_HEADER
#================================================================
# header 总行数
SCRIPT_HEADSIZE=$(head -200 "${0}" |grep -n "^# END_OF_HEADER" | cut -f1 -d:)
# 脚本名称
SCRIPT_NAME="$(basename "${0}")"
# 版本
VERSION="0.0.2"
# 默认 host
HOST=127.0.0.1
# 默认 port
PORT=8001
# 默认 password
PASSWORD=password
# usage
usage() {
  head -"${SCRIPT_HEADSIZE:-99}" "${0}" \
  | grep -e "^#%" \
  | sed -e "s/^#%//g" -e "s/\${SCRIPT_NAME}/${SCRIPT_NAME}/g" -e "s/\${VERSION}/${VERSION}/g"
}
# redis-cli 方法
cli() {
  printf "\033[36mredis-cli -c -h %s -p %s -a %s %s \"%s\" \033[0m\n\n" "${HOST}" "${PORT}" "${PASSWORD}" "$1" "$2"
  eval redis-cli -c -h "${HOST}" -p "${PORT}" -a "${PASSWORD}" "$1" \""$2"\"
}
# clusterCli 方法
clusterCli() {
  printf "\033[36mredis-cli -c -h %s -p %s -a %s cluster %s \033[0m\n\n" "${HOST}" "${PORT}" "${PASSWORD}" "$1"
  eval redis-cli -c -h "${HOST}" -p "${PORT}" -a "${PASSWORD}" cluster "$1"
}
# 查询 master 节点
masterNodes() {
  masterNodes=$(clusterCli nodes | awk '{if($3=="master" || $3=="myself,master") print $2}' | awk -F@ '{print $1}')
  printf "\033[36mRedis master nodes: \n%s\n\033[0m" "${masterNodes}"
}
# 清理所有 key
flushallCli() {
  masterNodes
  # 循环清理
  for master in ${masterNodes}
  do
    thost=${master%:*}
    tport=${master#*:}
    printf "\033[36m\nredis-cli -c -h %s -p %s -a %s flushall \033[0m\n" "${thost}" "${tport}" "${PASSWORD}"
    eval redis-cli -c -h "${thost}" -p "${tport}" -a "${PASSWORD}" flushall
  done
}
# 查询 key
keysCli() {
  masterNodes
  # 循环查询 key
  for master in ${masterNodes}
  do
    thost=${master%:*}
    tport=${master#*:}
    printf "\033[36m\nredis-cli -c -h %s -p %s -a %s keys \"%s\" \033[0m\n" "${thost}" "${tport}" "${PASSWORD}" "$1"
    eval redis-cli -c -h "${thost}" -p "${tport}" -a "${PASSWORD}" keys \""$1"\"
  done
}
# 批量删除相同前缀的 key,支持正则表达式
bdelCli() {
  masterNodes
  # 循环查询 key
  for master in ${masterNodes}
  do
    thost=${master%:*}
    tport=${master#*:}
    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}"
    eval redis-cli -h "${thost}" -p "${tport}" -a "${PASSWORD}" --scan --pattern \""$1"\" | xargs -L 1 redis-cli -h "${thost}" -p "${tport}" -a "${PASSWORD}" del
  done
}
# 操作确认
inputYN() {
  read -r -p "是否继续 \"$1\" 操作(y/n):" choose
  case "${choose}" in
    [yY])
      return 0
      ;;
    [nN])
      exit 1
      ;;
    *)
      inputYN "$1"
      ;;
  esac
}
# 判断参数个数
if [ $# -eq 0 ];
then
  usage
  exit 1
fi
# getopt 命令行参数
if ! 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}" -- "$@")
then
  # 无效选项,则退出
  exit 1
fi
# 命令行参数格式化
eval set -- "${ARGS}"
while [ -n "$1" ]
do
  case "$1" in
    -a|--password)
      PASSWORD=$2
      shift 2
      ;;
    -h|--host)
      HOST=$2
      shift 2
      ;;
    -p|--port)
      PORT="$2"
      shift 2
      ;;
    -c|--cluster)
      clusterCli "$2"
      exit 1
      ;;
    -g|--get)
      cli get "$2"
      exit 1
      ;;
    -d|--del)
      # 先显示内容
      cli get "$2"
      # 确认是否删除
      inputYN "del"
      # 删除
      cli del "$2"
      exit 1
      ;;
    -k|--keys)
      keysCli "$2"
      exit 1
      ;;
    -b|--bdel)
      # 先显示匹配项
      keysCli "$2"
      # 确认是否删除
      inputYN "batch del"
      # 删除
      bdelCli "$2"
      exit 1
      ;;
    -f|--flushall)
      # 确认是否删除
      inputYN "flushall"
      # 删除所有 key
      flushallCli
      exit 1
      ;;
    -v|--version)
      printf "%s version %s\n" "${SCRIPT_NAME}" "${VERSION}"
      exit 1
      ;;
    --help)
      usage
      exit 1
      ;;
    --)
      shift
      break
      ;;
    *)
      printf "%s is not an option!" "$1"
      exit 1
      ;;
  esac
done

?

相关推荐

使用 Docker 部署 Java 项目(通俗易懂)

前言:搜索镜像的网站(推荐):DockerDocs1、下载与配置Docker1.1docker下载(这里使用的是Ubuntu,Centos命令可能有不同)以下命令,默认不是root用户操作,...

Spring Boot 3.3.5 + CRaC:从冷启动到秒级响应的架构实践与踩坑实录

去年,我们团队负责的电商订单系统因扩容需求需在10分钟内启动200个Pod实例。当运维组按下扩容按钮时,传统SpringBoot应用的冷启动耗时(平均8.7秒)直接导致流量洪峰期出现30%的请求超时...

《github精选系列》——SpringBoot 全家桶

1简单总结1SpringBoot全家桶简介2项目简介3子项目列表4环境5运行6后续计划7问题反馈gitee地址:https://gitee.com/yidao620/springbo...

Nacos简介—1.Nacos使用简介

大纲1.Nacos的在服务注册中心+配置中心中的应用2.Nacos2.x最新版本下载与目录结构3.Nacos2.x的数据库存储与日志存储4.Nacos2.x服务端的startup.sh启动脚...

spring-ai ollama小试牛刀

序本文主要展示下spring-aiollama的使用示例pom.xml<dependency><groupId>org.springframework.ai<...

SpringCloud系列——10Spring Cloud Gateway网关

学习目标Gateway是什么?它有什么作用?Gateway中的断言使用Gateway中的过滤器使用Gateway中的路由使用第1章网关1.1网关的概念简单来说,网关就是一个网络连接到另外一个网络的...

Spring Boot 自动装配原理剖析

前言在这瞬息万变的技术领域,比了解技术的使用方法更重要的是了解其原理及应用背景。以往我们使用SpringMVC来构建一个项目需要很多基础操作:添加很多jar,配置web.xml,配置Spr...

疯了!Spring 再官宣惊天大漏洞

Spring官宣高危漏洞大家好,我是栈长。前几天爆出来的Spring漏洞,刚修复完又来?今天愚人节来了,这是和大家开玩笑吗?不是的,我也是猝不及防!这个玩笑也开的太大了!!你之前看到的这个漏洞已...

「架构师必备」基于SpringCloud的SaaS型微服务脚手架

简介基于SpringCloud(Hoxton.SR1)+SpringBoot(2.2.4.RELEASE)的SaaS型微服务脚手架,具备用户管理、资源权限管理、网关统一鉴权、Xss防跨站攻击、...

SpringCloud分布式框架&amp;分布式事务&amp;分布式锁

总结本文承接上一篇SpringCloud分布式框架实践之后,进一步实践分布式事务与分布式锁,其中分布式事务主要是基于Seata的AT模式进行强一致性,基于RocketMQ事务消息进行最终一致性,分布式...

SpringBoot全家桶:23篇博客加23个可运行项目让你对它了如指掌

SpringBoot现在已经成为Java开发领域的一颗璀璨明珠,它本身是包容万象的,可以跟各种技术集成。本项目对目前Web开发中常用的各个技术,通过和SpringBoot的集成,并且对各种技术通...

开发好物推荐12之分布式锁redisson-sb

前言springboot开发现在基本都是分布式环境,分布式环境下分布式锁的使用必不可少,主流分布式锁主要包括数据库锁,redis锁,还有zookepper实现的分布式锁,其中最实用的还是Redis分...

拥抱Kubernetes,再见了Spring Cloud

相信很多开发者在熟悉微服务工作后,才发现:以为用SpringCloud已经成功打造了微服务架构帝国,殊不知引入了k8s后,却和CloudNative的生态发展脱轨。从2013年的...

Zabbix/J监控框架和Spring框架的整合方法

Zabbix/J是一个Java版本的系统监控框架,它可以完美地兼容于Zabbix监控系统,使得开发、运维等技术人员能够对整个业务系统的基础设施、应用软件/中间件和业务逻辑进行全方位的分层监控。Spri...

SpringBoot+JWT+Shiro+Mybatis实现Restful快速开发后端脚手架

作者:lywJee来源:cnblogs.com/lywJ/p/11252064.html一、背景前后端分离已经成为互联网项目开发标准,它会为以后的大型分布式架构打下基础。SpringBoot使编码配置...

取消回复欢迎 发表评论: