Docker Compose 部署与日常排障¶
先在本机部署一个隔离的学习实例,练习写入、过期、重启和恢复,再读高可用。这里的实例只绑定宿主机回环地址,使用独立目录与卷;它不代表已具备生产高可用。
文件放在哪里¶
compose.yaml:
name: redis-learning
services:
redis:
image: redis:7.2
restart: unless-stopped
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
ports:
- "127.0.0.1:16379:6379"
volumes:
- ./redis.conf:/usr/local/etc/redis/redis.conf:ro
- redis-data:/data
mem_limit: 1g
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 3
volumes:
redis-data:
redis:7.2 是功能演示用版本系列,并非固定不可变制品。正式环境选受维护、验证过的补丁版本并固定 digest。示例假设较新的 Docker Compose 插件支持这些字段。
redis.conf:
bind 0.0.0.0
protected-mode yes
port 6379
daemonize no
dir /data
dbfilename dump.rdb
save 900 1
appendonly yes
appendfsync everysec
maxmemory 512mb
maxmemory-policy allkeys-lru
logfile ""
容器内部需要监听网络接口,宿主机发布端口则限制为 127.0.0.1:16379,避免与现有 6379 冲突。此实验未配置密码,不要改成公网绑定;同一 Docker 网络中的容器仍可能访问它。正式环境再按业务配置 ACL、网络边界和需要的加密连接。
1 GiB 容器、512 MiB maxmemory 为学习预算,后台重写与高写入时仍需观察峰值。allkeys-lru 适合此处缓存练习,不适合直接复制到重要任务或会话实例。
启动并确认¶
在上面的 redis-lab 目录执行:
docker compose config
docker compose up -d
docker compose ps
docker compose logs --tail=100 redis
docker compose exec redis redis-cli PING
docker compose exec redis redis-cli INFO server
docker compose exec redis redis-cli CONFIG GET maxmemory
docker compose exec redis redis-cli CONFIG GET maxmemory-policy
PING 返回 PONG 说明可以执行简单命令,再确认版本和有效配置。健康检查显示 unhealthy 不代表 Docker 一定自动重启该容器;这里的重启策略主要处理进程退出等情况。
进入交互命令行后练习前几页:
修改 redis.conf 后,在实验环境重启服务再核对生效值。CONFIG SET 属于运行时修改,不一定持久保存;本例配置文件只读,不能依靠 CONFIG REWRITE 回写,应该修改受管理的文件。
做一次重启实验¶
先写入一个测试 key,不设置 TTL,避免把过期与恢复混淆:
docker compose exec redis redis-cli SET learn:restart-check hello
docker compose exec redis redis-cli INFO persistence
docker compose restart redis
docker compose exec redis redis-cli GET learn:restart-check
预期返回 hello。这个实验验证正常重启与持久目录连接,不证明断电时零丢失,也不证明备份可以恢复。确认结果后可删除这一个实验 key。数据卷应保留;带 -v 的删除操作会同时删除卷,练习时不要误用。
六个日常检查入口¶
| 位置 | 看什么 | 对应的问题 |
|---|---|---|
| memory | 已用内存、RSS、maxmemory、碎片 | 是否接近上限、实际内存是否明显超过数据量 |
| stats | 命中/未命中、expired_keys、evicted_keys | 是 TTL 到期还是被淘汰,缓存是否有效 |
| clients | 连接、阻塞客户端 | 连接池是否失控;阻塞读客户端是否符合业务预期 |
| persistence | RDB/AOF 最近状态、后台任务 | 磁盘写入失败或重写是否异常 |
| replication | 角色、连接和复制进度 | 主从是否按预期连接、是否落后 |
| slowlog | 高耗时命令及参数线索 | 大 key、全量查询或 Lua 是否拖慢命令执行 |
SLOWLOG 主要衡量服务端命令执行耗时,不包含完整的网络等待和客户端排队。因此应用很慢而慢日志为空时,还要查网络、连接池、DNS、TLS、CPU 调度以及输出缓冲。相关机制见官方延迟排查。
遍历 key 时别一次拿全库¶
返回结果包含新游标和一批 key,下一次使用新游标,直到返回 0。COUNT 是工作量提示,不保证返回恰好 100 条;一次可能没有匹配 key,遍历也可能重复,不能把它当成固定时间点快照。
KEYS * 会集中遍历全库,大实例上容易阻塞。redis-cli --bigkeys 会扫描并统计不同类型的较大 key,也需要评估负载,成员最多不一定字节数最大。先缩小排查范围,再结合 MEMORY USAGE、HLEN、LLEN、SCARD 等检查具体 key。
故障发生时从哪里查¶
| 现象 | 排查顺序 |
|---|---|
| 连接不上 | 进程与日志 → 发布端口 → 网络/防火墙 → ACL、密码、TLS |
NOAUTH / WRONGPASS / NOPERM |
分别检查是否认证、凭据/用户状态、命令与 key 权限 |
WRONGTYPE |
用 TYPE 检查数据类型,确认 key 命名是否冲突 |
OOM command not allowed... |
maxmemory、淘汰策略、是否缺少可淘汰候选;不等于进程已被内核杀死 |
| 容器 OOMKilled | 容器上限、RSS、重写峰值、缓冲和主机内存 |
MISCONF 写入失败 |
查看持久化错误、磁盘容量/权限,不先关闭保护来掩盖原因 |
| 大量缓存未命中 | 重启冷缓存、TTL、淘汰、应用 key 或序列化规则变化 |
| 延迟突然升高 | 慢日志、大 key、重写/fork、CPU、网络、磁盘和客户端连接池 |
| 接口偶发超时 | 对齐应用与 Redis 时间线,注意写命令超时后结果可能未知 |
对结果未知的写操作,不应盲目无限重试。例如 INCR 重试可能多加一次,需要业务幂等或对账。MONITOR 会输出实时命令并增加负载,也可能暴露业务数据,不能当作长期默认监控。
接到一个生产 Redis,先确认什么¶
确认用途是缓存还是重要状态、单机还是 Sentinel/Cluster、应用连接方式、版本、内存上限、淘汰策略、持久化目录、备份恢复记录。再看连接池、超时和告警能否覆盖业务故障。
应用使用专门的 ACL 用户,限制命令及 key 范围;运维账号与业务账号分开。不要用多个逻辑数据库当成强隔离,也不要向公网直接开放 Redis。
上线后可以通过 Redis Exporter 等采集方式接入现有指标平台,重点跟踪延迟、错误、内存、淘汰、连接、持久化和复制状态。告警阈值按容量和业务基线设置,避免只告警进程是否活着。
下一步:主节点故障后如何接管。