>_ 智斗星 工具库
← 全部工具
redis-memory-audit

Redis 内存排查

统计各业务 Key 的内存占用、无过期时间占用和大 Key,按业务内存排序。只传 IP,按提示输入密码即可运行。

下载 v1.0.3 ↓23.1 KiB / tar.gz

使用说明

来自当前版本包内 README,下载后也可离线查看。

# Redis 内存排查

版本 1.0.3。支持 Python 3.6+ 及 SQLite 3.6.20+,目标 Redis 需支持 MEMORY USAGE(Redis 4.0+)。解压后进入目录,首次使用时用运行脚本的同一个 Python 安装依赖:

```bash
python -m pip install -r requirements.txt
```

依赖会自动选择:Python 3.6/3.7 安装 `redis 4.3.6`,Python 3.8+ 安装 `redis 5.3.1`。`pip` 提示旧包装器时也统一用上面的 `python -m pip`。

本版本已包含旧 Python 客户端及 SQLite 初始化兼容修复。旧版本有安装或建表错误时,按下面的更新方式升级即可。若本地文件操作仍失败,会显示具体错误、SQLite 版本和数据库路径。

## 一键更新

以后在工具目录执行一条命令:

```bash
bash update.sh
```

它会检查工具站最新版本、校验下载包 SHA-256、自动更新程序。已经是最新版时直接结束。旧程序自动备份到 `.update-backups/`;更新报错会还原已替换文件。原有报告目录和自定义 `business_rules.example.json` 保留;如果新版默认规则不同,另存为 `business_rules.example.json.dist` 供对照。

需要新依赖时自动安装到工具内的 `.dependencies/`,不修改系统 Python 包。默认使用 `python`;若平时通过 `python3` 运行,可使用 `PYTHON=python3 bash update.sh`。

**旧包还没有 update.sh 时,只需做一次:**在现有工具目录运行下面的命令,直接补上更新脚本并升级,不用重新下载、解压整个包。

```bash
curl -fsS https://tools.zhidouxing.cn/install/redis-memory-audit/update.sh -o update.sh && bash update.sh
```

## 运行排查

**只传 IP,按提示输入密码即可:**

```bash
python redis_memory_audit.py 你的RedisIP
```

密码隐藏输入;无密码直接回车。已有 `REDISCLI_AUTH` 环境变量时自动使用。

默认端口 **6379**、**DB 0**。从头扫描到结束,没有 Key 数量或扫描时长限制。觉得需要停止就按 **Ctrl+C**,脚本会将已完成的统计保存下来,并标注为部分结果。

限速、去重、业务归组和结果目录均自动处理,不必指定参数。每秒约 200 条查询命令,每个 Key 查询 4 次;扫描较大数据库需要时间。脚本只查询,不读取 Value,不删除 Key,不修改过期时间。

## 看哪些结果

结果自动存入当前目录的 `redis-audit-时间/`:

| 文件 | 内容 |
|---|---|
| `business_memory.csv` | 按业务总内存降序,附 Key 数量、内存占比、无 TTL 占用 |
| `business_no_ttl.csv` | 按各业务无 TTL 内存降序 |
| `no_ttl_keys.csv` | 具体无 TTL Key 及其内存,按内存降序 |
| `top_keys.csv` | 内存最大的 30 个 Key |
| `summary.json` | 扫描是否完整、内存汇总、发现但消失或查询失败的 Key 数 |
| `audit.sqlite3` | 本地去重和采集明细,可用于后续分析 |

先看两个业务 CSV 的前几行,再查对应的大 Key。业务占比以**本次成功测量的 Key 内存总和**为分母;它不是 Redis 进程 RSS 占比。Ctrl+C 得到的部分结果不能外推整个库。

## 自动业务归组

自动加载脚本旁的 `business_rules.example.json`,按公共字符串首次匹配,避免重复计数。该文件已有从项目源码核实的业务规则,无需额外参数。单独复制脚本也能运行:未匹配的 Key 按名称中的固定文字归组,将数字/UUID 等可变部分归一化。

项目有 `gameID:业务名:userID` 这种格式,因此匹配完整 Key 中的公共字符串,不仅取第一个冒号段。自动分组是初筛,例如数字版本也可能被合并;规则文件已将 `dayCacheV2` / `dayCacheV3` 分开。如需补业务,只要在 JSON 数组中加一行,具体规则放宽泛规则前面:

```json
{"name": "你的业务", "contains": "该业务Key的公共字符串"}
```

## 非默认连接

只有端口、DB 或鉴权方式不同时才补相应参数:

```bash
python redis_memory_audit.py 你的RedisIP --port 6380 --db 1
```

ACL 用户可加 `--username 用户名`,TLS 加 `--tls`,私有 CA 加 `--ca-cert ca.pem`。当前每次只扫描一个连接入口和一个 DB;集群需分别检查主节点,代理入口的覆盖范围按服务商说明确认。

## 统计说明

- `PTTL=-1` 表示当前无 Key 级过期时间,不能证明从未设置过,也不代表一定是泄漏;业务可能主动清理或使用 Hash 字段 TTL。
- `SCAN` 重复返回的 Key 用本地 SQLite 按原始字节去重;查询时已消失、发生错误的 Key 不按正常 0 字节数据计算。
- 使用 `PTTL → TYPE → MEMORY USAGE SAMPLES 5 → PTTL` 检查内存和 TTL 状态;扫描不是原子快照,集合内存是采样估算,在线变更会产生误差。
- CSV 不含 Value,但含 Key 名,可能包含用户编号。原始 Key 可从 `key_base64` 无损恢复。
- 退出码 `0` 为完整遍历,`130` 为 Ctrl+C,`2` 为连接/查询/导出失败;异常只保存类型,不写出密码。

本地验证:`python -m unittest -v test_redis_memory_audit.py test_update.py`。

官方语义:[PTTL](https://redis.io/docs/latest/commands/pttl/)、[SCAN](https://redis.io/docs/latest/commands/scan/)、[MEMORY USAGE](https://redis.io/docs/latest/commands/memory-usage/)。