news 2026/5/5 2:18:55

清理三主三从redis集群的过期key和键值超过10M的key

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
清理三主三从redis集群的过期key和键值超过10M的key

一.基于shell脚本进行删除

针对 Redis 三主三从集群,要实现定时清理过期 Key + 超过 10M 的超大 Key,核心思路是:

  1. 自动识别集群所有主节点(从节点无需清理,数据同步主节点);
  2. 基于SCAN非阻塞遍历主节点 Key,筛选目标后删除;
  3. 通过 Linuxcrontab配置定时任务,低峰期自动执行。

以下是基于shell脚本实现

#!/bin/bash # Redis 集群清理脚本:删除过期 Key + 超过10M的Key # 适配三主三从集群,仅清理主节点 ########################## 配置区(根据实际修改) ########################## # Redis 集群任意节点地址(用于获取主节点列表) CLUSTER_ANY_NODE="10.10.19.11:6379" # Redis 密码(无密码则注释此行,后续删除 -a $REDIS_PASSWORD) REDIS_PASSWORD="your_redis_password" # 超大 Key 阈值:10M(字节) MAX_KEY_SIZE=$((10 * 1024 * 1024)) # SCAN 每次遍历 Key 数量(建议 100-500,越小越不阻塞) SCAN_COUNT=500 # 日志文件路径 LOG_FILE="/var/log/redis_cluster_clean.log" ########################################################################### # 日志函数(带时间戳) log() { echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> $LOG_FILE } # 检查 redis-cli 是否存在 if ! command -v redis-cli &> /dev/null; then log "错误:未找到 redis-cli,请确保 Redis 客户端已安装" exit 1 fi # 步骤1:获取集群所有主节点(过滤从节点、空行) log "开始获取集群主节点列表..." MASTER_NODES=$(redis-cli -h $(echo $CLUSTER_ANY_NODE | cut -d':' -f1) \ -p $(echo $CLUSTER_ANY_NODE | cut -d':' -f2) \ -a $REDIS_PASSWORD --raw CLUSTER NODES 2>> $LOG_FILE \ | grep -E "master|myself,master" \ | awk '{print $2}' \ | cut -d'@' -f1 \ | sort -u) if [ -z "$MASTER_NODES" ]; then log "错误:未获取到集群主节点,请检查集群连接或密码" exit 1 fi log "获取到主节点列表:$MASTER_NODES" # 步骤2:遍历每个主节点,清理目标 Key TOTAL_DELETED_EXPIRED=0 # 累计删除过期 Key 数 TOTAL_DELETED_LARGE=0 # 累计删除超大 Key 数 for NODE in $MASTER_NODES; do NODE_HOST=$(echo $NODE | cut -d':' -f1) NODE_PORT=$(echo $NODE | cut -d':' -f2) log "开始清理主节点:$NODE_HOST:$NODE_PORT" # 初始化 SCAN 游标 CURSOR=0 # 节点内删除计数 NODE_EXPIRED=0 NODE_LARGE=0 # 循环 SCAN 遍历当前节点所有 Key while :; do # 执行 SCAN 命令(--raw 避免中文/特殊字符乱码) SCAN_RESULT=$(redis-cli -h $NODE_HOST -p $NODE_PORT -a $REDIS_PASSWORD \ --raw SCAN $CURSOR COUNT $SCAN_COUNT 2>> $LOG_FILE) # 解析游标(第一行)和 Key 列表(剩余行) NEW_CURSOR=$(echo "$SCAN_RESULT" | head -n 1) KEYS=$(echo "$SCAN_RESULT" | tail -n +2) # 遍历当前批次 Key for KEY in $KEYS; do # 跳过空 Key [ -z "$KEY" ] && continue # 条件1:删除已过期 Key(TTL ≤ 0,-2=Key不存在,-1=永不过期,0=已过期) TTL=$(redis-cli -h $NODE_HOST -p $NODE_PORT -a $REDIS_PASSWORD --raw TTL "$KEY" 2>> $LOG_FILE) if [ "$TTL" -le 0 ] && [ "$TTL" -ne -1 ]; then # 排除永不过期的 Key redis-cli -h $NODE_HOST -p $NODE_PORT -a $REDIS_PASSWORD DEL "$KEY" >> /dev/null 2>&1 NODE_EXPIRED=$((NODE_EXPIRED + 1)) log "[$NODE] 删除过期 Key: $KEY (TTL: $TTL)" continue fi # 条件2:删除超过10M的 Key KEY_SIZE=$(redis-cli -h $NODE_HOST -p $NODE_PORT -a $REDIS_PASSWORD --raw MEMORY USAGE "$KEY" 2>> $LOG_FILE) # 防止 MEMORY USAGE 返回非数字(如 Key 被并发删除) if [[ "$KEY_SIZE" =~ ^[0-9]+$ ]] && [ "$KEY_SIZE" -gt "$MAX_KEY_SIZE" ]; then redis-cli -h $NODE_HOST -p $NODE_PORT -a $REDIS_PASSWORD DEL "$KEY" >> /dev/null 2>&1 NODE_LARGE=$((NODE_LARGE + 1)) log "[$NODE] 删除超大 Key: $KEY (大小: $KEY_SIZE 字节,阈值: $MAX_KEY_SIZE 字节)" fi done # 游标为 0 表示当前节点遍历完成 if [ "$NEW_CURSOR" = "0" ]; then break fi CURSOR=$NEW_CURSOR done # 累计节点删除数 TOTAL_DELETED_EXPIRED=$((TOTAL_DELETED_EXPIRED + NODE_EXPIRED)) TOTAL_DELETED_LARGE=$((TOTAL_DELETED_LARGE + NODE_LARGE)) log "[$NODE] 清理完成:过期 Key 删 $NODE_EXPIRED 个,超大 Key 删 $NODE_LARGE 个" done # 步骤3:输出总清理结果 log "==================== 清理汇总 ====================" log "集群总清理:过期 Key 共 $TOTAL_DELETED_EXPIRED 个,超大 Key 共 $TOTAL_DELETED_LARGE 个" log "===================================================" log " " # 空行分隔日志 exit 0

二.基于lua脚本删除

在 Redis 三主三从集群中使用 Lua 脚本清理过期 Key超过 10M 的超大 Key,核心优势是:

  1. Lua 脚本在 Redis 服务端原子执行,减少网络往返(相比 Shell/Python 遍历更高效);
  2. 结合SCAN非阻塞遍历,避免阻塞主线程;
  3. 适配集群特性(仅清理主节点,从节点同步删除结果)。

创建redis_clean.lua,实现单节点的 Key 筛选与删除(可直接在 Redis 节点执行)

-- Redis 单节点清理脚本:删除过期 Key + 超过10M的超大 Key -- 参数说明: -- ARGV[1] = 超大 Key 阈值(字节,如 10485760 表示 10M) -- ARGV[2] = SCAN 每次遍历数量(如 200) -- 初始化变量 local max_key_size = tonumber(ARGV[1]) local scan_count = tonumber(ARGV[2]) local cursor = "0" local deleted_expired = 0 -- 过期 Key 删除计数 local deleted_large = 0 -- 超大 Key 删除计数 local batch_del = {} -- 批量删除缓存(避免频繁 DEL) local batch_max = 50 -- 每批次最多删 50 个 Key -- 循环 SCAN 遍历所有 Key repeat -- 执行 SCAN:cursor = 下一个游标, keys = 当前批次 Key 列表 local scan_result = redis.call("SCAN", cursor, "COUNT", scan_count) cursor = scan_result[1] local keys = scan_result[2] -- 遍历当前批次 Key for _, key in ipairs(keys) do -- 跳过空 Key if key == nil or key == "" then goto continue end -- 条件1:删除已过期 Key(ttl ≤ 0 且 不是永不过期) local ttl = redis.call("TTL", key) if ttl <= 0 and ttl ~= -1 then table.insert(batch_del, key) deleted_expired = deleted_expired + 1 goto continue -- 满足过期条件,无需检查大小 end -- 条件2:删除超过阈值的超大 Key local size = redis.call("MEMORY", "USAGE", key) if tonumber(size) > max_key_size then table.insert(batch_del, key) deleted_large = deleted_large + 1 end ::continue:: -- 批量删除:达到批次上限则执行 DEL if #batch_del >= batch_max then redis.call("DEL", unpack(batch_del)) batch_del = {} -- 清空缓存 end end -- 游标为 0 时结束遍历 until cursor == "0" -- 处理剩余未删除的 Key if #batch_del > 0 then redis.call("DEL", unpack(batch_del)) end -- 返回清理结果 return { ["deleted_expired"] = deleted_expired, ["deleted_large"] = deleted_large }

编写redis_cluster_lua_clean.sh,自动识别集群主节点,逐个执行 Lua 脚本(适配三主三从集群):

#!/bin/bash # Redis 三主三从集群清理脚本(Lua 版) # 自动识别主节点 → 执行 Lua 脚本 → 输出清理结果 ########################## 配置区(根据实际修改) ########################## # Redis 集群任意节点(用于获取主节点列表) CLUSTER_NODE="192.168.1.10:6379" # Redis 密码(无密码则删除 -a $REDIS_PWD) REDIS_PWD="your_redis_password" # 超大 Key 阈值:10M(字节) MAX_SIZE=$((10 * 1024 * 1024)) # SCAN 每次遍历数量(建议 200-500) SCAN_COUNT=200 # Lua 脚本路径 LUA_SCRIPT="/path/to/redis_clean.lua" # 日志文件 LOG_FILE="/var/log/redis_cluster_lua_clean.log" ########################################################################### # 日志函数(带时间戳) log() { echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> $LOG_FILE } # 检查依赖 if ! command -v redis-cli &> /dev/null; then log "错误:未找到 redis-cli,请安装 Redis 客户端" exit 1 fi if [ ! -f "$LUA_SCRIPT" ]; then log "错误:Lua 脚本不存在 → $LUA_SCRIPT" exit 1 fi # 步骤1:获取集群所有主节点 log "开始获取集群主节点列表..." MASTER_NODES=$(redis-cli -h $(echo $CLUSTER_NODE | cut -d':' -f1) \ -p $(echo $CLUSTER_NODE | cut -d':' -f2) \ -a $REDIS_PWD --raw CLUSTER NODES 2>> $LOG_FILE \ | grep -E "master|myself,master" \ | awk '{print $2}' | cut -d'@' -f1 | sort -u) if [ -z "$MASTER_NODES" ]; then log "错误:未获取到主节点,请检查集群连接/密码" exit 1 fi log "获取到主节点:$MASTER_NODES" # 步骤2:遍历主节点执行 Lua 脚本 TOTAL_EXPIRED=0 TOTAL_LARGE=0 for NODE in $MASTER_NODES; do HOST=$(echo $NODE | cut -d':' -f1) PORT=$(echo $NODE | cut -d':' -f2) log "开始清理主节点 → $HOST:$PORT" # 执行 Lua 脚本(--eval 加载脚本,ARGV 传参) RESULT=$(redis-cli -h $HOST -p $PORT -a $REDIS_PWD --raw \ EVAL "$(cat $LUA_SCRIPT)" 0 $MAX_SIZE $SCAN_COUNT 2>> $LOG_FILE) # 解析 Lua 返回结果(示例:{deleted_expired=10,deleted_large=2}) NODE_EXPIRED=$(echo $RESULT | grep -oP 'deleted_expired"\s*:\s*\K\d+') NODE_LARGE=$(echo $RESULT | grep -oP 'deleted_large"\s*:\s*\K\d+') # 兼容空结果 NODE_EXPIRED=${NODE_EXPIRED:-0} NODE_LARGE=${NODE_LARGE:-0} # 累计计数 TOTAL_EXPIRED=$((TOTAL_EXPIRED + NODE_EXPIRED)) TOTAL_LARGE=$((TOTAL_LARGE + NODE_LARGE)) log "[$HOST:$PORT] 清理完成 → 过期 Key:$NODE_EXPIRED 个,超大 Key:$NODE_LARGE 个" done # 步骤3:输出汇总 log "==================== 集群清理汇总 ====================" log "总删除:过期 Key = $TOTAL_EXPIRED 个,超大 Key = $TOTAL_LARGE 个" log "======================================================" log " " # 空行分隔日志 exit 0
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/27 4:25:25

3B参数大模型崛起:IBM Granite-4.0-Micro如何重塑企业AI部署格局

导语 【免费下载链接】granite-4.0-micro 项目地址: https://ai.gitcode.com/hf_mirrors/ibm-granite/granite-4.0-micro 2025年10月&#xff0c;IBM发布的3B参数模型Granite-4.0-Micro以"轻量级架构企业级性能"的组合&#xff0c;标志着AI行业正式进入"…

作者头像 李华
网站建设 2026/4/29 14:57:41

11、云生活入门:网本软件与服务全攻略

云生活入门:网本软件与服务全攻略 在当今数字化时代,云生活已经成为了一种趋势,而网本则是我们畅享云生活的得力助手。下面将为大家介绍一系列实用的云服务软件,以及一个有趣的实践项目。 实用云服务软件推荐 QuickTime Player :苹果公司的QuickTime Player同时支持Wi…

作者头像 李华
网站建设 2026/5/1 15:23:36

Vencord权限突破指南:如何全局启用ModView功能

Vencord权限突破指南&#xff1a;如何全局启用ModView功能 【免费下载链接】Vencord The cutest Discord client mod 项目地址: https://gitcode.com/GitHub_Trending/ve/Vencord Discord社区管理中的ModView功能原本只为管理员设计&#xff0c;但普通用户也经常需要查看…

作者头像 李华
网站建设 2026/4/30 5:43:57

NVIDIA DALI性能验证突破:重新定义MLPerf基准测试标准

NVIDIA DALI性能验证突破&#xff1a;重新定义MLPerf基准测试标准 【免费下载链接】DALI NVIDIA/DALI: DALI 是一个用于数据预处理和增强的 Python 库&#xff0c;可以用于图像&#xff0c;视频和音频数据的处理和增强&#xff0c;支持多种数据格式和平台&#xff0c;如 Python…

作者头像 李华
网站建设 2026/5/4 21:11:03

Kuboard与AI结合:智能K8s管理新体验

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个基于Kuboard的AI辅助插件&#xff0c;实现以下功能&#xff1a;1. 自动分析K8s集群日志&#xff0c;识别异常模式并给出修复建议 2. 智能预测资源需求&#xff0c;自动调整…

作者头像 李华
网站建设 2026/5/2 10:11:08

效率对比:手打 vs 脚本——僵尸游戏辅助实测

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个僵尸游戏效率测试工具&#xff0c;能够记录并比较手动操作和脚本操作的以下数据&#xff1a;击杀数/分钟、资源收集量/分钟、生存时间。使用Python编写&#xff0c;包含数据…

作者头像 李华