监控、安全与性能优化
没有监控就无法判断调优是否有效;没有安全边界,性能再好也不能上线。本章先建立指标和告警,再处理 ACL/TLS,最后讨论 BigKey、HotKey 和内核参数。
1. Redis 监控分四层
| 层次 | 关注点 | 数据来源 |
|---|---|---|
| 可用性 | 能否连接、角色、Cluster/Sentinel 状态 | exporter、PING、合成探测 |
| 容量 | 内存、key 数、磁盘、连接、复制 backlog | INFO、node exporter |
| 性能 | ops/sec、延迟、慢日志、CPU、网络 | INFO、LATENCY、系统指标 |
| 正确性 | 复制、持久化、淘汰、写入错误 | INFO、日志、应用指标 |
只监控 PING 会漏掉“进程活着但不能持久化”“主从断链”“内存满后写失败”等问题。
2. 部署 redis_exporter
先创建只读监控 ACL 用户,按 exporter 实际所需命令授权,不要复用应用或管理员密码。下面以容器为例:
user monitor on >替换为随机密码 ~* +ping +info +client|getname +config|get +scan +slowlog +latency
如果 exporter 日志出现 NOPERM,根据它实际调用的命令补充单项权限,不要直接给 +@all。
services:
redis-exporter:
image: oliver006/redis_exporter:v1.67.0
environment:
REDIS_ADDR: redis://redis:6379
REDIS_USER: monitor
REDIS_PASSWORD: ${REDIS_MONITOR_PASSWORD}
ports:
- "127.0.0.1:9121:9121"
Prometheus 配置:
scrape_configs:
- job_name: redis
scrape_interval: 15s
static_configs:
- targets:
- redis-exporter-1:9121
- redis-exporter-2:9121
启动后验证:
curl -fsS http://127.0.0.1:9121/metrics | head
3. 新手先看这些指标
内存
used_memory / maxmemory:数据离上限还有多远;used_memory_rss:操作系统实际分配;mem_fragmentation_ratio:需结合 used/RSS 判断,不能只看一个比值;evicted_keys:发生淘汰,说明容量或策略已介入业务。
客户端和命令
connected_clients接近maxclients;blocked_clients持续大于 0;instantaneous_ops_per_sec与历史基线偏离;- keyspace hits/misses 用于计算缓存命中率;
- rejected connections 表示连接已被拒绝。
持久化与复制
- RDB/AOF 最近执行状态不是
ok; - AOF rewrite 长时间未完成;
master_link_status为 down;- 主从 offset 差距持续扩大;
- Cluster 状态非 ok 或 slot 缺失。
4. 告警应包含持续时间和处置入口
groups:
- name: redis
rules:
- alert: RedisMemoryNearLimit
expr: redis_memory_used_bytes / redis_memory_max_bytes > 0.85
for: 10m
labels:
severity: warning
annotations:
summary: Redis 内存持续超过上限的 85%
- alert: RedisReplicationBroken
expr: redis_connected_slaves < 1
for: 2m
labels:
severity: critical
生产规则需按 exporter 实际指标名和架构调整。告警描述应包含实例、角色、看板和运行手册链接,避免只发一句“Redis Down”。
5. 网络、ACL 与 TLS
Redis 不直接暴露公网。使用私网监听、安全组/防火墙、ACL 最小权限和 TLS。危险命令权限只给受审计的运维用户。
port 0
tls-port 6379
tls-cert-file /etc/redis/tls/redis.crt
tls-key-file /etc/redis/tls/redis.key
tls-ca-cert-file /etc/redis/tls/ca.crt
tls-auth-clients yes
redis-cli --tls \
--cacert /etc/redis/tls/ca.crt \
--cert /etc/redis/tls/client.crt \
--key /etc/redis/tls/client.key \
-h redis.internal.example.com -p 6379 --user app PING
验证证书域名、有效期和 CA 链。Sentinel、复制、Cluster bus 和 exporter 也要按实际版本与部署方式配置相应 TLS/认证,不能只加密应用入口。
6. BigKey:一个 key 拖慢整个实例
BigKey 可能是 20 MB 字符串,也可能是有百万成员的集合。影响包括网络传输长、删除慢、复制和持久化放大、迁 slot 困难。
# 在低峰或副本扫描候选
redis-cli --bigkeys
# 对候选精确确认
redis-cli TYPE candidate:key
redis-cli MEMORY USAGE candidate:key SAMPLES 10
redis-cli HLEN candidate:key
redis-cli LLEN candidate:key
redis-cli SCARD candidate:key
redis-cli ZCARD candidate:key
治理方式是拆 key、限制集合长度、压缩 value、分页读取;删除使用 UNLINK 并监控后台释放造成的 CPU 压力。
7. HotKey:少数 key 吃掉大部分 QPS
HotKey 常表现为单线程 CPU 高、某个 Cluster 主节点明显更忙、网络出入流量集中。优先从应用埋点、代理日志或客户端采样定位;redis-cli --hotkeys 依赖 LFU 且会扫描 keyspace,只在受控环境使用。
治理包括本地缓存、请求合并、拆分 key、只读副本、限流和避免同一 hash tag 集中全部流量。单纯扩容 Cluster 但热点仍在一个 slot,问题不会消失。
8. Pipeline 和连接池
Pipeline 将多条命令一次发送,减少网络往返。可以在隔离实例用 redis-benchmark 比较不同 pipeline 深度:
redis-benchmark -t set,get -n 10000 -c 20 -P 1 -q
redis-benchmark -t set,get -n 10000 -c 20 -P 16 -q
批次过大会占用输入/输出缓冲并让其他请求等待。应用应限制单批命令和响应字节数。连接池也不是越大越好:总连接数约等于应用实例数 × 每实例池大小,必须与 maxclients、fd 和故障重连风暴一起规划。
9. Linux 基础参数
# /etc/sysctl.d/99-redis.conf
vm.overcommit_memory = 1
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
sudo sysctl --system
echo never | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
echo never | sudo tee /sys/kernel/mm/transparent_hugepage/defrag
THP 往往造成延迟抖动;Swap 会产生不可预测延迟,应靠容量规划避免常态使用。NUMA、CPU 绑核、网卡和 TCP 参数必须压测,不要照搬所谓“万能调优配置”。
10. 调优闭环
- 明确现象和目标指标;
- 保存变更前基线;
- 一次只调整一个变量;
- 在预发或影子流量压测;
- 比较吞吐、P50/P95/P99、错误率和资源;
- 准备回滚并观察足够时间;
- 将最终参数写回配置管理与运行手册。