当前位置: 首页 > news >正文

操作 Redis 常用 shell 脚本

目录

1. 取出所有指定前缀的 string 类型的 key 及其 value

2. 批量删除 key

3. 一键批量删除指定 key

4. 非阻塞批量删除指定 key

5. 批量修改特征 key 的过期时间为一个指定区间内的随机数

6. 查询每个客户端 IP 的连接数

7. 迁移 zset 类型的 key

8. 根据哨兵提供的信息更新配置文件

9. 根据哨兵提供的信息生成配置模板文件


1. 取出所有指定前缀的 string 类型的 key 及其 value

# 取出 key
redis-cli -p 6379 -a 123456 -n 0 --scan --pattern "g.at.ga.*" > a.txt

# 拼出取 value 的命令
sed 's/^/get &/g' a.txt > b.txt

# 取 value
cat b.txt | redis-cli -p 6379 -a 123456 -n 0 --pipe > c.txt

# 将 key、value 拼成一个文件
paste a.txt c.txt > d.txt

2. 批量删除 key

(要删除的 key 已经导出到一个文件中)

# key 文件改名
mv keys.log keys.log.1

# 拼接删除 key 的命令
sed 's/^/unlink &/g' key.log.1 > key.log

# 执行批量删除
cat keys.log | redis-cli -p 6379 -a 123456 -n 0 --pipe

3. 一键批量删除指定 key

redis-cli -h 10.10.10.2 -p 6379 -a 123456 -n 1 --scan --pattern "g.at.ga.*" | \
xargs -n 1000 redis-cli -h 10.10.10.1 -p 6379 -a 123456 -n 1 unlink

4. 非阻塞批量删除指定 key

#!/bin/bash
 
command_dir="/home/redis/redis-5.0.3/src"
REDIS_PASSWORD=123456
 
# 已知主库和哨兵端口号,获取主库 IP
master_ip=`$command_dir/redis-cli -p 26379 info | grep 6379 | awk 'BEGIN{FS="[=:]"}{print $5}'`
# 从主库获取从库 IP 和端口
read slave_ip slave_port <<< `$command_dir/redis-cli -h $master_ip -p 6379 -a $REDIS_PASSWORD info replication | grep slave0 | awk -F"[=:,]" '{print $3,$5}'`
 
# 读从库写主库执行删除
$command_dir/redis-cli -h $slave_ip -p $slave_port -a $REDIS_PASSWORD -n 1 --scan --pattern "m_roam_[123456789]*" | \
awk '{print "unlink "$0}' | \
$command_dir/redis-cli -h $master_ip -p 6379 -a $REDIS_PASSWORD -n 1 --pipe

5. 批量修改特征 key 的过期时间为一个指定区间内的随机数

# 方法1,用循环逐行拼命令,很慢
rm -f c.txt
 
# 读从库导出 key
redis-cli -h 10.10.10.2 -p 6379 -a 123456 -n 1 --scan --pattern "room_onmic_photo:*" > a.txt
 
cat a.txt|while read line
do
    r=`expr $RANDOM % 3600`
    echo "expire ${line} $r" >> c.txt 
done
 
# 主库执行修改操作
cat c.txt | redis-cli -h 10.10.10.1 -p 6379 -a 123456 -n 1 --pipe
 
 
# 方法2,用 awk 拼命令,很快。通过管道一句执行,不需要临时文件。
redis-cli -h 10.10.10.2 -p 6379 -a 123456 -n 1 --scan --pattern "room_onmic_photo:*" | \
awk -v seed=$RANDOM 'BEGIN{srand(seed);} {print "expire "$0" " int(rand()*10000%3600+1) }' | \
redis-cli -h 10.10.10.1 -p 6379 -a 123456 -n 1 --pipe

6. 查询每个客户端 IP 的连接数

redis-cli -p 6379 -a 123456 client list | \
awk -F"[ =:]" '{print $4}' | sort -n | \
awk '{s[$1] += 1}END{ for(i in s){print i, s[i] } }' | sort -nrk2

7. 迁移 zset 类型的 key

# 导出
echo "zrange channel_overseas_final_hot 0 -1 withscores" | redis-cli -p 6379 -a 123456 -n 15 > zset.txt
# 导入
awk '{line=$0; getline; print "zadd channel_overseas_final_hot", $0,"\""line"\""}' zset.txt > zadd.txt
cat zadd.txt | redis-cli -p 6369 -a 123456 -n 15

8. 根据哨兵提供的信息更新配置文件

        本例只更新 IP 地址的最后一段。

/bin/cp -f ~/tmp_sentinel_monitor.txt ~/tmp_sentinel_monitor.txt.bak
redis-cli -p 26379 info | egrep master[0-9]+ | \
awk -F"[,=.:]" '{print $3, $10, $11}' | \ 
while read master_name ip port;
do
    sed -i -E "s/(sentinel monitor ${master_name} [0-9]+\.[0-9]+\.[0-9]+\.)[0-9]+ ${port} /\1${ip} ${port} /" ~/tmp_sentinel_monitor.txt
done

        这个需求无论怎样实现,本质上都是一个二重循环。上面这个脚本对配置文件执行了多次 sed 替换,次数是哨兵所监控的 master 数量。下面的脚本扫描一遍配置文件,但比上面的脚本执行还慢。

#!/bin/bash
 
# 保存哨兵的 info 输出
redis-cli -p 26379 info | egrep master[0-9]+ | sed 's/123.123.123/10.10.10/g' > info_output 
 
# 模板文件路径
template_file="tmp_sentinel_monitor.txt"
 
# 输出文件路径
output_file="output.conf"
 
# 清空输出文件
> "$output_file"
 
# 读取模板文件
while IFS= read -r line; do
    # 检查是否是 sentinel monitor 行
    if [[ "$line" =~ ^sentinel\ monitor ]]; then
        # 提取 Redis 实例名称
        redis_name=$(echo $line | awk '{print $3}')
        
        # 从 info 输出中提取对应的 IP 和端口
        address=$(cat info_output | grep "$redis_name," | awk -F"[=,]" '{print $6}')
        ip=$(echo "$address" | cut -d':' -f1)
        port=$(echo "$address" | cut -d':' -f2)
        
        # 替换模板中的 IP 和端口
        new_line="sentinel monitor $redis_name $ip $port 2"
        
        # 将新行写入输出文件
        echo "$new_line" >> "$output_file"
    else
        # 如果不是 sentinel monitor 行,直接写入输出文件
        echo "$line" >> "$output_file"
    fi
done < "$template_file"
 
echo "配置文件已生成: $output_file"

        高效的做法是,把 awk 输出的多列,每一列存储到一个 shell 数组中,然后用一个 sed 命令同时执行多个替换。这种方法只执行一次 awk 命令,通过遍历数组将多个 sed 替换命令写入一个临时脚本文件(避免单个 sed 命令过长),再只执行一次 sed 命令完成匹配和替换。update_tmp_sentinel_monitor.sh 文件内容如下:

#!/bin/bash
 
# 初始化数组
col_name=()
col_ip=()
col_port=()
 
# 使用 awk 一次性处理文件,并通过 read 解析每一列
while read -r c1 c2 c3; do
    col_name+=("$c1")
    col_ip+=("$c2")
    col_port+=("$c3")
done < <(redis-cli -p 26379 info | egrep master[0-9]+ | awk -F"[:=,.]" '{print $3,$10,$11}')
 
# 将 sed 替换脚本写入临时文件
sed_script=$(mktemp)
for i in "${!col_name[@]}"; do
    echo "s/(sentinel monitor ${col_name[$i]} [0-9]+\.[0-9]+\.[0-9]+\.)[0-9]+ ${col_port[$i]} /\1${col_ip[$i]} ${col_port[$i]} /" >> "$sed_script"
done
 
# 使用 sed -f 从临时文件中读取脚本并执行替换
sed -i -E -f "$sed_script" tmp_sentinel_monitor.txt
 
# 删除临时文件
rm -f "$sed_script"

9. 根据哨兵提供的信息生成配置模板文件

        generate_tmp_sentinel_monitor.sh 文件内容如下:

#!/bin/bash
 
# 初始化变量
port=26379
sentinel_dir="/sentinel"
command_dir="/home/redis/redis-5.0.3/src"
 
# 初始化数组
col_name=()
col_ip=()
col_port=()
 
# 初始化文件
tmp_sentinel_monitor_file="${HOME}/tmp_sentinel_monitor.txt" 
> "$tmp_sentinel_monitor_file"
 
# 生成全局配置
echo -e "port ${port}\nprotected-mode no\ndir \"${sentinel_dir}\"\n" >> "$tmp_sentinel_monitor_file"
 
# 将 awk 输出的三列按端口号排序后,分别存储到三个数组中
while read -r c1 c2 c3; do
    col_name+=("$c1")
    col_ip+=("$c2")
    col_port+=("$c3")
done < <($command_dir/redis-cli -p $port info | egrep master[0-9]+ | awk -F"[:=,]" '{print $3,$7,$8}' | sort -k3n)
 
# 遍历数组,生成哨兵监控配置
for i in "${!col_name[@]}"; do
    if [ ${col_name[$i]} == "cluster1" ]; then
        password="cluster1"
    elif [ ${col_name[$i]} == "cluster2" ] || [ ${col_name[$i]} == "cluster3" ] || [ ${col_name[$i]} == "cluster4" ]; then
        password="cluster2"
    elif [ ${col_name[$i]} == "cluster5" ]; then
        password="cluster5"
    else
        password="123456"
    fi
    
    echo "sentinel monitor ${col_name[$i]} ${col_ip[$i]} ${col_port[$i]} 2" >> "$tmp_sentinel_monitor_file"
    echo "sentinel down-after-milliseconds ${col_name[$i]} 5000" >> "$tmp_sentinel_monitor_file"
    echo "sentinel failover-timeout ${col_name[$i]} 10000" >> "$tmp_sentinel_monitor_file"
    echo "sentinel auth-pass ${col_name[$i]} ${password}" >> "$tmp_sentinel_monitor_file"
    echo >> "$tmp_sentinel_monitor_file"
done
 
# 删除最后一个空行,并替换成内网地址
sed -i '${/^\s*$/d};s/123.123.123/10.10.10/g' "$tmp_sentinel_monitor_file"

相关文章:

  • 获取哔站评论
  • 【JavaScript — 前端快速入门】 JavaScript 引入方式
  • 全向广播扬声器在油气田中的关键应用 全方位守护安全
  • 充电桩测试负载应用:保障充电安全与性能的核心技术
  • SpringBoot获取YAML配置文件中的属性值(二):使用Environment环境组件读取值
  • 非docker方式部署openwebui过程记录
  • 【MySQL】事务二
  • deepseek助力运维和监控自动化
  • LeetCode 链表章节
  • 深度学习-138-LangGraph之应用实例(七)构建自动绘图系统
  • 3D相机的种类
  • 腾讯云 | 微搭低代码快速开发数据表单应用
  • DFT之SSN架构
  • UniApp如何判断平台的多种方法(2025最新指南)
  • 【大模型学习】第一章 大模型技术综述
  • 2025年渗透测试面试题总结- 阿某云安全实习(题目+回答)
  • 第四节:基于Winform框架的串口助手小项目---开关串口《C#编程》
  • 链表-相关面试算法题
  • Android Studio 的详细安装步骤,适用于 Windows/MacOS/Linux 系统
  • MySQL数据库安装(详细)—>Mariadb的安装
  • wordpress页面归档/站长工具之家seo查询
  • 常用浏览器网址大全/星乐seo网站关键词排名优化
  • 做外贸哪个英文网站好/杭州搜索引擎优化公司
  • 去国外做网站/百度搜索网页
  • 江西航达建设集团网站/什么优化
  • 网站建设维护费摊销/抖来查关键词搜索排名