Redis 部署运维
本文范围
Redis 很容易装,难的是装完以后谁来守住它:端口是不是暴露了,密码是不是写死了,内存有没有上限,RDB 和 AOF 有没有落盘,主库挂了谁来切,备份能不能真的恢复。
所以这篇文章不把 Redis 写成概念百科,我们就按真实部署顺序来:先装一台单机,能连上;再把配置文件、systemd、密码、端口、持久化和内存限制补齐;最后再做主从、哨兵、Cluster、备份恢复和故障排查。
这里先划边界。本文只讲 Redis 部署运维,不展开缓存穿透、击穿、雪崩,不深挖 Redisson 分布式锁,不讲业务缓存模型,也不讲 Spring Boot 客户端封装。这些内容该放到后端和架构主题里。这里的目标很直接:服务器上这套 Redis 能装、能查、能备、能切、能恢复。
当前写作时间是 2026-07-09,Redis Open Source 下载页主版本已经到 8.8。生产环境不要只看“最新版”三个字,真正要看的是:你的 Linux 发行版有没有对应包,客户端是否兼容,监控工具是否识别,回滚包是否准备好。Redis 8 起官方配置样例区分 redis.conf 和 redis-full.conf,这篇只讲 Redis Server 部署运维,主线按 redis.conf 来。
前置条件
读这篇文章前,先准备好下面这些东西。Redis 的安装命令很短,但生产里真正耗时间的是权限、网络、持久化目录和回滚包:
- 一台 Linux 测试机:Ubuntu 24.04 / Debian 12 / RHEL 9 / Rocky Linux 9 / AlmaLinux 9 均可。
- Redis Server 与
redis-cli:优先使用官方包、发行版包或内部制品库里已经校验过的包。 - 一个持久化目录:示例使用
/data/redis/6379,生产环境建议独立磁盘或独立挂载点。 - 网络边界:明确哪些应用服务器可以访问
6379,Sentinel 使用26379,Cluster 还要放行 cluster bus 端口。 - 一份恢复演练环境:不要只在生产机器上做第一次
BGSAVE、AOF rewrite 或主从切换。
部署形态怎么选
很多人一上来就问“Redis 要不要上 Cluster”。先别急。Cluster 是分片和容量扩展方案,不是所有系统的默认答案。
一般按这个顺序判断:
如果是学习、测试、小型内部系统,单机 Redis 就够了。如果读请求多,可以做主从。主库挂了不能等人半夜手动切,就加 Sentinel。如果单主内存不够、写入也打满了,再考虑 Cluster。
常见起步方案:
| 形态 | 机器和端口 | 解决什么 | 注意什么 |
|---|---|---|---|
| 单机 | 1 个实例,默认 6379 | 快速部署、低成本 | 没有自动切换 |
| 主从 | 1 主 1 到 2 从 | 读扩展、数据副本 | Redis 复制是异步的,不保证零丢失 |
| Sentinel | 1 主 2 从 + 3 个 Sentinel,默认 26379 | 主库故障自动切换 | 客户端要支持 Sentinel 发现 |
| Cluster | 3 主 3 从起步,示例 7000-7005 | 分片、容量扩展 | 客户端必须支持 Cluster,bus 端口也要通 |
这里要注意:Redis 高可用不是只多起几个进程。备份、监控、切换演练、客户端配置都要跟上,否则主库切过去了,应用还连着旧地址,业务一样不可用。
中国大陆、内网和离线环境先准备好
Redis 安装命令本身不难,难点是现场网络经常不配合。尤其是企业内网、金融政企、离线交付环境,不能默认 Redis 官网、GitHub、Docker Hub、国外 apt/yum 仓库都能访问。
一般按三种情况处理。
公网可访问
Ubuntu / Debian 可以用官方 APT 仓库:
sudo apt-get update
sudo apt-get install -y lsb-release curl gpg
curl -fsSL https://packages.redis.io/gpg \
| sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
sudo chmod 644 /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-get update
sudo apt-get install -y redis执行完以后不要马上认为安装成功,先看版本:
redis-server --version
redis-cli --version正常应该能看到 Redis 版本号。如果 apt-get update 报 GPG 错误,一般是 key 没导入成功;如果报仓库不可达,先确认服务器是否能访问 packages.redis.io,不要在生产服务器上临时乱换不明来源。
Rocky Linux / AlmaLinux 可以用官方 RPM 仓库。下面以 Rocky / AlmaLinux 9 为例:
sudo tee /etc/yum.repos.d/redis.repo >/dev/null <<'EOF'
[Redis]
name=Redis
baseurl=http://packages.redis.io/rpm/rockylinux9
enabled=1
gpgcheck=1
EOF
curl -fsSL https://packages.redis.io/gpg -o /tmp/redis.key
sudo rpm --import /tmp/redis.key
sudo yum install -y redis如果你的系统是 8.x,就把 rockylinux9 改成官方对应的 8.x 仓库。这里不要靠记忆写死,正式部署前重新看官方文档。
安装完成后启动:
sudo systemctl enable redis
sudo systemctl start redis
sudo systemctl status redis --no-pager看到 active (running) 说明服务进程起来了。如果服务名不是 redis,用下面命令查一下:
systemctl list-unit-files | grep -E '^redis'Ubuntu 上常见服务名是 redis-server,RPM 包常见服务名是 redis。脚本里一定不要凭感觉写服务名。
公网不稳或企业内网
这种环境一般需要一台下载机,把包先下载好,再放进内网制品库或文件服务器。
APT 包可以这样准备:
mkdir -p /opt/offline/redis-debs
cd /opt/offline/redis-debs
apt-get download redis redis-server redis-sentinel redis-tools
sha256sum *.deb > SHA256SUMS这里的 SHA256SUMS 是给后面校验用的。拷贝到内网机器以后先执行:
sha256sum -c SHA256SUMS看到每个包后面都是 OK,再安装。如果校验不通过,先停下来,不要带病安装。
RPM 包可以这样准备依赖:
sudo dnf install -y dnf-plugins-core
mkdir -p /opt/offline/redis-rpms
dnf download --resolve --destdir /opt/offline/redis-rpms redis
cd /opt/offline/redis-rpms
sha256sum *.rpm > SHA256SUMS内网安装时:
cd /opt/offline/redis-rpms
sha256sum -c SHA256SUMS
sudo yum localinstall -y ./*.rpm这里要注意:离线包不是“能装上一次”就完事。要把包、校验文件、安装脚本、版本说明一起归档。否则半年后要扩容一台机器,大家只剩下一堆不知道来源的 rpm。
完全离线
完全离线环境有三条路:离线 DEB/RPM、源码包、Docker 镜像包。生产服务器更推荐 DEB/RPM 或源码方式,容器方式要看你们是否已经有稳定的容器运行时和私有镜像仓库。
源码包准备:
wget https://download.redis.io/redis-stable.tar.gz
sha256sum redis-stable.tar.gz > redis-stable.tar.gz.sha256目标机器上编译:
sha256sum -c redis-stable.tar.gz.sha256
tar -xzvf redis-stable.tar.gz
cd redis-stable
make
sudo make install验证:
redis-server --version
redis-cli --version如果要启用 TLS,编译前需要准备 OpenSSL 开发库,然后这样编译:
make BUILD_TLS=yes
sudo make install如果你们用 Docker,要先在可联网机器下载镜像,再导出:
docker pull redis:<version>
docker save redis:<version> -o redis-<version>.tar
sha256sum redis-<version>.tar > redis-<version>.tar.sha256离线机器导入:
sha256sum -c redis-<version>.tar.sha256
docker load -i redis-<version>.tar
docker image inspect redis:<version>不要把某个临时可用的第三方镜像源写成唯一方案。国内镜像源和加速器可用性变化很快,生产标准应该是版本固定、来源可追溯、哈希可校验、包可回退。
先跑通一台单机 Redis
先别急着改一堆配置。第一步就是让 Redis 在本机跑起来,然后用 redis-cli 连一次。
启动服务:
sudo systemctl start redis
sudo systemctl status redis --no-pager如果你的服务名是 redis-server,就用:
sudo systemctl start redis-server
sudo systemctl status redis-server --no-pager看到 active (running) 后,测试连通:
redis-cli -h 127.0.0.1 -p 6379 PING正常应该返回:
PONG如果这里都不通,先不要看应用。按顺序查:
ss -lntp | grep 6379
journalctl -u redis -n 100 --no-pager
journalctl -u redis-server -n 100 --no-pagerss 看端口有没有监听,journalctl 看启动日志。如果日志里出现配置文件错误、目录权限错误、端口占用,先把这些处理掉。
把目录和配置文件管起来
Redis 能跑起来只是第一步。生产环境不能让数据目录、日志目录、配置文件散落在默认位置没人知道。
如果是源码安装,建议先建用户和目录:
sudo useradd --system --home /var/lib/redis --shell /usr/sbin/nologin redis
sudo install -d -o redis -g redis -m 0750 /etc/redis
sudo install -d -o redis -g redis -m 0750 /var/lib/redis
sudo install -d -o redis -g redis -m 0750 /var/log/redis
sudo install -d -o redis -g redis -m 0750 /run/redis这几条命令分别解决用户、配置目录、数据目录、日志目录和运行时目录问题。执行完以后看权限:
ls -ld /etc/redis /var/lib/redis /var/log/redis /run/redis应该看到这些目录属于 redis 用户和 redis 组。如果不是,后面 RDB、AOF 或日志写入很容易失败。
准备配置文件:
sudo cp redis.conf /etc/redis/redis.conf
sudo chown redis:redis /etc/redis/redis.conf
sudo chmod 0640 /etc/redis/redis.conf如果是包安装,配置文件一般已经存在。可以先找一下:
sudo find /etc -name 'redis*.conf' -maxdepth 3这里要注意:不要在生产机器上用“我先随便改一下”的方式改 Redis 配置。配置文件要进备份,要能回滚。后面事故复盘时,配置文件就是最关键的现场材料之一。
redis.conf 先改这几项
先看一份单机基线配置。不要一口气背完,先知道每一项解决什么问题。
port 6379
bind 127.0.0.1 10.0.0.11
protected-mode yes
supervised systemd
daemonize no
pidfile /run/redis/redis-server.pid
dir /var/lib/redis
logfile /var/log/redis/redis-server.log
loglevel notice
databases 16
timeout 0
tcp-keepalive 300
maxclients 10000
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
appendonly yes
appendfsync everysec
maxmemory 6gb
maxmemory-policy allkeys-lru
slowlog-log-slower-than 10000
slowlog-max-len 1024重点解释一下:
bind决定 Redis 监听哪些地址。不要为了远程连接直接写0.0.0.0后就不管了。protected-mode yes要保留,它不是万能安全方案,但能挡住一部分误暴露。dir是数据目录,RDB、AOF、临时文件都跟它有关。appendonly yes是开启 AOF,减少故障时的数据丢失窗口。maxmemory必须显式设置,不然 Redis 可能把机器内存吃满。slowlog-log-slower-than 10000表示记录超过 10ms 的命令,单位是微秒。
改完配置后重启:
sudo systemctl restart redis
sudo systemctl status redis --no-pager验证配置是否生效:
redis-cli CONFIG GET bind
redis-cli CONFIG GET protected-mode
redis-cli CONFIG GET maxmemory
redis-cli CONFIG GET maxmemory-policy
redis-cli INFO persistence如果 CONFIG GET maxmemory 返回 0,说明你没有真正设置内存上限。生产环境看到这个结果就要停下来处理。
用 systemd 托管 Redis
如果是包安装,一般已经带 systemd。源码安装就需要自己写服务文件。
示例:
[Unit]
Description=Redis Server
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0750
ExecStart=/usr/local/bin/redis-server /etc/redis/redis.conf --supervised systemd --daemonize no
ExecStop=/usr/local/bin/redis-cli -h 127.0.0.1 -p 6379 SHUTDOWN
Restart=on-failure
RestartSec=3
LimitNOFILE=65535
NoNewPrivileges=true
PrivateTmp=true
[Install]
WantedBy=multi-user.target保存为 Redis 服务文件后,加载并启动:
sudo systemctl daemon-reload
sudo systemctl enable redis
sudo systemctl start redis
sudo systemctl status redis --no-pager这里要注意两点。
第一,supervised systemd、daemonize no 和 systemd 的 Type=notify 要配套。否则 Redis 可能启动了,但 systemd 认为它没启动成功。
第二,如果 Redis 配了密码,不要把 redis-cli -a password 写进 systemd 命令行。这样密码可能出现在进程列表和审计日志里。可以使用 ACL、受限本机管理账号,或者给运维脚本提供受保护的环境变量。
端口、密码和访问边界
Redis 的安全原则很简单:先用网络挡住,再用认证兜底。不要把 Redis 暴露到公网后只靠密码硬扛。
先看 Redis 监听在哪里:
ss -lntp | grep 6379
redis-cli CONFIG GET bind如果你看到 Redis 监听在 0.0.0.0:6379,先确认是不是有明确的安全组、防火墙和来源 IP 限制。没有就赶紧收回去。
firewalld 示例:
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" port port="6379" protocol="tcp" accept'
sudo firewall-cmd --reload
sudo firewall-cmd --list-all客户端测试:
nc -vz 10.0.0.11 6379
redis-cli -h 10.0.0.11 -p 6379 PINGnc 成功只说明 TCP 能通,redis-cli PING 成功才说明 Redis 协议能通。
Redis 6 以后优先使用 ACL:
redis-cli ACL SETUSER app on '>change-me-to-a-long-random-secret' '~app:*' '+@read' '+@write' '-@dangerous'
redis-cli ACL SETUSER readonly on '>change-me-too' '~app:*' '+@read' '-@write' '-@dangerous'
redis-cli ACL SAVE验证:
redis-cli --user app --pass 'change-me-to-a-long-random-secret' PING
redis-cli --user app --pass 'change-me-to-a-long-random-secret' ACL WHOAMI如果返回 PONG,再返回 app,说明这个用户能正常登录。
老系统可能还用 requirepass:
requirepass "change-me-to-a-long-random-secret"连接时建议用环境变量,少用 -a:
export REDISCLI_AUTH='change-me-to-a-long-random-secret'
redis-cli -h 10.0.0.11 -p 6379 PING
unset REDISCLI_AUTH如果看到 NOAUTH Authentication required,说明 Redis 要认证但你没带密码。如果看到 WRONGPASS,说明用户名或密码不对。这个时候不要去重启 Redis,先查应用配置、密钥版本和 ACL 用户。
RDB 怎么做备份
Redis 数据在内存里跑得很快,但服务器重启、进程退出、机器故障时,内存数据会丢。RDB 就是把某个时刻的数据做成快照文件,方便备份和快速恢复。
先看当前 RDB 状态:
redis-cli INFO persistence | grep rdb手动触发一次后台快照:
redis-cli BGSAVE执行后不要马上复制文件,先等它完成:
redis-cli INFO persistence | grep rdb_bgsave_in_progress看到:
rdb_bgsave_in_progress:0说明后台保存结束了。再看文件:
ls -lh /var/lib/redis/dump.rdb这里要注意:生产环境不要随便执行 SAVE。SAVE 会阻塞 Redis 主线程,数据量大时业务会明显卡顿。一般用 BGSAVE。
一个简单的 RDB 备份脚本可以这样写:
#!/usr/bin/env bash
set -euo pipefail
host="${REDIS_HOST:-127.0.0.1}"
port="${REDIS_PORT:-6379}"
data_dir="${REDIS_DATA_DIR:-/var/lib/redis}"
backup_dir="${BACKUP_DIR:-/backup/redis}"
ts="$(date +%F-%H%M%S)"
mkdir -p "$backup_dir/$ts"
redis-cli -h "$host" -p "$port" BGSAVE
while true; do
running="$(redis-cli -h "$host" -p "$port" INFO persistence | awk -F: '/rdb_bgsave_in_progress/ {gsub(/\r/,"",$2); print $2}')"
[ "$running" = "0" ] && break
sleep 1
done
cp -a "$data_dir/dump.rdb" "$backup_dir/$ts/dump.rdb"
redis-cli -h "$host" -p "$port" INFO server > "$backup_dir/$ts/info-server.txt"
redis-cli -h "$host" -p "$port" INFO persistence > "$backup_dir/$ts/info-persistence.txt"
sha256sum "$backup_dir/$ts/dump.rdb" > "$backup_dir/$ts/SHA256SUMS"这个脚本做了四件事:触发快照、等待完成、复制 RDB、生成校验文件。备份完成后要把文件同步到远端存储或备份服务器,不能只放在 Redis 本机。机器盘坏了,本机备份也一起没了。
AOF 怎么配置
AOF 可以理解成 Redis 的写命令日志。每次写入都追加到 AOF 文件里,Redis 重启时再回放这些命令,把数据恢复出来。
开启 AOF:
appendonly yes
appendfsync everysecappendfsync 常用三种:
| 配置 | 含义 | 使用建议 |
|---|---|---|
always | 每次写尽量刷盘 | 最安全但最慢,必须压测 |
everysec | 每秒刷盘 | 常规生产起点 |
no | 交给操作系统刷盘 | 可重建缓存才考虑 |
改完配置后重启,再看:
redis-cli INFO persistence | grep aof正常应该能看到 AOF 已启用、最近写入状态正常。如果出现 aof_last_write_status:err,先看磁盘和权限:
df -h /var/lib/redis
ls -ld /var/lib/redis
journalctl -u redis -n 100 --no-pagerAOF 文件会变大,所以 Redis 会做 rewrite:
redis-cli BGREWRITEAOF
redis-cli INFO persistence | grep -E 'aof_rewrite|aof_last_bgrewrite_status'Redis 新版本的 AOF 可能是多文件布局,不要只凭旧经验找一个 appendonly.aof。排障时先看 INFO persistence 和数据目录。
如果 AOF 损坏,先停服务、备份现场,再修:
sudo systemctl stop redis
sudo cp -a /var/lib/redis /var/lib/redis.bak.$(date +%F-%H%M%S)
redis-check-aof --fix /var/lib/redis/appendonly.aof
sudo systemctl start redis如果实际是多文件 AOF,要按当前版本的 AOF manifest 和目录结构处理,不能生搬硬套单文件命令。
持久化方案评审时,不要只问“开没开 RDB/AOF”。下面这张图要一起看写入路径、刷盘策略、文件落点、校验、恢复和数据丢失窗口。生产上最怕的是 AOF 开了但 redis.conf 没落盘、RDB 文件只在本机、rewrite 临时空间不足,或者恢复时不知道 Redis 启动会优先加载哪一类文件。
排障时按图从右往左倒查:先用 redis-cli INFO persistence 看最近一次 RDB/AOF 状态,再看 dir 和 appendonlydir 下的文件,接着看磁盘容量、权限和 aof_last_write_status。恢复演练必须在隔离实例里完成,启动后用 DBSIZE、关键业务 key 抽样和 INFO persistence 验证,不要直接覆盖生产现场。
恢复演练一定要做
备份有没有用,不是看文件在不在,而是看能不能恢复。
RDB 恢复基本流程:
sudo systemctl stop redis
sudo cp -a /var/lib/redis /var/lib/redis.before-restore.$(date +%F-%H%M%S)
sudo install -o redis -g redis -m 0640 /backup/redis/2026-07-09-010000/dump.rdb /var/lib/redis/dump.rdb
sudo systemctl start redis启动后验证:
redis-cli PING
redis-cli DBSIZE
redis-cli INFO persistence应该看到 PONG,DBSIZE 也应该符合预期。如果你只想按 RDB 恢复,但配置里还开着 AOF,要先确认 Redis 启动时到底加载哪个文件。很多恢复事故不是没备份,而是 RDB 放进去了,却被旧 AOF 恢复结果覆盖。
生产建议:每个月至少做一次隔离环境恢复演练。恢复演练不要连生产客户端,不要用生产端口,避免误写。
内存必须有限制
Redis 是内存服务,不限制内存就像水龙头不装阀门。业务写多了、key 过期不及时、大 key 膨胀,最后可能把机器内存吃满。
先看内存:
redis-cli INFO memory
redis-cli MEMORY STATS
redis-cli MEMORY DOCTOR配置上限:
maxmemory 6gb
maxmemory-policy allkeys-lru验证:
redis-cli CONFIG GET maxmemory
redis-cli CONFIG GET maxmemory-policy如果 maxmemory 是 0,表示没有按 Redis 层限制内存。生产环境一般不建议这样。
常见淘汰策略:
| 策略 | 怎么淘汰 | 适合什么 |
|---|---|---|
noeviction | 内存满后写入报错 | 不能静默丢 key 的场景 |
allkeys-lru | 所有 key 里淘汰最近少用的 | 通用缓存 |
allkeys-lfu | 所有 key 里淘汰低频访问的 | 热点比较稳定的缓存 |
volatile-lru | 只淘汰设置过期时间的 key | 只有部分 key 允许淘汰 |
volatile-ttl | 优先淘汰快过期的 key | 希望临近过期数据先让位 |
这里要注意:如果 Redis 只是缓存,allkeys-lru 或 allkeys-lfu 可以作为起点。如果 Redis 里放了会话、队列状态、计数器这类不能随便丢的数据,就不能简单套 allkeys-lru。
内存打满常见报错:
OOM command not allowed when used memory > 'maxmemory'排查顺序:
redis-cli INFO memory
redis-cli CONFIG GET maxmemory
redis-cli CONFIG GET maxmemory-policy
redis-cli DBSIZE
redis-cli --bigkeys -i 0.1
redis-cli --memkeys -i 0.1
redis-cli --keystats --top 20 -i 0.1--bigkeys 看结构长度,--memkeys 和 --keystats 更适合找内存占用大的 key。生产上加 -i 0.1,让扫描慢一点,别把排查命令变成新的压力源。
big key 和慢日志怎么查
big key 的问题不只是“占内存”。它还会带来三个现场问题:节点内存不均、命令阻塞、网络流量突然放大。
先扫一遍:
redis-cli --bigkeys -i 0.1
redis-cli --keystats --top 20 -i 0.1定位单个 key:
redis-cli TYPE app:large:key
redis-cli MEMORY USAGE app:large:key
redis-cli OBJECT ENCODING app:large:key
redis-cli TTL app:large:key如果确认要删除大 key,不要直接用 DEL:
redis-cli UNLINK app:large:keyUNLINK 会异步释放内存,比 DEL 更适合删除大 key。这里也要注意,运维删除只是止血,根治还得改 key 设计。比如一个大 hash 拆成多个分片 hash,一个大 list 做归档或分页。
慢日志这样看:
redis-cli CONFIG GET slowlog-log-slower-than
redis-cli SLOWLOG LEN
redis-cli SLOWLOG GET 20如果看到 KEYS *、超大 HGETALL、大集合全量读取,先查是谁发的命令。生产不要把 KEYS 当查询接口,需要遍历用 SCAN:
redis-cli --scan --pattern 'app:user:*' | headSCAN 也不是随便扫全库。它只是比 KEYS 更温和,仍然要控制频率、pattern 和执行时间。
主从复制怎么搭
主从复制解决两个问题:读扩展和数据副本。它不解决强一致问题。主库刚写完还没同步给从库就挂了,这段数据可能丢。
主库配置:
port 6379
appendonly yes
requirepass "change-me"从库配置:
port 6379
replicaof 10.0.0.11 6379
masterauth "change-me"
replica-read-only yes
appendonly yes启动后验证主库:
redis-cli -h 10.0.0.11 INFO replication应该看到:
role:master
connected_slaves:1验证从库:
redis-cli -h 10.0.0.12 INFO replication
redis-cli -h 10.0.0.12 ROLE应该看到从库角色,以及 master_link_status:up。如果是 down,优先查网络、密码和主库地址。
临时把一个实例改成从库:
redis-cli -h 10.0.0.12 REPLICAOF 10.0.0.11 6379取消复制,让它变成主库:
redis-cli -h 10.0.0.12 REPLICAOF NO ONE这里要注意一个很容易踩的坑:不要把“从库有数据”当成“主库不用持久化”的理由。如果主库没持久化,主库故障后空数据重启,再同步给从库,可能把从库数据也冲掉。主库必须有 RDB/AOF 和外部备份。
Sentinel 怎么做自动切换
Sentinel 是给主从架构做自动故障转移的。它会监控主库和从库,判断主库是否不可用,然后选一个从库提升为新主库。
一般至少 3 个 Sentinel。不要只起 1 个,也不要把 2 个 Sentinel 当生产高可用。
Sentinel 配置示例:
port 26379
bind 10.0.0.11
protected-mode yes
dir /var/lib/redis-sentinel
logfile /var/log/redis/sentinel.log
sentinel monitor mymaster 10.0.0.11 6379 2
sentinel auth-pass mymaster change-me
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1启动:
redis-server /etc/redis/sentinel.conf --sentinel验证:
redis-cli -p 26379 SENTINEL masters
redis-cli -p 26379 SENTINEL replicas mymaster
redis-cli -p 26379 SENTINEL sentinels mymaster
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
redis-cli -p 26379 SENTINEL CKQUORUM mymasterSENTINEL CKQUORUM mymaster 很关键。它能告诉你当前 Sentinel 数量和多数派是否满足切换条件。不要等主库真的挂了才发现哨兵数量不够。
手动演练一次切换:
redis-cli -p 26379 SENTINEL FAILOVER mymaster
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster执行后应该看到 master 地址变成新的主库。然后再看每个 Redis 实例的角色:
redis-cli -h 10.0.0.11 ROLE
redis-cli -h 10.0.0.12 ROLE
redis-cli -h 10.0.0.13 ROLE这里要注意:应用不能写死旧主库 IP。客户端要配置 Sentinel 地址列表和 mymaster 这个名字,让客户端自己发现当前主库。否则 Sentinel 切成功了,应用还在连旧主库。
Sentinel 和 Cluster 经常被混在一起说,但它们解决的问题不同。下面这张图用于设计评审:Sentinel 关注主从故障转移和客户端重连,Cluster 关注 slot 分布、reshard 和分片边界。读写入口、故障判断和扩容动作不要混用。
上线前至少做两类演练:Sentinel 场景跑 SENTINEL CKQUORUM mymaster 和 SENTINEL FAILOVER mymaster,确认应用能按新 master 重连;Cluster 场景跑 CLUSTER SLOTS、CLUSTER NODES 和一次小范围 reshard,确认客户端能处理 MOVED / ASK,且顺序敏感或多 key 操作没有跨 slot 风险。
Redis Cluster 怎么搭
Cluster 是分片方案。Redis 会把 key 映射到 16384 个 hash slot,每个主节点负责一部分槽。客户端写入时,如果连错节点,会收到 MOVED 或 ASK 重定向。
Cluster 还有一个很容易漏的点:每个节点除了客户端端口,还要开放 cluster bus 端口。默认 bus 端口是服务端口加 10000,例如 7000 对应 17000。
单实例配置模板:
port 7000
bind 10.0.0.11
protected-mode yes
dir /var/lib/redis/7000
logfile /var/log/redis/redis-7000.log
pidfile /run/redis/redis-7000.pid
cluster-enabled yes
cluster-config-file nodes-7000.conf
cluster-node-timeout 15000
appendonly yes
appendfsync everysec
maxmemory 6gb
maxmemory-policy allkeys-lru6 个实例准备好以后创建集群:
redis-cli --cluster create \
10.0.0.11:7000 10.0.0.11:7001 \
10.0.0.12:7002 10.0.0.12:7003 \
10.0.0.13:7004 10.0.0.13:7005 \
--cluster-replicas 1如果启用了密码:
REDISCLI_AUTH='change-me' redis-cli --cluster create \
10.0.0.11:7000 10.0.0.11:7001 \
10.0.0.12:7002 10.0.0.12:7003 \
10.0.0.13:7004 10.0.0.13:7005 \
--cluster-replicas 1验证:
redis-cli -c -h 10.0.0.11 -p 7000 CLUSTER INFO
redis-cli -c -h 10.0.0.11 -p 7000 CLUSTER NODES
redis-cli -c -h 10.0.0.11 -p 7000 CLUSTER SLOTS正常要看到:
cluster_state:ok测试写入:
redis-cli -c -h 10.0.0.11 -p 7000 SET app:user:1001 zhangsan
redis-cli -c -h 10.0.0.11 -p 7000 GET app:user:1001这里 -c 表示让 redis-cli 支持 Cluster 重定向。如果不加 -c,你可能看到:
MOVED 1234 10.0.0.12:7002这不是 Redis 坏了,而是你连到的节点不负责这个槽。生产客户端必须使用支持 Cluster 的客户端。
检查集群:
redis-cli --cluster check 10.0.0.11:7000
redis-cli --cluster info 10.0.0.11:7000扩容时添加新节点:
redis-cli --cluster add-node 10.0.0.14:7006 10.0.0.11:7000
redis-cli --cluster reshard 10.0.0.11:7000扩容前先查 big key。如果某个槽里有超大 key,迁移会很慢,甚至造成业务抖动。
日常巡检怎么做
巡检不要只看进程在不在。Redis 巡检至少看六层:机器、端口、进程、Redis 状态、持久化、复制或集群。
机器:
uptime
free -h
df -h
iostat -xz 1 3进程和端口:
systemctl status redis --no-pager
ss -lntp | grep redis
ps -eo pid,ppid,user,%cpu,%mem,cmd | grep redis-server | grep -v grepRedis:
redis-cli PING
redis-cli INFO server
redis-cli INFO clients
redis-cli INFO memory
redis-cli INFO persistence
redis-cli INFO replication
redis-cli INFO stats慢命令和大 key:
redis-cli SLOWLOG GET 20
redis-cli --bigkeys -i 0.1
redis-cli --keystats --top 20 -i 0.1如果是 Cluster,再加:
redis-cli -c -p 7000 CLUSTER INFO
redis-cli --cluster check 10.0.0.11:7000生产监控至少要覆盖:connected_clients、blocked_clients、used_memory、maxmemory、evicted_keys、rejected_connections、rdb_last_bgsave_status、aof_last_write_status、master_link_status、复制延迟、cluster_state、磁盘空间和系统内存。
常见故障怎么排
服务起不来
先看服务状态:
systemctl status redis --no-pager
journalctl -u redis -n 200 --no-pager如果服务名是 redis-server:
systemctl status redis-server --no-pager
journalctl -u redis-server -n 200 --no-pager常见原因就几类:配置文件写错、端口被占用、数据目录权限不对、RDB/AOF 文件损坏、systemd 配置和 redis.conf 不匹配。
看端口:
ss -lntp | grep 6379
lsof -iTCP:6379 -sTCP:LISTEN看目录权限:
ls -ld /var/lib/redis /var/log/redis如果日志写着 permission denied,先修权限:
sudo chown -R redis:redis /var/lib/redis /var/log/redis远程连不上
先在服务端确认 Redis 活着:
redis-cli -h 127.0.0.1 -p 6379 PING
ss -lntp | grep 6379
redis-cli CONFIG GET bind
redis-cli CONFIG GET protected-mode客户端机器测试:
nc -vz 10.0.0.11 6379
redis-cli -h 10.0.0.11 -p 6379 PING常见现象:
| 现象 | 通常是什么问题 |
|---|---|
Connection refused | 服务没起,或者没有监听这个地址 |
No route to host | 网络、路由、防火墙、安全组问题 |
DENIED Redis is running in protected mode | 远程访问但安全配置没配好 |
NOAUTH Authentication required | 没认证 |
WRONGPASS | 密码或 ACL 用户不对 |
不要一看到连不上就重启 Redis。先分清是进程、端口、网络、认证还是配置。
连接数打满
现象一般是:
ERR max number of clients reached排查:
redis-cli INFO clients
redis-cli CONFIG GET maxclients
redis-cli CLIENT LIST | awk '{print $2}' | sort | uniq -c | sort -nr | head如果某个应用 IP 连接特别多,先查它的连接池配置,看看是不是短连接风暴或连接泄漏。临时调大 maxclients 前先看系统文件句柄:
ulimit -n
cat /proc/$(pidof redis-server | awk '{print $1}')/limits | grep filesRDB 或 AOF 失败
排查:
redis-cli INFO persistence
df -h /var/lib/redis
ls -lh /var/lib/redis
journalctl -u redis -n 200 --no-pager重点看:
| 指标 | 说明 |
|---|---|
rdb_last_bgsave_status:err | 最近一次 RDB 失败 |
aof_last_bgrewrite_status:err | 最近一次 AOF rewrite 失败 |
aof_last_write_status:err | AOF 写入失败 |
磁盘满了先扩容或清理无关文件,不要上来就删 Redis 数据文件。文件损坏时先备份现场,再用 redis-check-rdb 或 redis-check-aof。
主从不同步
主库看:
redis-cli -h 10.0.0.11 INFO replication从库看:
redis-cli -h 10.0.0.12 INFO replication
redis-cli -h 10.0.0.12 ROLE重点看 master_link_status、复制 offset、认证失败日志。如果 master_link_status:down,优先查网络、主库密码、masterauth 和防火墙。
Sentinel 不切换
先看 quorum:
redis-cli -p 26379 SENTINEL CKQUORUM mymaster再看 Sentinel 眼里的主从:
redis-cli -p 26379 SENTINEL masters
redis-cli -p 26379 SENTINEL replicas mymaster
redis-cli -p 26379 SENTINEL sentinels mymaster如果 Sentinel 数量不足、网络分区、密码不对、sentinel.conf 不可写,都会导致切换不符合预期。切换问题一定要看 Sentinel 日志,不要只看 Redis 主从日志。
Cluster 槽位异常
常见报错:
CLUSTERDOWN Hash slot not served
MOVED 1234 10.0.0.12:7002
ASK 1234 10.0.0.12:7002排查:
redis-cli -c -p 7000 CLUSTER INFO
redis-cli -c -p 7000 CLUSTER NODES
redis-cli -c -p 7000 CLUSTER SLOTS
redis-cli --cluster check 10.0.0.11:7000MOVED 多数是客户端没开 Cluster 模式或连错节点。ASK 常出现在槽迁移过程中。Hash slot not served 要查是否有槽没有分配,或者 reshard 中断。
如果节点看起来都活着但集群异常,别忘了查 bus 端口:
nc -vz 10.0.0.11 17000
nc -vz 10.0.0.12 17002落地工程深水区
Redis 的生产风险通常不是语法问题,而是内存、持久化、复制和客户端行为互相放大。部署时要把下面几件事写成硬约束。
| 维度 | 必须明确的边界 | 常用验证 |
|---|---|---|
| 内存 | maxmemory 不能等于机器内存,要给 fork、AOF rewrite、复制缓冲和系统留空间 | redis-cli INFO memory |
| 持久化 | RDB、AOF、混合持久化选型要匹配 RPO,不能只说“开了持久化” | redis-cli INFO persistence |
| 高可用 | Sentinel 要验证 quorum,Cluster 要验证 slot 和 bus 端口 | redis-cli SENTINEL CKQUORUM mymaster、redis-cli --cluster check |
| 客户端 | 禁止业务随意 KEYS、大 value、无超时连接和无限重试 | redis-cli SLOWLOG GET 10、redis-cli --bigkeys |
| 权限 | ACL 按应用分用户,运维账号和业务账号分开 | redis-cli ACL LIST |
容量评审不要只看当前 key 数。更实用的检查是把“写入峰值 + fork 额外内存 + AOF 重写 + 主从复制缓冲”一起算:
redis-cli INFO memory | egrep 'used_memory_human|used_memory_peak_human|maxmemory_human|mem_fragmentation_ratio'
redis-cli INFO persistence | egrep 'rdb_last_bgsave_status|aof_last_bgrewrite_status|aof_current_size'
redis-cli INFO replication | egrep 'role|connected_slaves|master_link_status|master_repl_offset'
redis-cli --bigkeys -i 0.01
redis-cli SLOWLOG GET 10如果 Redis 被多个业务共用,运维侧要强制落三条线:
- 每个业务有独立 DB 或独立实例,关键系统不要和缓存实验场混用。
- key 命名、TTL、最大 value、批量删除方式写入研发规范,避免上线后靠巡检猜用途。
- 切换演练要覆盖客户端重连行为,Sentinel 或 Cluster 节点恢复不等于业务一定恢复。
上线前检查清单
上线前不要只执行一个 PING。按下面顺序过一遍:
redis-cli PING
redis-cli INFO server
redis-cli INFO clients
redis-cli INFO memory
redis-cli INFO persistence
redis-cli INFO replication
redis-cli CONFIG GET bind
redis-cli CONFIG GET protected-mode
redis-cli CONFIG GET maxmemory
redis-cli CONFIG GET maxmemory-policy
redis-cli SLOWLOG GET 5生产 checklist:
| 类别 | 检查点 |
|---|---|
| 版本 | Redis 版本、安装包来源、回退包都记录 |
| 安全 | 不暴露公网,防火墙限制来源,ACL 或密码已配置 |
| 配置 | bind、protected-mode、maxmemory、持久化策略明确 |
| 备份 | RDB/AOF 策略明确,备份能校验,恢复演练做过 |
| 内存 | 留出系统、fork、AOF rewrite、复制缓冲空间 |
| 高可用 | 主从、Sentinel 或 Cluster 已演练 |
| 监控 | 内存、连接、慢日志、持久化、复制、槽位都有告警 |
| 客户端 | Sentinel/Cluster 客户端配置经过切换验证 |
最后记住一句实战话:Redis 的部署不是“服务启动成功”就结束,而是“故障发生时能不能按命令一步步找回来”。能恢复,才算真正上线。
常用命令速查
# 基础状态
redis-cli PING
redis-cli INFO
redis-cli ROLE
redis-cli DBSIZE
# 配置
redis-cli CONFIG GET '*memory*'
redis-cli CONFIG GET maxclients
redis-cli CONFIG REWRITE
# 持久化
redis-cli BGSAVE
redis-cli BGREWRITEAOF
redis-cli LASTSAVE
redis-cli INFO persistence
# 内存和 key
redis-cli INFO memory
redis-cli MEMORY STATS
redis-cli MEMORY DOCTOR
redis-cli MEMORY USAGE key
redis-cli --bigkeys -i 0.1
redis-cli --memkeys -i 0.1
redis-cli --keystats --top 20 -i 0.1
# 慢日志
redis-cli SLOWLOG LEN
redis-cli SLOWLOG GET 20
redis-cli SLOWLOG RESET
# 客户端
redis-cli INFO clients
redis-cli CLIENT LIST
redis-cli CLIENT KILL id <client-id>
# 主从
redis-cli INFO replication
redis-cli ROLE
redis-cli REPLICAOF <host> <port>
redis-cli REPLICAOF NO ONE
# Sentinel
redis-cli -p 26379 SENTINEL masters
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
redis-cli -p 26379 SENTINEL CKQUORUM mymaster
redis-cli -p 26379 SENTINEL FAILOVER mymaster
# Cluster
redis-cli -c -p 7000 CLUSTER INFO
redis-cli -c -p 7000 CLUSTER NODES
redis-cli -c -p 7000 CLUSTER SLOTS
redis-cli --cluster check 10.0.0.11:7000
redis-cli --cluster info 10.0.0.11:7000官方文档入口
- Redis Open Source 安装总览:https://redis.io/docs/latest/operate/oss_and_stack/install/install-stack/
- APT 安装:https://redis.io/docs/latest/operate/oss_and_stack/install/install-stack/apt/
- RPM 安装:https://redis.io/docs/latest/operate/oss_and_stack/install/install-stack/rpm/
- 源码安装:https://redis.io/docs/latest/operate/oss_and_stack/install/archive/install-redis/install-redis-from-source/
- Redis 配置:https://redis.io/docs/latest/operate/oss_and_stack/management/config/
- Redis 安全:https://redis.io/docs/latest/operate/oss_and_stack/management/security/
- Redis 持久化:https://redis.io/docs/latest/operate/oss_and_stack/management/persistence/
- Redis 复制:https://redis.io/docs/latest/operate/oss_and_stack/management/replication/
- Redis Sentinel:https://redis.io/docs/latest/operate/oss_and_stack/management/sentinel/
- Redis Cluster:https://redis.io/docs/latest/operate/oss_and_stack/management/scaling/
- Cluster specification:https://redis.io/docs/latest/operate/oss_and_stack/reference/cluster-spec/
- 淘汰策略:https://redis.io/docs/latest/develop/reference/eviction/
- redis-cli:https://redis.io/docs/latest/develop/tools/cli/
- SLOWLOG GET:https://redis.io/docs/latest/commands/slowlog-get/
- MEMORY USAGE:https://redis.io/docs/latest/commands/memory-usage/
- CLIENT LIST:https://redis.io/docs/latest/commands/client-list/
