Redis 常用运维指令手册
Redis 常用运维指令手册
适用版本:Redis 6.2 / 7.0 / 7.2 / 7.4 / 8.x(当前稳定线 8.10) 约定:
#root 或 sudo,$普通用户,127.0.0.1:6379>redis-cli 提示符,<xxx>为占位符。 差异标注:正文用> **版本差异**引用块标注跨版本不一致之处。 更新时间:2026-11
目录
- 版本、许可与支持周期
- 下载地址与安装
- 服务启停与配置
- redis-cli 连接与常用命令
- 认证、ACL 与安全基线
- 键空间管理与大 key 治理
- 持久化:RDB 与 AOF
- 主从复制
- Sentinel 哨兵高可用
- Cluster 集群
- 内存管理与淘汰策略
- 日志、慢查询与监控
- 性能诊断
- 备份与恢复
- 升级与迁移
- 高频故障速查
- 危险命令与避坑清单
- 附录:巡检脚本与速查
1. 版本、许可与支持周期
1.1 版本状态(2026-11)
| 版本 | 发布时间 | 状态 | 说明 |
|---|---|---|---|
| 6.2 | 2021-02 | 安全维护至 2027-04 | 老系统仍在用 |
| 7.0 | 2022-04 | 已结束主流支持 | |
| 7.2 | 2023-08 | 安全维护至 2029-12 | 存量较多 |
| 7.4 | 2024-07 | 安全维护至 2029-12 | |
| 8.0 | 2025-05 | 安全维护至 2026-12 | 首个三许可版本 |
| 8.2 | 2025-08 | 安全维护至 2030-09 | |
| 8.4 | 2025-11 | 安全维护中 | |
| 8.6 | 2026-02 | 安全维护中 | |
| 8.8 | 2026-05 | 安全维护中 | |
| 8.10 | 2026-07-29 | 当前稳定线 | 新部署首选 |
| 8.12 | 2026-11(RC) | 预览 | 暂不入生产 |
注意:Redis 的版本节奏是"每年 1 个大版本 + 每 6 个月 1 个次版本",当前稳定线已到 8.10。不要再用"7.0 是最新版"的认知做规划。
1.2 许可证变化(重要)
| 版本 | 许可 |
|---|---|
| ≤ 7.2.x | BSD-3-Clause |
| 7.4 ~ 7.8 | RSALv2 或 SSPLv1(二选一) |
| 8.0+ | RSALv2 / SSPLv1 / AGPLv3 三选一 |
对运维的实际影响:8.0 起可以选择 AGPLv3,开源合规路径比 7.4 时期宽松;但如果你的公司政策禁止 AGPL,需要走商业授权。这一点在选型与法务评审时要提前确认。
Valkey 是 7.2.4 分支出来的 Linux 基金会项目,协议 BSD,命令与 Redis 高度兼容,可作为替代方案评估。
1.3 版本识别
redis-server --version
redis-cli --version
redis-cli INFO server | grep -E 'redis_version|redis_mode|os|arch_bits|uptime_in_days'
redis-cli INFO server | grep process_id
2. 下载地址与安装
2.1 官方入口总表
| 用途 | 地址 |
|---|---|
| 下载总入口 | https://redis.io/downloads/ |
| Redis Open Source 文档 | https://redis.io/docs/latest/ |
| APT/YUM 官方仓库 | https://packages.redis.io/ |
| GitHub 源码 | https://github.com/redis/redis |
| Docker 镜像 | https://hub.docker.com/_/redis |
| Redis Insight(图形客户端) | https://redis.io/insight/ |
| 命令参考 | https://redis.io/docs/latest/commands/ |
| 安全公告 | https://github.com/redis/redis/security/advisories |
国内镜像(同步源码与部分包):
https://mirrors.tuna.tsinghua.edu.cn/redis/
https://mirrors.aliyun.com/redis/
2.2 RHEL / Ubuntu 官方仓库
# RHEL 系
dnf install -y https://packages.redis.io/rpm/redis-repo-1-1.noarch.rpm
dnf install -y redis
systemctl enable --now redis
# Ubuntu / Debian
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" \
| sudo tee /etc/apt/sources.list.d/redis.list
sudo apt update && sudo apt install -y redis
sudo systemctl enable --now redis-server
避坑:发行版自带源里的
redis往往是很老的版本(RHEL 8 是 5.0,Ubuntu 22.04 是 6.0)。要装 8.x 必须用packages.redis.io,或自行编译。redis-server --version一定要核实。
2.3 源码编译
dnf install -y gcc make jemalloc-devel openssl-devel systemd-devel
wget https://download.redis.io/releases/redis-8.10.0.tar.gz
tar -xzf redis-8.10.0.tar.gz && cd redis-8.10.0
make -j$(nproc) BUILD_TLS=yes USE_SYSTEMD=yes
make PREFIX=/usr/local/redis install
# 目录与用户
useradd -r -s /sbin/nologin redis
mkdir -p /var/lib/redis /var/log/redis /etc/redis
chown -R redis:redis /var/lib/redis /var/log/redis
cp redis.conf /etc/redis/redis.conf
2.4 Docker 部署
docker run -d --name redis8 \
--restart unless-stopped \
-p 6379:6379 \
-v /data/redis/data:/data \
-v /data/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf \
redis:8.10 redis-server /usr/local/etc/redis/redis.conf \
--requirepass 'Str0ng#Pass2026' \
--appendonly yes
docker exec -it redis8 redis-cli -a 'Str0ng#Pass2026'
注意:命令行
--requirepass会出现在docker inspect与进程列表里。生产应写进挂载的配置文件并限制文件权限。
2.5 安装后必做
# 1) 确认版本
redis-server --version
# 2) 确认监听与保护模式
redis-cli CONFIG GET bind
redis-cli CONFIG GET protected-mode
redis-cli CONFIG GET port
# 3) 设密码(写入配置文件,不要只 CONFIG SET)
# requirepass Str0ng#Pass2026
# 4) 确认持久化
redis-cli CONFIG GET appendonly
redis-cli CONFIG GET save
# 5) 危险命令重命名或禁用
# rename-command FLUSHALL ""
# rename-command FLUSHDB ""
# rename-command KEYS ""
# rename-command CONFIG ""
3. 服务启停与配置
3.1 systemd
systemctl start redis # RHEL 系服务名 redis
systemctl stop redis
systemctl restart redis
systemctl status redis
systemctl enable redis
journalctl -u redis -n 200 --no-pager
# Ubuntu 包服务名是 redis-server
systemctl status redis-server
3.2 命令行启停
redis-server /etc/redis/redis.conf # 前台
redis-server /etc/redis/redis.conf --daemonize yes # 后台
redis-server /etc/redis/redis.conf --port 6380 # 覆盖单个参数
redis-cli -a 'pass' SHUTDOWN # 安全关闭(会持久化)
redis-cli -a 'pass' SHUTDOWN NOSAVE # 危险,不保存
redis-cli -a 'pass' SHUTDOWN SAVE
危险:
SHUTDOWN NOSAVE会跳过持久化直接退出,最近未落盘的写入全部丢失。只在数据可丢弃或磁盘损坏时用。
3.3 配置文件核心项
# /etc/redis/redis.conf 生产参考
# 网络
bind 10.0.0.11 127.0.0.1
port 6379
protected-mode yes
tcp-backlog 511
timeout 0
tcp-keepalive 300
# 通用
daemonize no
supervised systemd
pidfile /var/run/redis/redis.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
# 安全
requirepass Str0ng#Pass2026
# ACL 方式(6.0+,推荐)
# user default off
# user app on >App#2026 ~app:* +@read +@write -@dangerous
# 持久化 RDB
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis
# 持久化 AOF
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-use-rdb-preamble yes
# 内存
maxmemory 16gb
maxmemory-policy allkeys-lru
maxmemory-samples 5
# 慢查询
slowlog-log-slower-than 10000
slowlog-max-len 256
# 客户端
maxclients 10000
# 惰性删除
lazyfree-lazy-eviction yes
lazyfree-lazy-expire yes
lazyfree-lazy-server-del yes
lazyfree-lazy-user-del yes
关键:
supervised systemd必须与 systemd 单元配合,否则Type=notify会启动超时。手写 unit 时若不确定,用Type=simple+daemonize no。
3.4 CONFIG 命令
redis-cli CONFIG GET maxmemory
redis-cli CONFIG GET maxmemory-policy
redis-cli CONFIG GET save
redis-cli CONFIG GET *memory* # 支持通配符
redis-cli CONFIG SET maxmemory 16gb
redis-cli CONFIG SET maxmemory-policy allkeys-lru
redis-cli CONFIG REWRITE # 把运行时配置写回文件(需文件可写)
redis-cli CONFIG RESETSTAT # 重置统计计数
# 7.0+ 支持一次取多个参数
redis-cli CONFIG GET maxmemory maxmemory-policy appendonly
# 7.0+ 支持一次设多个
redis-cli CONFIG SET maxmemory 16gb maxmemory-policy allkeys-lru
注意:
CONFIG SET只改内存中的配置,重启失效。要持久化必须CONFIG REWRITE(要求启动时用的是配置文件且文件可写),或者直接改配置文件再重启。
4. redis-cli 连接与常用命令
4.1 连接
redis-cli -h 127.0.0.1 -p 6379
redis-cli -h 10.0.0.11 -p 6379 -a 'pass'
redis-cli -h 10.0.0.11 -p 6379 --user app --pass 'App#2026'
redis-cli -h 10.0.0.11 -p 6379 -a 'pass' --tls --cacert /etc/ssl/ca.crt
redis-cli -s /var/run/redis/redis.sock # Unix socket
redis-cli -c -h 10.0.0.11 -p 6379 # 集群模式,自动跟随 MOVED
redis-cli --no-auth-warning -a 'pass'
安全做法(避免密码进 history 与进程列表):
export REDISCLI_AUTH='Str0ng#Pass2026'
redis-cli -h 10.0.0.11
4.2 常用命令速查
| 类别 | 命令 |
|---|---|
| 连通 | PING、ECHO、SELECT 0 |
| 信息 | INFO、INFO memory、INFO replication、INFO stats、INFO keyspace |
| 配置 | CONFIG GET、CONFIG SET、CONFIG REWRITE |
| 客户端 | CLIENT LIST、CLIENT INFO、CLIENT KILL、CLIENT NO-EVICT |
| 键 | SCAN、TYPE、TTL、EXPIRE、PERSIST、DEL、UNLINK |
| 内存 | MEMORY USAGE、MEMORY STATS、MEMORY DOCTOR、OBJECT ENCODING |
| 慢查询 | SLOWLOG GET、SLOWLOG LEN、SLOWLOG RESET |
| 复制 | REPLICAOF、INFO replication、WAIT |
| 集群 | CLUSTER INFO、CLUSTER NODES、CLUSTER SLOTS、CLUSTER KEYSLOT |
| 持久化 | BGSAVE、BGREWRITEAOF、LASTSAVE、SAVE |
| 服务 | SHUTDOWN、DEBUG SLEEP(禁用)、LATENCY、ACL |
4.3 批量与脚本
# 批量执行命令
redis-cli -a 'pass' --pipe < commands.txt
# 遍历所有 key(生产禁止用 KEYS)
redis-cli -a 'pass' --scan --pattern 'app:user:*' | head -20
redis-cli -a 'pass' --scan --pattern 'app:user:*' --count 1000
# 只读副本上扫描
redis-cli -h replica -p 6379 --scan --pattern '*'
# 统计 key 数量(按模式,慎用)
redis-cli -a 'pass' --scan --pattern 'order:*' | wc -l
关键:
KEYS *是单线程阻塞操作,百万级 key 会让 Redis 卡住数秒甚至更久,生产禁用。用SCAN游标迭代,它是非阻塞的(但可能返回重复 key,需去重)。
4.4 交互式小技巧
127.0.0.1:6379> INFO memory
127.0.0.1:6379> CONFIG GET maxmemory
127.0.0.1:6379> SCAN 0 MATCH app:* COUNT 100
127.0.0.1:6379> -- 注释
127.0.0.1:6379> exit
5. 认证、ACL 与安全基线
5.1 简单密码
requirepass Str0ng#Pass2026
redis-cli -a 'Str0ng#Pass2026' PING
redis-cli CONFIG SET requirepass 'New#2026'
redis-cli CONFIG REWRITE
5.2 ACL(6.0+,推荐)
# 创建受限用户:只能操作 app: 前缀,只能读写类命令
redis-cli ACL SETUSER app on '>App#2026' '~app:*' '+@read' '+@write' '-@dangerous' '-flushall' '-keys'
# 只读用户
redis-cli ACL SETUSER ro on '>RO#2026' '~*' '+@read'
# 管理员
redis-cli ACL SETUSER admin on '>Admin#2026' '~*' '+@all'
# 禁用默认用户(强制所有连接使用 ACL 用户)
redis-cli ACL SETUSER default off
# 查看
redis-cli ACL LIST
redis-cli ACL GETUSER app
redis-cli ACL WHOAMI
redis-cli ACL CAT
redis-cli ACL CAT dangerous
# 持久化到 ACL 文件
redis-cli ACL SAVE
redis-cli ACL LOAD
# redis.conf 中的等价写法
user app on >App#2026 ~app:* +@read +@write -@dangerous
user default off
aclfile /etc/redis/users.acl
注意:使用
aclfile后就不能在配置文件里写user指令,二选一。ACL SAVE会覆盖 aclfile,改完记得ACL LOAD或重启验证。
5.3 危险命令管控
# 重命名为空字符串等于禁用
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command KEYS ""
rename-command CONFIG ""
rename-command DEBUG ""
rename-command SHUTDOWN "SHUTDOWN_ADMIN_9f3a"
注意:
rename-command在 7.0 起已被标记为弃用,官方推荐用 ACL 控制。新部署优先用 ACL,老环境继续用 rename 也仍然有效。
5.4 网络与传输安全
bind 10.0.0.11 127.0.0.1
protected-mode yes
port 6379
# TLS(8.x 支持)
tls-port 6380
tls-cert-file /etc/ssl/redis.crt
tls-key-file /etc/ssl/redis.key
tls-ca-cert-file /etc/ssl/ca.crt
tls-auth-clients yes
redis-cli --tls --cacert /etc/ssl/ca.crt -p 6380 PING
特别提醒:Redis 未授权访问是历史上最经典的安全事故之一,攻击者可通过写 crontab / SSH key 直接拿到服务器权限。任何对非可信网络可达的 Redis 必须同时满足:
bind内网、requirepass或 ACL、protected-mode yes、禁用CONFIG/MODULE/DEBUG。
6. 键空间管理与大 key 治理
6.1 键空间概况
redis-cli INFO keyspace
# db0:keys=1250000,expires=1200000,avg_ttl=86400000
redis-cli DBSIZE
redis-cli SELECT 1
redis-cli -n 1 DBSIZE
# 各库 key 数量
for i in $(seq 0 15); do echo -n "db$i: "; redis-cli -n $i DBSIZE; done
6.2 大 key 排查
# 官方工具:扫描并统计各类 key 的大小与元素数量
redis-cli -a 'pass' --bigkeys
redis-cli -a 'pass' --bigkeys -i 0.1 # 每 100 条命令休眠 0.1s,降低影响
# 内存维度(7.0+,比 --bigkeys 更贴近真实占用)
redis-cli -a 'pass' --memkeys
redis-cli -a 'pass' --memkeys --memkeys-samples 0
# 单个 key 的大小与类型
redis-cli -a 'pass' MEMORY USAGE app:user:1000
redis-cli -a 'pass' MEMORY USAGE app:user:1000 SAMPLES 0
redis-cli -a 'pass' TYPE app:user:1000
redis-cli -a 'pass' OBJECT ENCODING app:user:1000
redis-cli -a 'pass' LLEN app:queue
redis-cli -a 'pass' HLEN app:hash
redis-cli -a 'pass' ZCARD app:rank
redis-cli -a 'pass' SCARD app:set
redis-cli -a 'pass' STRLEN app:bigstring
大 key 的判定参考:
| 类型 | 阈值 |
|---|---|
| String | > 10 KB |
| Hash / List / Set / ZSet | 元素数 > 5000,或总内存 > 1 MB |
| 单实例 | 任意 key > 100 MB 都算严重 |
6.3 大 key 的处理
# 1) 拆分:按业务维度打散
# app:user:1000 -> app:user:1000:profile / app:user:1000:orders
# 2) 删除:用 UNLINK(异步释放,不阻塞主线程)而不是 DEL
redis-cli UNLINK app:big:hash
# 3) 遍历删除大集合(避免一次性 DEL 阻塞)
redis-cli --scan --pattern 'app:big:list:*' | while read k; do
redis-cli UNLINK "$k"
done
# 4) Hash 分批删除字段(HSCAN + HDEL)
关键:
DEL大 key 是同步释放内存,百万元素的 Hash 可能阻塞主线程数百毫秒。一律用UNLINK,它把释放工作交给后台线程(需lazyfree-lazy-user-del yes配合,7.0+ 默认)。
6.4 过期与内存碎片
redis-cli TTL app:session:abc
redis-cli PTTL app:session:abc
redis-cli PERSIST app:session:abc
redis-cli EXPIRE app:session:abc 3600
redis-cli OBJECT IDLETIME app:session:abc
# 碎片率
redis-cli INFO memory | grep -E 'used_memory_human|used_memory_rss_human|mem_fragmentation_ratio'
mem_fragmentation_ratio |
含义 |
|---|---|
| 1.0 ~ 1.5 | 正常 |
| > 1.5 | 碎片较多,可考虑 activedefrag yes |
| < 1 | 部分内存被交换到 swap,性能会崩,必须查 swap |
activedefrag yes
active-defrag-ignore-bytes 100mb
active-defrag-threshold-lower 10
active-defrag-threshold-upper 100
7. 持久化:RDB 与 AOF
7.1 两种方式对比
| 维度 | RDB | AOF |
|---|---|---|
| 内容 | 内存快照(二进制) | 写命令追加日志 |
| 恢复速度 | 快 | 慢(需重放) |
| 数据安全 | 可能丢最后一次快照后的数据 | everysec 最多丢 1 秒 |
| 文件大小 | 小 | 大(需重写压缩) |
| 对性能影响 | fork 时有尖刺 | 持续写盘,always 影响大 |
生产推荐:两者都开。RDB 用于快速恢复与备份,AOF 用于减少数据丢失。
7.2 RDB 操作
redis-cli BGSAVE # 后台保存,不阻塞
redis-cli LASTSAVE # 上次成功保存的时间戳
redis-cli SAVE # 前台保存,阻塞!生产禁用
redis-cli INFO persistence | grep -E 'rdb_last_bgsave_status|rdb_changes_since_last_save|rdb_bgsave_in_progress'
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes # 保存失败时拒写,避免"以为有备份其实没有"
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis
注意:
stop-writes-on-bgsave-error yes是双刃剑。磁盘满导致 BGSAVE 失败时会拒写,业务报错,但这比"静默丢数据"好。曾经因为这个配置引发过大规模写入失败,运维要提前监控rdb_last_bgsave_status。
7.3 AOF 操作
redis-cli BGREWRITEAOF # 后台重写,压缩 AOF
redis-cli INFO persistence | grep -E 'aof_enabled|aof_rewrite_in_progress|aof_last_bgrewrite_status|aof_current_size|aof_base_size'
appendonly yes
appendfilename "appendonly.aof"
appenddirname "appendonlydir" # 7.0+ AOF 目录(多文件清单)
appendfsync everysec # always / everysec / no
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-use-rdb-preamble yes # 混合持久化,重启恢复更快
版本差异:Redis 7.0 起 AOF 改为多文件结构(
appendonlydir/下含 base、incr 与 manifest),不再是单个appendonly.aof。备份与拷贝时要把整个目录一起处理,只拷单文件会丢数据。7.0 之前是单文件。
7.4 持久化故障处理
# AOF 损坏时(启动报 "Bad file format reading the append only file")
redis-check-aof --fix /var/lib/redis/appendonlydir/appendonly.aof.manifest
# 7.0 之前
redis-check-aof --fix /var/lib/redis/appendonly.aof
# RDB 损坏校验
redis-check-rdb /var/lib/redis/dump.rdb
# fork 失败("Can't save in background: fork: Cannot allocate memory")
cat /proc/sys/vm/overcommit_memory # 应为 1
sysctl -w vm.overcommit_memory=1
echo 'vm.overcommit_memory = 1' >> /etc/sysctl.conf
根因:BGSAVE 需要 fork,fork 依赖 overcommit。
vm.overcommit_memory=0时,即使物理内存够,也可能 fork 失败。这是 Redis 最经典的环境配置问题,安装后必须设置。
7.5 持久化监控项
| 指标 | 健康值 |
|---|---|
rdb_last_bgsave_status |
ok |
aof_last_bgrewrite_status |
ok |
rdb_changes_since_last_save |
不应无限增长 |
latest_fork_usec |
通常 < 100ms,过大说明内存大或 CPU 繁忙 |
aof_current_size 与 aof_base_size |
比值接近 1 说明重写正常 |
8. 主从复制
8.1 配置
从节点:
replicaof 10.0.0.11 6379
masterauth Str0ng#Pass2026
replica-read-only yes
replica-serve-stale-data yes
replica-priority 100
min-replicas-to-write 1
min-replicas-max-lag 10
# 运行时切换主节点(会触发全量同步)
redis-cli -h 10.0.0.12 REPLICAOF 10.0.0.11 6379
redis-cli -h 10.0.0.12 REPLICAOF NO ONE # 提升为主
8.2 状态查看
redis-cli INFO replication
# role:master
# connected_slaves:2
# slave0:ip=10.0.0.12,port=6379,state=online,offset=1234567,lag=0
# master_replid:...
# master_repl_offset:1234567
redis-cli -h 10.0.0.12 INFO replication
# role:slave
# master_link_status:up
# master_last_io_seconds_ago:0
# master_sync_in_progress:0
# slave_repl_offset:1234567
# slave_read_only:1
关键判读:
| 字段 | 期望 |
|---|---|
master_link_status |
up(down 说明断链) |
master_sync_in_progress |
0(1 表示正在全量同步) |
master_last_io_seconds_ago |
< 10 |
slave_repl_offset 与主库 master_repl_offset |
差值小 |
# 延迟(字节)
redis-cli -h 10.0.0.11 INFO replication | grep master_repl_offset
redis-cli -h 10.0.0.12 INFO replication | grep slave_repl_offset
8.3 复制原理与优化
第一次连接 → 全量同步(RDB + 缓冲区命令)→ 增量同步(repl_backlog)
断线重连 → 若 offset 在 repl_backlog 范围内则部分重同步,否则全量
# 加大复制缓冲区,减少全量同步概率
repl-backlog-size 256mb
repl-backlog-ttl 3600
repl-diskless-sync yes
repl-diskless-sync-delay 5
repl-diskless-load disabled
建议:
repl-backlog-size默认 1MB,在网络抖动或从库短暂重启时极易触发全量同步(大实例全量同步会打满带宽并造成主库 fork 尖刺)。生产建议 64~256MB。
8.4 写安全
min-replicas-to-write 1
min-replicas-max-lag 10
含义:至少有 1 个从库延迟 ≤ 10 秒,主库才接受写入。可显著降低主库宕机时的数据丢失,代价是从库全挂时主库变只读。
# 同步复制确认(应用侧保证)
redis-cli SET key value
redis-cli WAIT 1 1000 # 等 1 个副本确认,最多 1000ms
9. Sentinel 哨兵高可用
9.1 架构
应用 → Sentinel 集群(3 或 5 个)→ 监控 → Master / Slave
Sentinel 负责:监控、自动故障转移、通知客户端新主库地址。
9.2 配置
# /etc/redis/sentinel.conf
port 26379
daemonize no
supervised systemd
logfile /var/log/redis/sentinel.log
dir /var/lib/redis/sentinel
# 监控主库:quorum=2 表示 2 个 Sentinel 认为客观下线才判定
sentinel monitor mymaster 10.0.0.11 6379 2
sentinel auth-pass mymaster Str0ng#Pass2026
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
# 安全(6.2+)
requirepass Sentinel#2026
sentinel sentinel-user default
sentinel sentinel-pass Sentinel#2026
redis-server /etc/redis/sentinel.conf --sentinel
systemctl enable --now redis-sentinel
注意:Sentinel 至少部署 3 个且为奇数,分布在不同物理机/可用区。单机跑 3 个 Sentinel 只是自欺欺人——机器一挂全挂。
9.3 运维命令
redis-cli -p 26379 SENTINEL masters
redis-cli -p 26379 SENTINEL master mymaster
redis-cli -p 26379 SENTINEL slaves mymaster
redis-cli -p 26379 SENTINEL sentinels mymaster
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
redis-cli -p 26379 SENTINEL failover mymaster # 手动触发切换
redis-cli -p 26379 SENTINEL ckquorum mymaster # 检查 quorum 是否够
redis-cli -p 26379 SENTINEL reset mymaster # 重置状态(谨慎)
redis-cli -p 26379 SENTINEL flushconfig # 重写配置文件
9.4 故障转移流程
- Sentinel 主观下线(
sdown):单个 Sentinel 超过down-after-milliseconds没收到 PING 回复。 - 客观下线(
odown):达到 quorum 数量的 Sentinel 都认为下线。 - 选举 leader Sentinel(Raft 类似机制)。
- leader 选新主:按
replica-priority→ 复制 offset → runid 排序。 - 其他从库
REPLICAOF新主,旧主恢复后降为从库。 - 通过 pub/sub 通知客户端。
# 观察切换日志
tail -f /var/log/redis/sentinel.log | grep -E '\+sdown|\+odown|\+switch-master|\+failover-end'
应用侧必须支持 Sentinel:客户端要订阅
+switch-master频道,或通过 Sentinel 查询当前主库地址。硬编码 IP 的应用在切换后必然连不上。
9.5 常见问题
| 现象 | 原因 |
|---|---|
| 频繁误切换 | down-after-milliseconds 太小、网络抖动 |
| 切换后应用连不上 | 客户端未接入 Sentinel,或 DNS 缓存 |
| 无法切换 | quorum 不足(Sentinel 数量不够或全在一台机) |
| 脑裂 | 网络分区,旧主仍在写入;用 min-replicas-to-write 缓解 |
10. Cluster 集群
10.1 架构与限制
- 数据按 16384 个 slot 分片,每个主节点负责一部分。
- 至少 3 主 3 从(6 节点)。
- 集群模式只支持 db0,不支持多库。
- 多 key 操作要求 key 在同一 slot:用 hash tag
{user1000}:profile、{user1000}:orders。 - 不支持跨 slot 的事务与 Lua(除非用 hash tag)。
10.2 配置
# 每个节点
port 6379
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000
cluster-announce-ip 10.0.0.11
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
protected-mode no
masterauth Str0ng#Pass2026
requirepass Str0ng#Pass2026
注意:集群模式下
protected-mode no常被要求,但这不等于可以不要密码。必须同时设requirepass与masterauth,否则任何能连上 16379 的人都能改集群拓扑。
10.3 创建与检查
# 创建 3 主 3 从
redis-cli --cluster create \
10.0.0.11:6379 10.0.0.12:6379 10.0.0.13:6379 \
10.0.0.14:6379 10.0.0.15:6379 10.0.0.16:6379 \
--cluster-replicas 1 -a 'Str0ng#Pass2026'
# 检查集群健康
redis-cli --cluster check 10.0.0.11:6379 -a 'pass'
redis-cli --cluster info 10.0.0.11:6379 -a 'pass'
# 集群状态
redis-cli -c -h 10.0.0.11 CLUSTER INFO
redis-cli -c -h 10.0.0.11 CLUSTER NODES
redis-cli -c -h 10.0.0.11 CLUSTER SLOTS
redis-cli CLUSTER KEYSLOT 'app:user:1000'
CLUSTER INFO 关键字段:
| 字段 | 期望 |
|---|---|
cluster_state |
ok |
cluster_slots_assigned |
16384 |
cluster_known_nodes |
节点总数 |
cluster_size |
主节点数 |
cluster_slots_ok |
16384 |
10.4 扩缩容
# 加节点(先起空实例,再 add-node)
redis-cli --cluster add-node 10.0.0.17:6379 10.0.0.11:6379 -a 'pass'
# 加为从节点(指定主节点 ID)
redis-cli --cluster add-node 10.0.0.18:6379 10.0.0.11:6379 \
--cluster-slave --cluster-master-id <master-node-id> -a 'pass'
# 迁移 slot(交互式,会问迁移数量与源/目标)
redis-cli --cluster reshard 10.0.0.11:6379 -a 'pass'
# 非交互
redis-cli --cluster reshard 10.0.0.11:6379 \
--cluster-from <src-id> --cluster-to <dst-id> \
--cluster-slots 1000 --cluster-yes -a 'pass'
# 均衡
redis-cli --cluster rebalance 10.0.0.11:6379 --cluster-use-empty-masters -a 'pass'
# 删除节点(先迁走 slot)
redis-cli --cluster del-node 10.0.0.11:6379 <node-id> -a 'pass'
10.5 故障转移
# 手动让某主节点降级(触发从节点接管)
redis-cli -h 10.0.0.11 -p 6379 CLUSTER FAILOVER
# 强制(主节点不可达时,可能丢数据)
redis-cli -h 10.0.0.12 -p 6379 CLUSTER FAILOVER FORCE
# 忽略数据一致性(最危险)
redis-cli -h 10.0.0.12 -p 6379 CLUSTER FAILOVER TAKEOVER
危险:
TAKEOVER不做任何一致性校验,可能造成数据分叉且无法自动修复。只在灾难恢复、明确接受数据丢失时使用,事后必须人工比对与修复。
10.6 集群常见坑
| 问题 | 说明 |
|---|---|
CROSSSLOT Keys in request don't hash to the same slot |
多 key 不在同槽,用 hash tag |
MOVED 重定向 |
客户端需支持集群模式(redis-cli -c) |
CLUSTERDOWN The cluster is down |
slot 覆盖不全或多数主节点失联 |
| 扩容后数据不均 | 需 reshard 或 rebalance |
| 从节点不接管 | cluster-node-timeout 太大,或从节点数据太旧被拒绝 |
11. 内存管理与淘汰策略
11.1 内存查看
redis-cli INFO memory
# used_memory: 17179869184
# used_memory_human: 16.00G
# used_memory_rss: 18253611008
# maxmemory: 17179869184
# maxmemory_policy: allkeys-lru
# mem_fragmentation_ratio: 1.06
# mem_allocator: jemalloc-5.3.0
redis-cli MEMORY STATS
redis-cli MEMORY DOCTOR
redis-cli MEMORY USAGE app:user:1000
11.2 淘汰策略
| 策略 | 行为 | 适用 |
|---|---|---|
noeviction |
内存满后写入报错(读仍可) | 数据库型,不能丢数据 |
allkeys-lru |
所有 key 按 LRU 淘汰 | 纯缓存首选 |
allkeys-lfu |
按访问频率淘汰 | 热点明显的缓存 |
allkeys-random |
随机淘汰 | 极少用 |
volatile-lru |
只淘汰设了 TTL 的 key | 缓存与持久数据混存 |
volatile-lfu |
同上,按频率 | |
volatile-ttl |
优先淘汰快过期的 | 有明确 TTL 策略 |
volatile-random |
随机淘汰带 TTL 的 | 极少用 |
redis-cli CONFIG SET maxmemory 16gb
redis-cli CONFIG SET maxmemory-policy allkeys-lru
redis-cli CONFIG REWRITE
重要:
noeviction在内存满时写入会报OOM command not allowed when used memory > 'maxmemory',读请求仍然正常。如果业务把这个错当成"Redis 挂了",会引发误判。监控必须区分 OOM 错误与连接失败。
11.3 内存优化手段
- 设置合理 TTL:没有 TTL 的缓存 key 是内存泄漏的头号来源。
- 控制大 key:拆分或改用更紧凑的结构(如用 Hash 存小对象,利用 ziplist/listpack 编码)。
- 开启压缩编码阈值:
hash-max-listpack-entries、zset-max-listpack-entries等。 - 避免重复存储:key 前缀不要过长(百万 key × 20 字节前缀 = 20MB 开销)。
- 使用
UNLINK异步删除。 - 定期
MEMORY DOCTOR体检。
# 编码检查(listpack/ziplist 比 hashtable/skiplist 省内存)
redis-cli OBJECT ENCODING app:user:1000
redis-cli CONFIG GET hash-max-listpack-entries
redis-cli CONFIG GET zset-max-listpack-entries
版本差异:7.0 起
ziplist编码全部替换为listpack,对应参数名从*-ziplist-*改为*-listpack-*。老配置里的hash-max-ziplist-entries在新版本会被忽略(有兼容别名但行为不同),迁移时要改。
11.4 内存告警线
| 指标 | 阈值 |
|---|---|
used_memory / maxmemory |
> 80% 关注,> 90% 告警 |
mem_fragmentation_ratio |
> 1.5 考虑 activedefrag |
evicted_keys 增长速率 |
突增说明内存不足 |
keyspace_hits / (hits+misses) |
< 90% 说明缓存效果差,或 key 被过早淘汰 |
12. 日志、慢查询与监控
12.1 日志
loglevel notice # debug / verbose / notice / warning
logfile /var/log/redis/redis.log
syslog-enabled no
tail -f /var/log/redis/redis.log
grep -i -E 'error|warning|oom|fork' /var/log/redis/redis.log | tail -30
常见日志关键字:
| 关键字 | 含义 |
|---|---|
OOM command not allowed |
内存满,noeviction 拒写 |
Can't save in background: fork |
fork 失败,查 overcommit_memory |
Background saving error |
RDB 失败,查磁盘与权限 |
MASTER <-> REPLICA sync started |
正在全量同步 |
Connection with master lost |
复制断链 |
Possible SECURITY ATTACK |
协议异常,可能被扫描 |
12.2 慢查询
redis-cli CONFIG SET slowlog-log-slower-than 10000 # 微秒,10000 = 10ms
redis-cli CONFIG SET slowlog-max-len 256
redis-cli SLOWLOG GET 10
redis-cli SLOWLOG LEN
redis-cli SLOWLOG RESET
SLOWLOG GET 输出字段:id、时间戳、耗时(微秒)、命令数组、客户端地址、客户端名。
注意:
slowlog-log-slower-than单位是微秒,不是毫秒。设成 10 会记录几乎所有命令,日志暴涨且本身影响性能。
常见慢命令:KEYS、HGETALL(大 Hash)、SMEMBERS(大 Set)、ZRANGE(大范围)、DEL(大 key)、FLUSHDB、SORT、复杂 Lua 脚本。
12.3 延迟监控
# 持续采样延迟
redis-cli --latency
redis-cli --latency-history -i 5
redis-cli --intrinsic-latency 100
# 延迟事件(需配置 latency-monitor-threshold)
redis-cli CONFIG SET latency-monitor-threshold 100
redis-cli LATENCY LATEST
redis-cli LATENCY HISTORY command
redis-cli LATENCY RESET
redis-cli LATENCY DOCTOR
经验值:Redis 单实例正常延迟 P99 应在 1ms 内。出现 10ms+ 尖刺要查:大 key 删除、fork(BGSAVE/AOF rewrite)、swap、CPU 争抢、慢命令。
12.4 客户端管理
redis-cli CLIENT LIST
redis-cli CLIENT LIST TYPE normal
redis-cli CLIENT INFO
redis-cli CLIENT GETNAME
redis-cli CLIENT SETNAME app-worker
redis-cli CLIENT KILL ID 12345
redis-cli CLIENT KILL ADDR 10.0.0.20:54321
redis-cli CLIENT KILL TYPE normal SKIPME yes
redis-cli CLIENT NO-EVICT on # 7.0+ 保护关键连接不被内存淘汰断开
redis-cli CLIENT PAUSE 1000 WRITE # 暂停写入 1 秒(切换时用)
# 按 IP 统计连接数(找连接泄漏)
redis-cli CLIENT LIST | awk '{print $2}' | cut -d= -f2 | cut -d: -f1 | sort | uniq -c | sort -rn | head
12.5 监控指标清单
| 指标 | 来源 | 告警建议 |
|---|---|---|
used_memory / maxmemory |
INFO memory | > 85% |
evicted_keys 速率 |
INFO stats | 突增 |
rejected_connections |
INFO stats | > 0 |
connected_clients |
INFO clients | > 80% maxclients |
blocked_clients |
INFO clients | 突增 |
master_link_status |
INFO replication | down |
master_sync_in_progress |
INFO replication | 长时间为 1 |
rdb_last_bgsave_status |
INFO persistence | err |
aof_last_bgrewrite_status |
INFO persistence | err |
latest_fork_usec |
INFO stats | > 500000 |
keyspace_hit_ratio |
计算 | < 90% |
cluster_state |
CLUSTER INFO | != ok |
# 一行取关键指标
redis-cli INFO | grep -E 'used_memory_human|connected_clients|blocked_clients|evicted_keys|rejected_connections|instantaneous_ops_per_sec|keyspace_hits|keyspace_misses'
13. 性能诊断
13.1 实时状态
redis-cli --stat # 每秒刷新:keys、mem、clients、blocked、requests、connections
redis-cli INFO stats | grep -E 'instantaneous_ops_per_sec|total_commands_processed|total_connections_received|expired_keys|evicted_keys|keyspace_hits|keyspace_misses'
# 命中率
redis-cli INFO stats | awk -F: '/keyspace_hits/{h=$2} /keyspace_misses/{m=$2} END{printf "hit ratio: %.2f%%\n", h/(h+m)*100}'
13.2 命令级诊断
# 7.0+ 命令统计(比 MONITOR 安全得多)
redis-cli INFO commandstats | sort -t= -k3 -rn | head -20
# 重置
redis-cli CONFIG RESETSTAT
# 实时命令流(危险:严重降低性能,仅短时排障)
redis-cli MONITOR
# 排障时限定在从库执行,或最多开几秒
timeout 5 redis-cli MONITOR | head -200
危险:
MONITOR会把每条命令都回传,QPS 上万时会把 Redis 与客户端都拖垮。生产排障优先用INFO commandstats、SLOWLOG、LATENCY。
13.3 单机性能上限判断
redis-cli --intrinsic-latency 10
# 输出系统本身的基础延迟。若 > 1ms,说明宿主环境有问题(虚拟化、超卖、CPU 降频)
redis-benchmark -h 127.0.0.1 -p 6379 -a 'pass' -q -n 100000 -c 50 -t set,get
redis-benchmark -h 127.0.0.1 -p 6379 -a 'pass' -q -n 100000 -c 50 -P 16 -t set,get # pipeline
| 场景 | 参考 QPS(单实例,普通云主机) |
|---|---|
| 简单 GET/SET,无 pipeline | 8~12 万 |
| Pipeline=16 | 50~100 万 |
| 集群 3 主 | 约 3 倍单主 |
13.4 常见性能问题定位
| 现象 | 排查方向 |
|---|---|
| CPU 100% 单核 | 慢命令、大 key、Lua 长脚本、MONITOR |
| 延迟尖刺周期性出现 | BGSAVE/AOF rewrite fork、定时任务、swap |
| QPS 上不去但 CPU 不高 | 网络 RTT、客户端串行、连接数不足 |
| 内存持续增长 | 无 TTL 的 key、大 key、客户端缓冲区 |
blocked_clients 高 |
用了 BLPOP/BRPOP 等等待命令,属于正常;突增要查业务 |
# 客户端缓冲区过大(输出缓冲区堆积会吃内存)
redis-cli CLIENT LIST | awk '{for(i=1;i<=NF;i++) if($i ~ /^obl=/ || $i ~ /^omem=/) printf "%s ", $i; print ""}' | sort -t= -k3 -rn | head
14. 备份与恢复
14.1 备份方式
| 方式 | 一致性 | 影响 | 适用 |
|---|---|---|---|
| 拷贝 RDB 文件 | 到上次快照 | 无 | 常规备份 |
BGSAVE + 拷贝 |
是 | fork 尖刺 | 推荐 |
| AOF 目录整体拷贝 | 接近实时 | 无 | 要求低丢失 |
redis-cli --rdb |
是 | 触发一次全量 | 远程备份 |
# 1) 触发快照
redis-cli -a 'pass' BGSAVE
# 等待完成
while [ "$(redis-cli -a 'pass' INFO persistence | grep rdb_bgsave_in_progress | tr -d '\r' | cut -d: -f2)" != "0" ]; do sleep 1; done
# 2) 拷贝(RDB 路径以 CONFIG GET dir 为准)
RDB_DIR=$(redis-cli -a 'pass' CONFIG GET dir | tail -1)
cp "$RDB_DIR/dump.rdb" /backup/redis/dump_$(date +%F).rdb
# 3) 校验
redis-check-rdb /backup/redis/dump_$(date +%F).rdb
# 远程拉取(不影响主库磁盘)
redis-cli -h 10.0.0.11 -p 6379 -a 'pass' --rdb /backup/redis/remote.rdb
# AOF 目录整体备份(7.0+ 多文件结构)
cp -a /var/lib/redis/appendonlydir /backup/redis/aof_$(date +%F)
重要:7.0+ 只拷
appendonly.aof是错的,必须拷整个appendonlydir/(含 manifest 与 base/incr 文件),否则恢复会失败或丢数据。
14.2 恢复
# RDB 恢复
systemctl stop redis
cp /backup/redis/dump_2026-11-05.rdb /var/lib/redis/dump.rdb
chown redis:redis /var/lib/redis/dump.rdb
systemctl start redis
# AOF 恢复
systemctl stop redis
rm -rf /var/lib/redis/appendonlydir
cp -a /backup/redis/aof_2026-11-05 /var/lib/redis/appendonlydir
chown -R redis:redis /var/lib/redis/appendonlydir
systemctl start redis
# 恢复后校验
redis-cli DBSIZE
redis-cli INFO keyspace
redis-cli --scan --pattern '*' | wc -l
14.3 从备份恢复到新实例
redis-server --port 6380 --dir /backup/redis --dbfilename dump_2026-11-05.rdb
redis-cli -p 6380 DBSIZE
# 校验无误后再切换
14.4 备份策略
| 场景 | 策略 |
|---|---|
| 纯缓存(可回源) | 可不备份,或每日 RDB |
| 有状态数据(session、队列) | 每日 RDB + AOF 实时 |
| 关键数据(排行榜、计数器) | RDB + AOF + 异地备份,定期恢复演练 |
原则:备份文件必须异机存放,且每季度做一次真实恢复验证。Redis 的备份常被忽视,因为"它只是缓存"——直到缓存里存了不可重建的数据。
15. 升级与迁移
15.1 升级路径
6.2 → 7.0 → 7.2 → 7.4 → 8.x
规则:
- 不能跨大版本直跳(6.2 不能直接升 8.10)。
- 建议逐个小版本升,且每次升级后观察 24 小时。
- 升级前必须备份 RDB + AOF。
- 主从架构可滚动升级:先升从库 → 主从切换 → 再升原主库,业务基本无感。
15.2 滚动升级(主从)
# 1) 升级一个从库
systemctl stop redis
# 替换二进制或安装新版本包
systemctl start redis
redis-cli INFO server | grep redis_version
redis-cli INFO replication | grep master_link_status # 等它变 up
# 2) 主从切换,让已升级的从库成为主
redis-cli -h old-master REPLICAOF NO ONE # 或者用 Sentinel 的 failover
redis-cli -h new-master REPLICAOF NO ONE
# 3) 把其他节点指向新主
redis-cli -h other REPLICAOF new-master 6379
# 4) 升级原主库,再作为从库加入
注意:Redis 主从复制不支持跨大版本反向同步(新从库可以同步老主库,但老从库不能同步新主库的某些新特性数据)。滚动升级时务必先升从库、再切主,顺序不能反。
15.3 数据迁移
| 方式 | 适用 | 说明 |
|---|---|---|
| RDB 文件拷贝 | 同版本、可停机 | 最快 |
| 主从复制 | 跨实例、低停机 | 目标设为源 REPLICAOF,同步完切主 |
redis-cli --pipe |
小数据量 | 生成命令流重放 |
redis-shake / redis-migrate-tool |
大集群、跨版本 | 第三方工具,支持在线迁移 |
# 主从方式迁移(推荐)
# 1) 目标实例起空库
# 2) 目标执行
redis-cli -h target REPLICAOF source 6379
# 3) 等 INFO replication 的 master_link_status=up 且 offset 追上
# 4) 切换应用连接,目标执行
redis-cli -h target REPLICAOF NO ONE
15.4 升级检查清单
# 1) 版本与配置
redis-cli INFO server | grep redis_version
redis-cli CONFIG GET appendonly
redis-cli CONFIG GET maxmemory-policy
# 2) 备份
redis-cli BGSAVE && cp /var/lib/redis/dump.rdb /backup/pre_upgrade.rdb
# 3) 检查已弃用配置(升级后可能不识别)
grep -nE 'ziplist|rename-command' /etc/redis/redis.conf
# 4) 集群/哨兵状态
redis-cli CLUSTER INFO
redis-cli -p 26379 SENTINEL masters
# 5) 客户端兼容性:确认驱动支持新版本的 RESP3 / 新命令
版本差异:7.0 起
ziplist相关配置改为listpack(旧名保留兼容但语义变化);rename-command被标记弃用;AOF 变为多文件结构。从 6.x 升 7.x/8.x 时这三处最容易出问题。
16. 高频故障速查
16.1 连不上
| 现象 | 排查 |
|---|---|
Connection refused |
服务未起 / bind 不含该地址 / 防火墙 |
NOAUTH Authentication required |
未带密码 |
WRONGPASS invalid username-password pair |
密码或 ACL 用户错 |
NOPERM this user has no permissions to run the ... command |
ACL 权限不足 |
DENIED Redis is running in protected mode |
未设密码且非本机访问 |
| 连接超时 | maxclients 满 / 网络 / 被 CLIENT PAUSE |
redis-cli -h 10.0.0.11 PING
ss -lntp | grep 6379
redis-cli INFO clients | grep connected_clients
redis-cli INFO stats | grep rejected_connections
redis-cli CONFIG GET maxclients
16.2 OOM(内存满)
redis-cli INFO memory | grep -E 'used_memory_human|maxmemory_human|maxmemory_policy'
redis-cli INFO stats | grep evicted_keys
| 情况 | 处理 |
|---|---|
maxmemory-policy=noeviction 且内存满 |
扩容、清理无用 key、或改策略(业务允许丢失时) |
| 有淘汰但仍在涨 | 新写入速率 > 淘汰速率,扩内存 |
| 内存没到上限却报 OOM | 检查 maxmemory 是否被设得过小,或碎片导致 RSS 高 |
# 找大 key
redis-cli --bigkeys -i 0.1
redis-cli --memkeys
16.3 响应变慢
redis-cli --latency
redis-cli SLOWLOG GET 10
redis-cli LATENCY LATEST
redis-cli INFO stats | grep -E 'instantaneous_ops_per_sec|expired_keys'
top -p $(redis-cli INFO server | grep process_id | cut -d: -f2 | tr -d '\r')
排查顺序:慢命令 → 大 key → fork(latest_fork_usec)→ swap(free -h、vmstat)→ CPU 争抢 → 网络。
# 是否用了 swap(致命)
grep -i swap /proc/$(redis-cli INFO server | grep process_id | cut -d: -f2 | tr -d '\r')/status
16.4 主从断开
redis-cli -h replica INFO replication | grep -E 'master_link_status|master_last_io_seconds_ago|master_sync_in_progress'
tail -50 /var/log/redis/redis.log | grep -i -E 'sync|master|replica'
| 原因 | 处理 |
|---|---|
| 网络中断 | 恢复链路,repl-backlog 够大则可部分重同步 |
| 主库密码变更 | 更新从库 masterauth |
| 从库磁盘满 | 清理空间后会自动重试 |
| 全量同步反复触发 | 加大 repl-backlog-size |
主库 maxclients 满 |
预留连接给复制 |
16.5 集群异常
redis-cli --cluster check 10.0.0.11:6379 -a 'pass'
redis-cli -c CLUSTER INFO
redis-cli -c CLUSTER NODES
| 现象 | 处理 |
|---|---|
cluster_state:fail |
检查 slot 是否全覆盖、主节点是否多数存活 |
CLUSTERDOWN |
恢复失联主节点,或用 CLUSTER FAILOVER TAKEOVER(危险) |
节点被标记 fail 但实际存活 |
检查 cluster-node-timeout、网络、系统时间 |
| slot 迁移卡住 | CLUSTER SETSLOT ... STABLE,排查 migrating/importing 状态 |
大量 MOVED |
客户端未用集群模式 |
16.6 fork 失败 / 持久化失败
tail -50 /var/log/redis/redis.log | grep -i -E 'fork|bgsave|aof'
cat /proc/sys/vm/overcommit_memory
redis-cli INFO persistence | grep -E 'rdb_last_bgsave_status|aof_last_bgrewrite_status'
# 修复
sysctl -w vm.overcommit_memory=1
echo 'vm.overcommit_memory = 1' >> /etc/sysctl.conf
# 检查磁盘与目录权限
df -h
ls -ld /var/lib/redis
16.7 连接数打满
redis-cli INFO clients
redis-cli CONFIG GET maxclients
redis-cli CLIENT LIST | wc -l
redis-cli CLIENT LIST | awk '{print $2}' | cut -d= -f2 | cut -d: -f1 | sort | uniq -c | sort -rn | head
处理:提高 maxclients(同时调 ulimit -n)、查应用连接池是否泄漏、清理空闲连接。
# 系统层限制
ulimit -n
cat /proc/$(redis-cli INFO server | grep process_id | cut -d: -f2 | tr -d '\r')/limits | grep 'open files'
17. 危险命令与避坑清单
| 命令 | 后果 | 防护 |
|---|---|---|
KEYS * |
单线程阻塞,百万 key 卡数秒 | 用 SCAN |
FLUSHALL / FLUSHDB |
数据全清,不可恢复 | rename-command 禁用 + ACL |
DEL 大 key |
同步释放内存,阻塞主线程 | 用 UNLINK |
SHUTDOWN NOSAVE |
跳过持久化,丢数据 | 只 SHUTDOWN |
CONFIG SET 后不 REWRITE |
重启后配置丢失 | 改配置文件或 CONFIG REWRITE |
MONITOR |
严重降性能 | 仅短时、在从库用 |
DEBUG SEGFAULT / DEBUG SLEEP |
崩溃/阻塞 | 禁用 DEBUG |
SAVE |
前台阻塞直到完成 | 用 BGSAVE |
CLUSTER FAILOVER TAKEOVER |
数据分叉,无法自动修复 | 最后手段,需人工修复 |
REPLICAOF NO ONE 误用 |
从库脱离,形成双主 | 确认目标节点 |
maxmemory=0 且内存无上限 |
吃光内存被 OOM Killer 杀 | 必设 maxmemory |
只拷 appendonly.aof(7.0+) |
恢复丢数据 | 拷整个 appendonlydir/ |
无密码 + bind 0.0.0.0 |
被入侵、写入 SSH key / crontab | 密码 + ACL + bind 内网 |
vm.overcommit_memory=0 |
BGSAVE fork 失败 | 设为 1 |
17.1 变更前检查清单
# 1) 确认实例与角色
redis-cli INFO server | grep -E 'redis_version|redis_mode|process_id'
redis-cli INFO replication | grep -E '^role|connected_slaves'
redis-cli -c CLUSTER INFO 2>/dev/null | grep cluster_state
# 2) 备份
redis-cli BGSAVE
cp /var/lib/redis/dump.rdb /backup/pre_change.rdb
# 3) 看内存与大 key
redis-cli INFO memory | grep -E 'used_memory_human|maxmemory_human'
redis-cli --bigkeys -i 0.1
# 4) 看慢查询与延迟
redis-cli SLOWLOG GET 5
redis-cli --latency -i 1
# 5) 变更(批量操作分批、用 SCAN)
18. 附录:巡检脚本与速查
18.1 巡检脚本
#!/usr/bin/env bash
# 用法:REDISCLI_AUTH=pass ./redis_health.sh [host] [port]
HOST=${1:-127.0.0.1}
PORT=${2:-6379}
R="redis-cli -h $HOST -p $PORT --no-auth-warning"
echo "========== 版本与运行 =========="
$R INFO server | grep -E 'redis_version|redis_mode|uptime_in_days|process_id|config_file'
echo "========== 内存 =========="
$R INFO memory | grep -E 'used_memory_human|used_memory_rss_human|maxmemory_human|maxmemory_policy|mem_fragmentation_ratio'
echo "========== 客户端 =========="
$R INFO clients | grep -E 'connected_clients|blocked_clients|client_recent_max_input_buffer'
echo "========== 命中率与淘汰 =========="
$R INFO stats | grep -E 'keyspace_hits|keyspace_misses|evicted_keys|expired_keys|rejected_connections|instantaneous_ops_per_sec'
echo "========== 持久化 =========="
$R INFO persistence | grep -E 'rdb_last_bgsave_status|rdb_changes_since_last_save|aof_enabled|aof_last_bgrewrite_status|latest_fork_usec'
echo "========== 复制 =========="
$R INFO replication | grep -E '^role|connected_slaves|master_link_status|master_repl_offset|slave_repl_offset'
echo "========== 键空间 =========="
$R INFO keyspace
echo "========== 慢查询 TOP5 =========="
$R SLOWLOG GET 5
echo "========== 延迟事件 =========="
$R LATENCY LATEST
echo "========== 集群 =========="
$R CLUSTER INFO 2>/dev/null | grep -E 'cluster_state|cluster_slots_assigned|cluster_known_nodes'
18.2 常用单行命令
redis-cli PING
redis-cli INFO
redis-cli INFO memory
redis-cli INFO replication
redis-cli DBSIZE
redis-cli --scan --pattern 'app:*' | head
redis-cli --bigkeys -i 0.1
redis-cli --memkeys
redis-cli --stat
redis-cli --latency
redis-cli SLOWLOG GET 10
redis-cli CLIENT LIST
redis-cli CONFIG GET maxmemory
redis-cli CONFIG REWRITE
redis-cli BGSAVE
redis-cli BGREWRITEAOF
redis-cli --cluster check 10.0.0.11:6379
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
18.3 关键指标与阈值
| 指标 | 健康值 | 告警 |
|---|---|---|
used_memory / maxmemory |
< 70% | > 85% |
mem_fragmentation_ratio |
1.0~1.5 | > 1.5 或 < 1 |
connected_clients / maxclients |
< 60% | > 80% |
rejected_connections |
0 | > 0 |
keyspace_hit_ratio |
> 95% | < 90% |
master_link_status |
up | down |
latest_fork_usec |
< 100000 | > 500000 |
rdb_last_bgsave_status |
ok | err |
cluster_state |
ok | fail |
| P99 延迟 | < 1ms | > 10ms |
18.4 关键路径与端口
| 项 | 值 |
|---|---|
| 默认端口 | 6379 |
| 集群总线端口 | 16379(端口 + 10000) |
| Sentinel 端口 | 26379 |
| 配置文件 | /etc/redis/redis.conf |
| 数据目录 | /var/lib/redis |
| AOF 目录(7.0+) | /var/lib/redis/appendonlydir |
| 日志 | /var/log/redis/redis.log |
| Sentinel 配置 | /etc/redis/sentinel.conf |
| 服务名 | redis(RHEL)/ redis-server(Debian) |
附:与工作区其他手册的配合
- 操作系统层见
CentOS-7-10-常规运维指令手册.md/Ubuntu-常用运维指令手册.md - 放行端口:
firewall-cmd --add-port=6379/tcp --permanent(集群还要 16379) - 必做的系统层配置:
vm.overcommit_memory = 1(否则 BGSAVE fork 失败)net.core.somaxconn = 1024(提高连接队列)- 关闭 THP(透明大页会导致延迟尖刺):
echo never > /sys/kernel/mm/transparent_hugepage/enabled ulimit -n 65535
- 与其他数据库的核心差异:单线程模型决定了大 key 与慢命令是致命的、内存是硬约束、持久化有数据丢失窗口、集群用 slot 而非范围分片