Redis 工程化部署深度解析
📖 本文档定位 :本文是
Redis数据库工程化部署安装流程.md的配套解析文档。部署流程文档回答「怎么做」,本文档回答「为什么这么做、每条命令的原理是什么、不这么做会怎样」。每一条命令、每一个配置字段都会被逐行拆解,力求不遗漏、不遗留。所有示意图使用 Mermaid 流程图,可在 Obsidian / GitHub / VS Code 中直接渲染。
目录
- 一、整体架构与部署全景
- 二、第一章「配置需求」解析
- 三、第三章「验证环节」逐条解析
- 四、第四章「具体流程」逐条深度解析
- 五、第五章「常用管理命令」逐条解析
- 六、第六章「验证连接」逐条解析
- 七、第七章「备份与恢复」逐条解析
- 八、第八章「监控与告警」逐条解析
- 九、第九章「故障排查」逐条解析
- 十、第十章「升级与回滚」逐条解析
- 十一、附录解析
- 十二、全流程串联总览
一、整体架构与部署全景
1.1 部署架构图
#mermaid-svg-gL0amcFK95jb7l0S{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-gL0amcFK95jb7l0S .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-gL0amcFK95jb7l0S .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-gL0amcFK95jb7l0S .error-icon{fill:#552222;}#mermaid-svg-gL0amcFK95jb7l0S .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-gL0amcFK95jb7l0S .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-gL0amcFK95jb7l0S .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-gL0amcFK95jb7l0S .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-gL0amcFK95jb7l0S .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-gL0amcFK95jb7l0S .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-gL0amcFK95jb7l0S .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-gL0amcFK95jb7l0S .marker{fill:#333333;stroke:#333333;}#mermaid-svg-gL0amcFK95jb7l0S .marker.cross{stroke:#333333;}#mermaid-svg-gL0amcFK95jb7l0S svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-gL0amcFK95jb7l0S p{margin:0;}#mermaid-svg-gL0amcFK95jb7l0S .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-gL0amcFK95jb7l0S .cluster-label text{fill:#333;}#mermaid-svg-gL0amcFK95jb7l0S .cluster-label span{color:#333;}#mermaid-svg-gL0amcFK95jb7l0S .cluster-label span p{background-color:transparent;}#mermaid-svg-gL0amcFK95jb7l0S .label text,#mermaid-svg-gL0amcFK95jb7l0S span{fill:#333;color:#333;}#mermaid-svg-gL0amcFK95jb7l0S .node rect,#mermaid-svg-gL0amcFK95jb7l0S .node circle,#mermaid-svg-gL0amcFK95jb7l0S .node ellipse,#mermaid-svg-gL0amcFK95jb7l0S .node polygon,#mermaid-svg-gL0amcFK95jb7l0S .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-gL0amcFK95jb7l0S .rough-node .label text,#mermaid-svg-gL0amcFK95jb7l0S .node .label text,#mermaid-svg-gL0amcFK95jb7l0S .image-shape .label,#mermaid-svg-gL0amcFK95jb7l0S .icon-shape .label{text-anchor:middle;}#mermaid-svg-gL0amcFK95jb7l0S .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-gL0amcFK95jb7l0S .rough-node .label,#mermaid-svg-gL0amcFK95jb7l0S .node .label,#mermaid-svg-gL0amcFK95jb7l0S .image-shape .label,#mermaid-svg-gL0amcFK95jb7l0S .icon-shape .label{text-align:center;}#mermaid-svg-gL0amcFK95jb7l0S .node.clickable{cursor:pointer;}#mermaid-svg-gL0amcFK95jb7l0S .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-gL0amcFK95jb7l0S .arrowheadPath{fill:#333333;}#mermaid-svg-gL0amcFK95jb7l0S .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-gL0amcFK95jb7l0S .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-gL0amcFK95jb7l0S .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gL0amcFK95jb7l0S .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-gL0amcFK95jb7l0S .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gL0amcFK95jb7l0S .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-gL0amcFK95jb7l0S .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-gL0amcFK95jb7l0S .cluster text{fill:#333;}#mermaid-svg-gL0amcFK95jb7l0S .cluster span{color:#333;}#mermaid-svg-gL0amcFK95jb7l0S div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-gL0amcFK95jb7l0S .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-gL0amcFK95jb7l0S rect.text{fill:none;stroke-width:0;}#mermaid-svg-gL0amcFK95jb7l0S .icon-shape,#mermaid-svg-gL0amcFK95jb7l0S .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gL0amcFK95jb7l0S .icon-shape p,#mermaid-svg-gL0amcFK95jb7l0S .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-gL0amcFK95jb7l0S .icon-shape .label rect,#mermaid-svg-gL0amcFK95jb7l0S .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gL0amcFK95jb7l0S .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-gL0amcFK95jb7l0S .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-gL0amcFK95jb7l0S :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 宿主机 Ubuntu 22.04
客户端层
Docker Engine
文件系统 /opt/redis
TCP 6379
bind mount
bind mount
bind mount
读取
定时拷贝
作用于
内核参数
vm.overcommit_memory=1
somaxconn=1024
THP=never
应用服务 / Python 脚本
data/
RDB + AOF 数据
conf/redis.conf
主配置文件
logs/
日志目录
backup/
备份文件
redis_server 容器
UID 999 运行
redis:7.2
宿主机端口 6379
1.2 部署流程总览
#mermaid-svg-oqog3fr0fcEWQZgn{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-oqog3fr0fcEWQZgn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-oqog3fr0fcEWQZgn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-oqog3fr0fcEWQZgn .error-icon{fill:#552222;}#mermaid-svg-oqog3fr0fcEWQZgn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-oqog3fr0fcEWQZgn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-oqog3fr0fcEWQZgn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-oqog3fr0fcEWQZgn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-oqog3fr0fcEWQZgn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-oqog3fr0fcEWQZgn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-oqog3fr0fcEWQZgn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-oqog3fr0fcEWQZgn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-oqog3fr0fcEWQZgn .marker.cross{stroke:#333333;}#mermaid-svg-oqog3fr0fcEWQZgn svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-oqog3fr0fcEWQZgn p{margin:0;}#mermaid-svg-oqog3fr0fcEWQZgn .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-oqog3fr0fcEWQZgn .cluster-label text{fill:#333;}#mermaid-svg-oqog3fr0fcEWQZgn .cluster-label span{color:#333;}#mermaid-svg-oqog3fr0fcEWQZgn .cluster-label span p{background-color:transparent;}#mermaid-svg-oqog3fr0fcEWQZgn .label text,#mermaid-svg-oqog3fr0fcEWQZgn span{fill:#333;color:#333;}#mermaid-svg-oqog3fr0fcEWQZgn .node rect,#mermaid-svg-oqog3fr0fcEWQZgn .node circle,#mermaid-svg-oqog3fr0fcEWQZgn .node ellipse,#mermaid-svg-oqog3fr0fcEWQZgn .node polygon,#mermaid-svg-oqog3fr0fcEWQZgn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-oqog3fr0fcEWQZgn .rough-node .label text,#mermaid-svg-oqog3fr0fcEWQZgn .node .label text,#mermaid-svg-oqog3fr0fcEWQZgn .image-shape .label,#mermaid-svg-oqog3fr0fcEWQZgn .icon-shape .label{text-anchor:middle;}#mermaid-svg-oqog3fr0fcEWQZgn .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-oqog3fr0fcEWQZgn .rough-node .label,#mermaid-svg-oqog3fr0fcEWQZgn .node .label,#mermaid-svg-oqog3fr0fcEWQZgn .image-shape .label,#mermaid-svg-oqog3fr0fcEWQZgn .icon-shape .label{text-align:center;}#mermaid-svg-oqog3fr0fcEWQZgn .node.clickable{cursor:pointer;}#mermaid-svg-oqog3fr0fcEWQZgn .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-oqog3fr0fcEWQZgn .arrowheadPath{fill:#333333;}#mermaid-svg-oqog3fr0fcEWQZgn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-oqog3fr0fcEWQZgn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-oqog3fr0fcEWQZgn .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-oqog3fr0fcEWQZgn .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-oqog3fr0fcEWQZgn .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-oqog3fr0fcEWQZgn .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-oqog3fr0fcEWQZgn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-oqog3fr0fcEWQZgn .cluster text{fill:#333;}#mermaid-svg-oqog3fr0fcEWQZgn .cluster span{color:#333;}#mermaid-svg-oqog3fr0fcEWQZgn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-oqog3fr0fcEWQZgn .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-oqog3fr0fcEWQZgn rect.text{fill:none;stroke-width:0;}#mermaid-svg-oqog3fr0fcEWQZgn .icon-shape,#mermaid-svg-oqog3fr0fcEWQZgn .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-oqog3fr0fcEWQZgn .icon-shape p,#mermaid-svg-oqog3fr0fcEWQZgn .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-oqog3fr0fcEWQZgn .icon-shape .label rect,#mermaid-svg-oqog3fr0fcEWQZgn .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-oqog3fr0fcEWQZgn .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-oqog3fr0fcEWQZgn .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-oqog3fr0fcEWQZgn :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
环境校验
Docker + 镜像源
拉取 redis:7.2
内核三项调优
overcommit/somaxconn/THP
编写 redis.conf
持久化+内存+安全
授权目录 999:999
编写 docker-compose.yml
docker compose up -d
STATUS=healthy?
redis-cli ping → PONG
查 logs 排障
部署完成
1.3 核心设计理念
| 设计理念 | 在本部署中的体现 |
|---|---|
| 声明式配置 | 用 docker-compose.yml + redis.conf 描述「要什么」,而不是用 docker run 描述「怎么做」 |
| 数据与计算分离 | 数据落宿主机 /opt/redis/data,容器可随时销毁重建,数据不丢 |
| 最小权限 | 容器内以非 root 用户(UID 999)运行 Redis |
| 内存有界(Redis 特有) | maxmemory + maxmemory-policy 设硬上限,防止吃光宿主机内存触发 OOM |
| 持久化双保险(Redis 特有) | RDB 快照 + AOF 追加日志同时开启,兼顾恢复速度与数据安全 |
| 安全加固(Redis 特有) | requirepass 设密码 + rename-command 禁用危险命令,杜绝未授权访问 |
| 可观测性 | 配置 healthcheck + logging,容器假活可被发现,日志不会撑满磁盘 |
| 可恢复性 | 提供 BGSAVE 备份 + 定时任务 + RDB/AOF 恢复的完整闭环 |
二、第一章「配置需求」解析
2.1 系统要求
- 一台装了 Docker 的服务器
- 该服务器能与本地 win 电脑 ping 通
- 操作系统:Ubuntu 22.04(推荐)
逐条解析:
| 要求 | 原理 |
|---|---|
| 装了 Docker | 整个部署基于容器化,Docker Engine 是前提。Compose V2 已内置为 docker compose 子命令,无需单独安装 |
| 能 ping 通 | 后续第六章要用 Python 从 Windows 远程连接 Redis。网络不通则所有远程验证失败。这一条把网络问题前置排除 |
| Ubuntu 22.04 | LTS 长期支持版,内核 5.15+,对 Docker、cgroup v2 支持完善;且 /sys/kernel/mm/transparent_hugepage 路径标准,便于关闭 THP |
2.2 资源需求
- Redis 7.2 镜像(Docker 官方仓库)
- 国内的能用来拉取镜像的 docker 镜像源
为什么需要国内镜像源: Docker Hub 官方仓库在海外,国内直连拉取极慢甚至超时。需配置 daemon.json 的 registry-mirrors 指向国内加速节点。
为什么选 Redis 7.2:
- Redis 7 是当前稳定大版本,引入了 multi-part AOF 、Function (替代 EVAL)、ACL 增强 等关键特性
.2是该大版本的小版本补丁,修复了已知安全与稳定性问题- 指定精确版本号(而非
latest)是工程化最佳实践:避免未来latest指向新大版本导致行为不兼容
2.3 预备配置参数
| 参数 | 值 | 解析 |
|---|---|---|
| 端口 | 6379 | Redis 官方默认端口,IANA 注册端口 |
| 访问密码 | redis123 | 教程示例值。生产环境必须替换为强密码 |
| 数据目录(宿主机) | /opt/redis/data | RDB 与 AOF 文件落盘位置 |
| 配置目录(宿主机) | /opt/redis/conf | redis.conf 主配置文件位置 |
| 备份目录(宿主机) | /opt/redis/backup | 定时备份与升级前备份存放处 |
⚠️ 安全提醒 :
redis123是公开示例凭证。历史上大量 Redis 被植入挖矿/勒索脚本,根本原因就是公网暴露 + 弱密码。务必修改。
三、第三章「验证环节」逐条解析
本章的作用是前置排障:在正式部署前,先确认 Docker 环境和镜像拉取能力正常。
3.1 验证 Docker 环境
命令 1:检查 Docker 是否安装
sudo docker --version
| 片段 | 作用 |
|---|---|
sudo |
以 root 权限执行。Docker 守护进程监听 /var/run/docker.sock,默认只有 root 和 docker 组用户可访问 |
docker |
Docker CLI 客户端 |
--version |
打印 Docker 版本号并退出(不连接守护进程) |
预期输出: Docker version 24.x.x, build xxxxxxx
如果失败: 说明 Docker 未安装,需先执行 curl -fsSL https://get.docker.com | sh 安装。
命令 2:检查 Docker 服务是否运行
sudo systemctl status docker
| 片段 | 作用 |
|---|---|
systemctl |
Systemd 服务管理工具 |
status |
查看服务运行状态 |
docker |
服务名 |
预期输出: 绿色 active (running)
3.2 验证镜像源是否能进行拉取镜像
sudo docker pull hello-world
原理: 用最小镜像(约 13KB)测试网络通路,而不是直接拉 redis(约 130MB)。如果 hello-world 都拉不下来,说明镜像源有问题,拉大镜像必然超时。
3.3 配置 Docker 镜像源
编辑 daemon.json
json
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://docker.1ms.run",
"https://docker.anyhub.us.kg"
],
"dns": ["223.5.5.5", "114.114.114.114"]
}
| 字段 | 作用 |
|---|---|
registry-mirrors |
镜像加速地址列表。Docker 拉取镜像时会依次尝试列表中的地址,第一个成功即停止 |
dns |
容器内 DNS 解析服务器。阿里/114 国内解析快,避免容器内域名解析失败 |
原理: Docker 默认从 registry-1.docker.io 拉取。配置 registry-mirrors 后,Docker 优先通过镜像加速节点拉取------加速节点本质是 Docker Hub 的反向代理/缓存。
重新加载 + 重启
sudo systemctl daemon-reload # 让 systemd 重新读取 service 配置
sudo systemctl restart docker # 守护进程启动时才读 daemon.json,必须重启
四、第四章「具体流程」逐条深度解析
本章是整个部署的核心。Redis 比 PostgreSQL 多一个关键环节------内核参数调优,否则持久化会埋雷。
4.1 拉取 Redis 镜像
sudo docker pull redis:7.2
| 片段 | 作用 |
|---|---|
docker pull |
从 registry 拉取镜像到本地 |
redis |
镜像名(官方 Redis 镜像) |
:7.2 |
版本标签。精确指定大版本 7 + 小版本 2 |
为什么不用 latest: latest 是浮动指针------今天指向 7.2,明天可能指向 8.0。生产用 latest 会导致不可复现、意外升级、无法回滚。
镜像分层原理: 镜像内 docker-entrypoint.sh 是关键------它负责解析启动命令。本方案通过 command 让它执行 redis-server /usr/local/etc/redis/redis.conf,从而读取我们挂载的自定义配置。
4.2 准备部署目录
sudo mkdir -p /opt/redis/{data,conf,backup,logs}
cd /opt/redis
| 命令 | 作用 |
|---|---|
mkdir -p /opt/redis/{data,conf,backup,logs} |
一次性创建四个子目录。{a,b,c} 是 bash 花括号展开;-p 递归创建父目录,已存在不报错 |
cd /opt/redis |
切换到 compose 工作目录 |
为什么用 /opt/ 目录: 按 FHS(文件系统层次标准),/opt/ 是第三方独立软件/大型应用的安装目录,语义最合适,便于备份、迁移、识别。
为什么需要专门的 compose 目录: Docker Compose 在哪个目录执行 docker compose,就以当前目录的 docker-compose.yml 为部署描述文件。固定目录后,团队协作和脚本都能统一引用。
4.3 调整宿主机内核参数(Redis 工程化关键)
这是 Redis 区别于其他数据库的最特殊一环。Redis 用 fork + COW(Copy-On-Write) 机制做后台持久化,对内核有三个硬性要求。
sudo sysctl -w vm.overcommit_memory=1
sudo sysctl -w net.core.somaxconn=1024
sudo bash -c 'echo never > /sys/kernel/mm/transparent_hugepage/enabled'
sudo bash -c 'echo never > /sys/kernel/mm/transparent_hugepage/defrag'
① vm.overcommit_memory=1 ------ 允许内存超分
为什么 Redis 需要它: Redis 做 BGSAVE(后台保存 RDB)和 BGREWRITEAOF(AOF 重写)时,会调用 fork() 创建子进程。fork() 是写时复制------子进程理论上与父进程共享全部内存页。
#mermaid-svg-Rr1HrsvJeC66uMGu{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Rr1HrsvJeC66uMGu .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Rr1HrsvJeC66uMGu .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Rr1HrsvJeC66uMGu .error-icon{fill:#552222;}#mermaid-svg-Rr1HrsvJeC66uMGu .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Rr1HrsvJeC66uMGu .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Rr1HrsvJeC66uMGu .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Rr1HrsvJeC66uMGu .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Rr1HrsvJeC66uMGu .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Rr1HrsvJeC66uMGu .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Rr1HrsvJeC66uMGu .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Rr1HrsvJeC66uMGu .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Rr1HrsvJeC66uMGu .marker.cross{stroke:#333333;}#mermaid-svg-Rr1HrsvJeC66uMGu svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Rr1HrsvJeC66uMGu p{margin:0;}#mermaid-svg-Rr1HrsvJeC66uMGu .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Rr1HrsvJeC66uMGu .cluster-label text{fill:#333;}#mermaid-svg-Rr1HrsvJeC66uMGu .cluster-label span{color:#333;}#mermaid-svg-Rr1HrsvJeC66uMGu .cluster-label span p{background-color:transparent;}#mermaid-svg-Rr1HrsvJeC66uMGu .label text,#mermaid-svg-Rr1HrsvJeC66uMGu span{fill:#333;color:#333;}#mermaid-svg-Rr1HrsvJeC66uMGu .node rect,#mermaid-svg-Rr1HrsvJeC66uMGu .node circle,#mermaid-svg-Rr1HrsvJeC66uMGu .node ellipse,#mermaid-svg-Rr1HrsvJeC66uMGu .node polygon,#mermaid-svg-Rr1HrsvJeC66uMGu .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Rr1HrsvJeC66uMGu .rough-node .label text,#mermaid-svg-Rr1HrsvJeC66uMGu .node .label text,#mermaid-svg-Rr1HrsvJeC66uMGu .image-shape .label,#mermaid-svg-Rr1HrsvJeC66uMGu .icon-shape .label{text-anchor:middle;}#mermaid-svg-Rr1HrsvJeC66uMGu .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Rr1HrsvJeC66uMGu .rough-node .label,#mermaid-svg-Rr1HrsvJeC66uMGu .node .label,#mermaid-svg-Rr1HrsvJeC66uMGu .image-shape .label,#mermaid-svg-Rr1HrsvJeC66uMGu .icon-shape .label{text-align:center;}#mermaid-svg-Rr1HrsvJeC66uMGu .node.clickable{cursor:pointer;}#mermaid-svg-Rr1HrsvJeC66uMGu .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Rr1HrsvJeC66uMGu .arrowheadPath{fill:#333333;}#mermaid-svg-Rr1HrsvJeC66uMGu .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Rr1HrsvJeC66uMGu .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Rr1HrsvJeC66uMGu .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Rr1HrsvJeC66uMGu .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Rr1HrsvJeC66uMGu .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Rr1HrsvJeC66uMGu .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Rr1HrsvJeC66uMGu .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Rr1HrsvJeC66uMGu .cluster text{fill:#333;}#mermaid-svg-Rr1HrsvJeC66uMGu .cluster span{color:#333;}#mermaid-svg-Rr1HrsvJeC66uMGu div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Rr1HrsvJeC66uMGu .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Rr1HrsvJeC66uMGu rect.text{fill:none;stroke-width:0;}#mermaid-svg-Rr1HrsvJeC66uMGu .icon-shape,#mermaid-svg-Rr1HrsvJeC66uMGu .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Rr1HrsvJeC66uMGu .icon-shape p,#mermaid-svg-Rr1HrsvJeC66uMGu .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Rr1HrsvJeC66uMGu .icon-shape .label rect,#mermaid-svg-Rr1HrsvJeC66uMGu .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Rr1HrsvJeC66uMGu .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Rr1HrsvJeC66uMGu .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Rr1HrsvJeC66uMGu :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} fork
COW 共享内存页
写入触发复制
继续服务读写
主进程
占 2GB
子进程
新页
仅改动部分
写出 dump.rdb
客户端
问题: Linux 默认 vm.overcommit_memory=0(启发式判断),它会按父进程实际内存大小评估 fork 是否允许 。假设 Redis 占 2GB,fork 时内核保守估算「子进程可能再要 2GB」,若剩余内存不足就拒绝 fork ,导致 BGSAVE 失败、报 MISCONF 错误、Redis 拒绝写入。
设为 1 后: 内核允许「超分」,因为 COW 实际并不会真的复制全部内存,fork 几乎总能成功。
② net.core.somaxconn=1024 ------ 增大连接队列
作用: somaxconn 是内核 TCP 全连接队列(accept queue)上限。Redis 配置了 tcp-backlog 511,但内核默认 somaxconn=128 会把它截断为 128 。高并发下连接会被直接丢弃(表现为 rejected_connections 飙升)。设为 1024 让 Redis 的 backlog 真正生效。
③ 关闭 THP(Transparent Huge Pages)
作用: THP 会把 4KB 小页合并成 2MB 大页。Redis fork 时,子进程只需复制「被改动的页」;但 THP 的粒度是 2MB------只要页内有 1 字节改动,整个 2MB 都要复制,导致 fork 期间内存放大、延迟飙升(最高达秒级卡顿)。关掉它,让 COW 在 4KB 粒度精确复制。
#mermaid-svg-v2iw5esx95R9MNEM{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-v2iw5esx95R9MNEM .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-v2iw5esx95R9MNEM .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-v2iw5esx95R9MNEM .error-icon{fill:#552222;}#mermaid-svg-v2iw5esx95R9MNEM .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-v2iw5esx95R9MNEM .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-v2iw5esx95R9MNEM .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-v2iw5esx95R9MNEM .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-v2iw5esx95R9MNEM .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-v2iw5esx95R9MNEM .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-v2iw5esx95R9MNEM .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-v2iw5esx95R9MNEM .marker{fill:#333333;stroke:#333333;}#mermaid-svg-v2iw5esx95R9MNEM .marker.cross{stroke:#333333;}#mermaid-svg-v2iw5esx95R9MNEM svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-v2iw5esx95R9MNEM p{margin:0;}#mermaid-svg-v2iw5esx95R9MNEM .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-v2iw5esx95R9MNEM .cluster-label text{fill:#333;}#mermaid-svg-v2iw5esx95R9MNEM .cluster-label span{color:#333;}#mermaid-svg-v2iw5esx95R9MNEM .cluster-label span p{background-color:transparent;}#mermaid-svg-v2iw5esx95R9MNEM .label text,#mermaid-svg-v2iw5esx95R9MNEM span{fill:#333;color:#333;}#mermaid-svg-v2iw5esx95R9MNEM .node rect,#mermaid-svg-v2iw5esx95R9MNEM .node circle,#mermaid-svg-v2iw5esx95R9MNEM .node ellipse,#mermaid-svg-v2iw5esx95R9MNEM .node polygon,#mermaid-svg-v2iw5esx95R9MNEM .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-v2iw5esx95R9MNEM .rough-node .label text,#mermaid-svg-v2iw5esx95R9MNEM .node .label text,#mermaid-svg-v2iw5esx95R9MNEM .image-shape .label,#mermaid-svg-v2iw5esx95R9MNEM .icon-shape .label{text-anchor:middle;}#mermaid-svg-v2iw5esx95R9MNEM .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-v2iw5esx95R9MNEM .rough-node .label,#mermaid-svg-v2iw5esx95R9MNEM .node .label,#mermaid-svg-v2iw5esx95R9MNEM .image-shape .label,#mermaid-svg-v2iw5esx95R9MNEM .icon-shape .label{text-align:center;}#mermaid-svg-v2iw5esx95R9MNEM .node.clickable{cursor:pointer;}#mermaid-svg-v2iw5esx95R9MNEM .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-v2iw5esx95R9MNEM .arrowheadPath{fill:#333333;}#mermaid-svg-v2iw5esx95R9MNEM .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-v2iw5esx95R9MNEM .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-v2iw5esx95R9MNEM .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-v2iw5esx95R9MNEM .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-v2iw5esx95R9MNEM .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-v2iw5esx95R9MNEM .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-v2iw5esx95R9MNEM .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-v2iw5esx95R9MNEM .cluster text{fill:#333;}#mermaid-svg-v2iw5esx95R9MNEM .cluster span{color:#333;}#mermaid-svg-v2iw5esx95R9MNEM div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-v2iw5esx95R9MNEM .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-v2iw5esx95R9MNEM rect.text{fill:none;stroke-width:0;}#mermaid-svg-v2iw5esx95R9MNEM .icon-shape,#mermaid-svg-v2iw5esx95R9MNEM .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-v2iw5esx95R9MNEM .icon-shape p,#mermaid-svg-v2iw5esx95R9MNEM .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-v2iw5esx95R9MNEM .icon-shape .label rect,#mermaid-svg-v2iw5esx95R9MNEM .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-v2iw5esx95R9MNEM .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-v2iw5esx95R9MNEM .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-v2iw5esx95R9MNEM :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} THP 开启
THP 关闭
Redis 触发 BGSAVE
fork 创建子进程
COW 复制
2MB 大页复制
延迟飙升
4KB 小页复制
延迟低
主进程卡顿/请求超时
主进程几乎无感知
永久生效
sudo tee -a /etc/sysctl.conf > /dev/null <<'EOF'
vm.overcommit_memory = 1
net.core.somaxconn = 1024
EOF
| 片段 | 作用 |
|---|---|
tee -a |
追加写入文件(-a 不覆盖原内容),同时输出到屏幕(这里重定向到 /dev/null 丢弃) |
<<'EOF' ... EOF |
Here Document,多行文本块。单引号 'EOF' 表示不做变量展开 |
/etc/sysctl.conf |
内核参数持久化配置文件,重启后由 sysctl --system 自动加载 |
📌 THP 关闭命令(
echo never > ...)不在 sysctl.conf 管辖范围 ,需写入rc.local或 systemd 单元才能开机自启,否则机器重启后 THP 会重新开启。
4.4 编写 redis.conf
这是 Redis 部署的「单一事实源」。所有运行时行为都声明在这个文件里。逐段拆解:
ini
################################# 网络 #################################
bind 0.0.0.0
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
################################# 通用 #################################
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
databases 16
################################# 安全 #################################
requirepass redis123
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""
rename-command KEYS ""
################################# 内存 #################################
maxmemory 1gb
maxmemory-policy allkeys-lru
################################# 持久化(RDB) ########################
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
dbfilename dump.rdb
dir /data
################################# 持久化(AOF) ########################
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
网络段
| 配置项 | 作用 |
|---|---|
bind 0.0.0.0 |
监听所有网卡。生产建议改为内网 IP |
protected-mode yes |
保护模式:未设密码时拒绝外部访问(防裸奔) |
port 6379 |
监听端口 |
tcp-backlog 511 |
TCP 全连接队列长度。需配合内核 somaxconn≥511 才生效 |
timeout 0 |
客户端空闲不主动断开(0 = 永不) |
tcp-keepalive 300 |
每 300 秒探测客户端是否存活,及时回收死连接 |
通用段
| 配置项 | 作用 |
|---|---|
daemonize no |
容器内必须为 no 。设为 yes 会让 redis-server 后台化,导致容器内无前台进程,Docker 立即判定容器退出 |
supervised no |
不向上游进程管理器汇报状态(容器由 Docker 管) |
pidfile |
进程号文件路径(容器内基本用不到) |
loglevel notice |
日志级别:debug/verbose/notice/warning,生产用 notice |
databases 16 |
逻辑库数量,db0~db15 |
安全段
| 配置项 | 作用 |
|---|---|
requirepass redis123 |
访问密码。所有命令需先 AUTH 密码 |
rename-command FLUSHALL "" |
把 FLUSHALL(清空所有库)重命名为空串 = 禁用 |
rename-command FLUSHDB "" |
禁用 FLUSHDB(清空当前库) |
rename-command CONFIG "" |
禁用 CONFIG(在线改配置),强制走 conf 文件,防配置漂移 |
rename-command KEYS "" |
禁用 KEYS(全库扫描,会阻塞),用 SCAN 替代 |
💡 禁用 CONFIG 的代价 :所有运行时配置变更必须改
redis.conf后docker compose restart。换来的是配置可版本化、不会被线上随手改坏。
内存段(Redis 工程化核心)
| 配置项 | 作用 |
|---|---|
maxmemory 1gb |
内存使用硬上限。达到后触发淘汰策略 |
maxmemory-policy allkeys-lru |
淘汰策略:所有 key 中淘汰最近最少使用的 |
常见淘汰策略对比:
| 策略 | 含义 | 适用场景 |
|---|---|---|
noeviction |
不淘汰,写操作直接报错 | 当数据库用,绝不能丢数据 |
allkeys-lru |
所有 key 按 LRU 淘汰 | 纯缓存(推荐) |
volatile-lru |
仅设了过期的 key 按 LRU 淘汰 | 混合(部分缓存部分持久) |
allkeys-random |
随机淘汰 | 无访问热点 |
volatile-ttl |
优先淘汰快过期的 | 知道 TTL 分布时 |
📌 不设 maxmemory 会怎样:Redis 内存无上限增长,最终触发 Linux OOM Killer------内核随机杀进程,可能杀掉 Redis 也可能杀掉其他关键服务。工程化部署必须设硬上限。
持久化段 ------ RDB 与 AOF 双开
#mermaid-svg-QX4Szhi00WcEaSr7{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-QX4Szhi00WcEaSr7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QX4Szhi00WcEaSr7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QX4Szhi00WcEaSr7 .error-icon{fill:#552222;}#mermaid-svg-QX4Szhi00WcEaSr7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QX4Szhi00WcEaSr7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QX4Szhi00WcEaSr7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QX4Szhi00WcEaSr7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QX4Szhi00WcEaSr7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QX4Szhi00WcEaSr7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QX4Szhi00WcEaSr7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QX4Szhi00WcEaSr7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QX4Szhi00WcEaSr7 .marker.cross{stroke:#333333;}#mermaid-svg-QX4Szhi00WcEaSr7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QX4Szhi00WcEaSr7 p{margin:0;}#mermaid-svg-QX4Szhi00WcEaSr7 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-QX4Szhi00WcEaSr7 .cluster-label text{fill:#333;}#mermaid-svg-QX4Szhi00WcEaSr7 .cluster-label span{color:#333;}#mermaid-svg-QX4Szhi00WcEaSr7 .cluster-label span p{background-color:transparent;}#mermaid-svg-QX4Szhi00WcEaSr7 .label text,#mermaid-svg-QX4Szhi00WcEaSr7 span{fill:#333;color:#333;}#mermaid-svg-QX4Szhi00WcEaSr7 .node rect,#mermaid-svg-QX4Szhi00WcEaSr7 .node circle,#mermaid-svg-QX4Szhi00WcEaSr7 .node ellipse,#mermaid-svg-QX4Szhi00WcEaSr7 .node polygon,#mermaid-svg-QX4Szhi00WcEaSr7 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QX4Szhi00WcEaSr7 .rough-node .label text,#mermaid-svg-QX4Szhi00WcEaSr7 .node .label text,#mermaid-svg-QX4Szhi00WcEaSr7 .image-shape .label,#mermaid-svg-QX4Szhi00WcEaSr7 .icon-shape .label{text-anchor:middle;}#mermaid-svg-QX4Szhi00WcEaSr7 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-QX4Szhi00WcEaSr7 .rough-node .label,#mermaid-svg-QX4Szhi00WcEaSr7 .node .label,#mermaid-svg-QX4Szhi00WcEaSr7 .image-shape .label,#mermaid-svg-QX4Szhi00WcEaSr7 .icon-shape .label{text-align:center;}#mermaid-svg-QX4Szhi00WcEaSr7 .node.clickable{cursor:pointer;}#mermaid-svg-QX4Szhi00WcEaSr7 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-QX4Szhi00WcEaSr7 .arrowheadPath{fill:#333333;}#mermaid-svg-QX4Szhi00WcEaSr7 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-QX4Szhi00WcEaSr7 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-QX4Szhi00WcEaSr7 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QX4Szhi00WcEaSr7 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-QX4Szhi00WcEaSr7 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QX4Szhi00WcEaSr7 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-QX4Szhi00WcEaSr7 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QX4Szhi00WcEaSr7 .cluster text{fill:#333;}#mermaid-svg-QX4Szhi00WcEaSr7 .cluster span{color:#333;}#mermaid-svg-QX4Szhi00WcEaSr7 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-QX4Szhi00WcEaSr7 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-QX4Szhi00WcEaSr7 rect.text{fill:none;stroke-width:0;}#mermaid-svg-QX4Szhi00WcEaSr7 .icon-shape,#mermaid-svg-QX4Szhi00WcEaSr7 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QX4Szhi00WcEaSr7 .icon-shape p,#mermaid-svg-QX4Szhi00WcEaSr7 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-QX4Szhi00WcEaSr7 .icon-shape .label rect,#mermaid-svg-QX4Szhi00WcEaSr7 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QX4Szhi00WcEaSr7 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-QX4Szhi00WcEaSr7 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-QX4Szhi00WcEaSr7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 追加日志持久化 AOF
always
everysec
no
每条写命令
追加到 appendonly.aof
appendfsync
每条刷盘 最安全最慢
每秒刷盘 推荐
交由OS 30秒刷一次
数据完整、最多丢 1 秒
文件膨胀 → 自动 rewrite
基于当前内存状态重写
快照持久化 RDB
满足 save 规则
如 900s/1变
BGSAVE fork 子进程
写出 dump.rdb
二进制紧凑
恢复快、文件小
但可能丢最近写入
RDB 配置解析:
| 配置项 | 作用 |
|---|---|
save 900 1 |
900 秒内至少 1 个 key 变化 → 触发快照 |
save 300 10 |
300 秒内至少 10 个 key 变化 → 触发快照 |
save 60 10000 |
60 秒内至少 10000 个 key 变化 → 触发快照 |
stop-writes-on-bgsave-error yes |
BGSAVE 失败时拒绝写入(提示运维持久化已坏) |
rdbcompression yes |
RDB 文件用 LZF 压缩,节省空间 |
dbfilename dump.rdb |
RDB 文件名 |
dir /data |
数据目录(容器内,与挂载点对应) |
AOF 配置解析:
| 配置项 | 作用 |
|---|---|
appendonly yes |
开启 AOF(默认 no) |
appendfilename "appendonly.aof" |
AOF 文件名 |
appendfsync everysec |
每秒刷盘一次,兼顾性能与安全(最多丢 1 秒数据) |
auto-aof-rewrite-percentage 100 |
AOF 文件比上次重写后大 100% 时触发重写 |
auto-aof-rewrite-min-size 64mb |
AOF 达到 64MB 才允许触发重写 |
📌 为什么 RDB + AOF 双开:RDB 提供快速重启恢复(分钟级拉起大库),AOF 提供数据完整性(最多丢 1 秒)。两者互补,是 Redis 生产持久化的推荐组合。
4.5 授权目录属主
sudo chown -R 999:999 /opt/redis/data /opt/redis/conf /opt/redis/logs
这两行解决两个完全不同的问题:① 数据持久化 ② UID 不一致。
① mkdir ------ 数据持久化(容器与数据分离)
#mermaid-svg-XVhZr7GJO26zOE6h{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-XVhZr7GJO26zOE6h .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-XVhZr7GJO26zOE6h .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-XVhZr7GJO26zOE6h .error-icon{fill:#552222;}#mermaid-svg-XVhZr7GJO26zOE6h .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-XVhZr7GJO26zOE6h .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-XVhZr7GJO26zOE6h .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-XVhZr7GJO26zOE6h .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-XVhZr7GJO26zOE6h .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-XVhZr7GJO26zOE6h .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-XVhZr7GJO26zOE6h .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-XVhZr7GJO26zOE6h .marker{fill:#333333;stroke:#333333;}#mermaid-svg-XVhZr7GJO26zOE6h .marker.cross{stroke:#333333;}#mermaid-svg-XVhZr7GJO26zOE6h svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-XVhZr7GJO26zOE6h p{margin:0;}#mermaid-svg-XVhZr7GJO26zOE6h .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-XVhZr7GJO26zOE6h .cluster-label text{fill:#333;}#mermaid-svg-XVhZr7GJO26zOE6h .cluster-label span{color:#333;}#mermaid-svg-XVhZr7GJO26zOE6h .cluster-label span p{background-color:transparent;}#mermaid-svg-XVhZr7GJO26zOE6h .label text,#mermaid-svg-XVhZr7GJO26zOE6h span{fill:#333;color:#333;}#mermaid-svg-XVhZr7GJO26zOE6h .node rect,#mermaid-svg-XVhZr7GJO26zOE6h .node circle,#mermaid-svg-XVhZr7GJO26zOE6h .node ellipse,#mermaid-svg-XVhZr7GJO26zOE6h .node polygon,#mermaid-svg-XVhZr7GJO26zOE6h .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-XVhZr7GJO26zOE6h .rough-node .label text,#mermaid-svg-XVhZr7GJO26zOE6h .node .label text,#mermaid-svg-XVhZr7GJO26zOE6h .image-shape .label,#mermaid-svg-XVhZr7GJO26zOE6h .icon-shape .label{text-anchor:middle;}#mermaid-svg-XVhZr7GJO26zOE6h .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-XVhZr7GJO26zOE6h .rough-node .label,#mermaid-svg-XVhZr7GJO26zOE6h .node .label,#mermaid-svg-XVhZr7GJO26zOE6h .image-shape .label,#mermaid-svg-XVhZr7GJO26zOE6h .icon-shape .label{text-align:center;}#mermaid-svg-XVhZr7GJO26zOE6h .node.clickable{cursor:pointer;}#mermaid-svg-XVhZr7GJO26zOE6h .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-XVhZr7GJO26zOE6h .arrowheadPath{fill:#333333;}#mermaid-svg-XVhZr7GJO26zOE6h .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-XVhZr7GJO26zOE6h .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-XVhZr7GJO26zOE6h .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-XVhZr7GJO26zOE6h .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-XVhZr7GJO26zOE6h .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-XVhZr7GJO26zOE6h .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-XVhZr7GJO26zOE6h .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-XVhZr7GJO26zOE6h .cluster text{fill:#333;}#mermaid-svg-XVhZr7GJO26zOE6h .cluster span{color:#333;}#mermaid-svg-XVhZr7GJO26zOE6h div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-XVhZr7GJO26zOE6h .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-XVhZr7GJO26zOE6h rect.text{fill:none;stroke-width:0;}#mermaid-svg-XVhZr7GJO26zOE6h .icon-shape,#mermaid-svg-XVhZr7GJO26zOE6h .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-XVhZr7GJO26zOE6h .icon-shape p,#mermaid-svg-XVhZr7GJO26zOE6h .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-XVhZr7GJO26zOE6h .icon-shape .label rect,#mermaid-svg-XVhZr7GJO26zOE6h .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-XVhZr7GJO26zOE6h .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-XVhZr7GJO26zOE6h .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-XVhZr7GJO26zOE6h :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 容器
宿主机
bind mount 双向同步
读写 RDB/AOF
/opt/redis/data
/data
redis-server 进程
效果: 容器内 Redis 读写的数据,实际落在宿主机 /opt/redis/data。即使容器被 docker compose down 删除,数据完整保留。重新 up -d 挂载同一目录即恢复。
② chown ------ 解决容器内外 UID 不一致
| 角色 | UID:GID | 说明 |
|---|---|---|
宿主机 sudo mkdir 创建的目录 |
0:0(root) |
sudo 以 root 执行,属主是 root |
| 容器内 Redis 进程 | 999:999 |
官方镜像安全最佳实践:非 root 运行,用专用用户 redis(UID 999) |
冲突场景: 容器内 redis 用户(999)对 root 属主的目录无写权限 → 启动时报 Can't open or create append-only dir 或写 RDB 失败。
| 参数 | 作用 |
|---|---|
chown |
change owner,修改属主 |
-R |
递归处理所有子目录和文件 |
999:999 |
官方 redis 镜像内 redis 用户的固定 UID:GID |
常见官方镜像固定 UID 速查:
| 镜像 | 内部用户 | UID |
|---|---|---|
redis |
redis | 999 |
postgres |
postgres | 999 |
mysql |
mysql | 999 |
nginx |
nginx | 101 |
elasticsearch |
elasticsearch | 1000 |
4.6 编写 docker-compose.yml
yaml
services:
redis:
image: redis:7.2
container_name: redis_server
restart: unless-stopped
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
ports:
- "6379:6379"
volumes:
- /opt/redis/data:/data
- /opt/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf
- /opt/redis/logs:/logs
environment:
TZ: Asia/Shanghai
deploy:
resources:
limits:
cpus: '2.0'
memory: 2G
healthcheck:
test: ["CMD", "redis-cli", "-a", "redis123", "ping"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
逐字段深度解析:
image: redis:7.2
指定镜像名:标签。本地没有则 Compose 自动拉取。
container_name: redis_server
固定容器名。不指定时 Docker 自动生成 目录名-服务名-序号(如 redis-redis-1),难记忆。固定后所有 docker exec、docker logs 都能直接用这个名字。
restart: unless-stopped
| 值 | 行为 |
|---|---|
no |
退出后不重启(默认) |
always |
总是重启,即使手动 stop 在 Docker 重启时也会被拉起 |
unless-stopped |
宕机/异常退出自动重启;手动 stop 后不被拉起 |
on-failure |
仅非零退出码时重启 |
选 unless-stopped 的原因: 既保证 Redis 崩溃后自动恢复,又不会在你主动维护(手动 stop)时被意外拉起。
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
| 片段 | 作用 |
|---|---|
redis-server |
Redis 服务端可执行文件 |
/usr/local/etc/redis/redis.conf |
关键:通过参数告诉 redis-server 读取我们挂载的配置文件 |
💡 这一行是「配置文件化」的核心 。不写
command,镜像默认执行redis-server(裸跑,全用默认值,无密码、无持久化)。写了这一行,Redis 才会读redis.conf,所有自定义配置生效。
ports: "6379:6379"
| 片段 | 含义 |
|---|---|
左 6379 |
宿主机端口 |
右 6379 |
容器内端口 |
原理: 容器有独立网络命名空间,外部无法直接访问。ports 在宿主机创建端口转发规则。改为 "127.0.0.1:6379:6379" 则仅本机可连。
volumes:
#mermaid-svg-bDz0PMyGm17gfqwN{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-bDz0PMyGm17gfqwN .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-bDz0PMyGm17gfqwN .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-bDz0PMyGm17gfqwN .error-icon{fill:#552222;}#mermaid-svg-bDz0PMyGm17gfqwN .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-bDz0PMyGm17gfqwN .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-bDz0PMyGm17gfqwN .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-bDz0PMyGm17gfqwN .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-bDz0PMyGm17gfqwN .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-bDz0PMyGm17gfqwN .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-bDz0PMyGm17gfqwN .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-bDz0PMyGm17gfqwN .marker{fill:#333333;stroke:#333333;}#mermaid-svg-bDz0PMyGm17gfqwN .marker.cross{stroke:#333333;}#mermaid-svg-bDz0PMyGm17gfqwN svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-bDz0PMyGm17gfqwN p{margin:0;}#mermaid-svg-bDz0PMyGm17gfqwN .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-bDz0PMyGm17gfqwN .cluster-label text{fill:#333;}#mermaid-svg-bDz0PMyGm17gfqwN .cluster-label span{color:#333;}#mermaid-svg-bDz0PMyGm17gfqwN .cluster-label span p{background-color:transparent;}#mermaid-svg-bDz0PMyGm17gfqwN .label text,#mermaid-svg-bDz0PMyGm17gfqwN span{fill:#333;color:#333;}#mermaid-svg-bDz0PMyGm17gfqwN .node rect,#mermaid-svg-bDz0PMyGm17gfqwN .node circle,#mermaid-svg-bDz0PMyGm17gfqwN .node ellipse,#mermaid-svg-bDz0PMyGm17gfqwN .node polygon,#mermaid-svg-bDz0PMyGm17gfqwN .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-bDz0PMyGm17gfqwN .rough-node .label text,#mermaid-svg-bDz0PMyGm17gfqwN .node .label text,#mermaid-svg-bDz0PMyGm17gfqwN .image-shape .label,#mermaid-svg-bDz0PMyGm17gfqwN .icon-shape .label{text-anchor:middle;}#mermaid-svg-bDz0PMyGm17gfqwN .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-bDz0PMyGm17gfqwN .rough-node .label,#mermaid-svg-bDz0PMyGm17gfqwN .node .label,#mermaid-svg-bDz0PMyGm17gfqwN .image-shape .label,#mermaid-svg-bDz0PMyGm17gfqwN .icon-shape .label{text-align:center;}#mermaid-svg-bDz0PMyGm17gfqwN .node.clickable{cursor:pointer;}#mermaid-svg-bDz0PMyGm17gfqwN .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-bDz0PMyGm17gfqwN .arrowheadPath{fill:#333333;}#mermaid-svg-bDz0PMyGm17gfqwN .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-bDz0PMyGm17gfqwN .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-bDz0PMyGm17gfqwN .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-bDz0PMyGm17gfqwN .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-bDz0PMyGm17gfqwN .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-bDz0PMyGm17gfqwN .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-bDz0PMyGm17gfqwN .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-bDz0PMyGm17gfqwN .cluster text{fill:#333;}#mermaid-svg-bDz0PMyGm17gfqwN .cluster span{color:#333;}#mermaid-svg-bDz0PMyGm17gfqwN div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-bDz0PMyGm17gfqwN .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-bDz0PMyGm17gfqwN rect.text{fill:none;stroke-width:0;}#mermaid-svg-bDz0PMyGm17gfqwN .icon-shape,#mermaid-svg-bDz0PMyGm17gfqwN .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-bDz0PMyGm17gfqwN .icon-shape p,#mermaid-svg-bDz0PMyGm17gfqwN .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-bDz0PMyGm17gfqwN .icon-shape .label rect,#mermaid-svg-bDz0PMyGm17gfqwN .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-bDz0PMyGm17gfqwN .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-bDz0PMyGm17gfqwN .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-bDz0PMyGm17gfqwN :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 挂载
挂载
挂载
/opt/redis/data
/data
RDB+AOF 落盘
/opt/redis/conf/redis.conf
/usr/local/etc/redis/redis.conf
/opt/redis/logs
/logs
⚠️ 注意 :挂载单个文件 (如
redis.conf)时,宿主机该文件必须事先存在 。如果不存在,Docker 会把它当成目录创建,导致容器内挂载点变成空目录,redis-server 启动报错。所以必须先vim redis.conf写好内容再up。
environment: TZ: Asia/Shanghai
设置容器时区,影响 Redis 日志时间戳和 TIME 命令返回值。
deploy: resources: limits:
| 字段 | 作用 |
|---|---|
limits.cpus: '2.0' |
限制最多用 2 个 CPU 核心 |
limits.memory: 2G |
限制最多用 2GB 内存 |
原理: 通过 Linux cgroup 限制资源上限。防止 Redis 异常(如大 key、误操作)吃光宿主机内存,导致其他服务被 OOM Killer 杀掉。
📌 memory 2G 与 maxmemory 1gb 的关系 :
maxmemory是 Redis 应用层上限(1GB,超了淘汰 key),deploy.memory是容器层上限(2G,含 Redis 进程本身、AOF 缓冲、fork 时 COW 临时内存)。容器上限必须 > maxmemory,给 fork 和缓冲留空间,否则 fork 时容器被 cgroup 杀掉。
healthcheck:
| 字段 | 作用 |
|---|---|
test |
健康检查命令。redis-cli -a redis123 ping,返回 PONG 视为健康 |
interval: 30s |
每 30 秒检查一次 |
timeout: 5s |
单次超时 5 秒 |
retries: 3 |
连续 3 次失败标记 unhealthy |
start_period: 10s |
启动后 10 秒内失败不计入(Redis 启动极快,10 秒够) |
没有 healthcheck 会怎样: Docker 只能判断进程存活(Up),无法判断 Redis 是否真正可接受命令。进程活着但持久化卡死时------这就是「假活」。healthcheck 解决这个问题。
logging:
| 字段 | 作用 |
|---|---|
driver: json-file |
日志以 JSON 写入文件(Docker 默认) |
max-size: "10m" |
单文件最大 10MB |
max-file: "3" |
最多保留 3 个文件 |
原理: Docker 默认无限增长日志(存 /var/lib/docker/containers/<id>/),不做轮转会撑满磁盘。配置后:json.log → json.log.1 → json.log.2 → 删最旧,总上限 30MB。
4.7 启动服务
sudo docker compose up -d # 后台创建并启动
sudo docker compose ps # 查看状态
sudo docker compose logs -f redis # 实时日志
| 命令 | 作用 |
|---|---|
up -d |
根据当前 docker-compose.yml 创建并启动容器,-d 后台运行。幂等:配置没变什么也不做,变了重建受影响容器 |
ps |
列出当前 compose 项目所有服务状态 |
logs -f |
-f follow,持续跟踪新输出(类似 tail -f) |
重点看 STATUS 列:
| 状态值 | 含义 | 是否可继续 |
|---|---|---|
Up |
已启动,healthcheck 未完成 | 等待 |
Up (healthy) |
健康检查通过,可接受命令 | ✅ |
Up (unhealthy) |
健康检查连续失败 | ❌ 排查 |
Exited (1) |
启动失败(权限/端口/配置) | ❌ 排查 |
Restarting |
反复重启 | ❌ 排查 |
4.8 验证服务可用
sudo docker exec -it redis_server redis-cli -a redis123 ping
逐参数解析:
| 片段 | 作用 |
|---|---|
docker exec |
在运行中 容器内执行命令(区别于 run 启动新容器) |
-i |
--interactive,保持标准输入开启 |
-t |
--tty,分配伪终端 |
redis_server |
目标容器名 |
redis-cli |
Redis 命令行客户端 |
-a redis123 |
提供密码(等价于先执行 AUTH redis123) |
ping |
向 Redis 发送 PING,正常返回 PONG |
💡 关于
sudo:若已通过sudo -i切到 root(提示符#),所有命令前的sudo可去掉。判断方法------提示符末尾$是普通用户(要加 sudo),#是 root(不用加)。
返回 PONG 即正常。
⚠️ 安全提醒(务必阅读)
bind 0.0.0.0+ 弱密码redis123在公网极危险。历史上大量 Redis 被植入挖矿脚本,根本原因即此。生产务必强密码 + bind 收紧内网。- 6379 端口不要直接暴露公网,用防火墙/安全组限制来源 IP。
- 禁用
CONFIG后,配置变更只能改redis.conf后docker compose restart,防线上被任意改配置。- 应用代码不要硬编码密码,用环境变量或配置中心注入。
五、第五章「常用管理命令」逐条解析
以下命令均在
/opt/redis/目录下执行。
5.1 ~ 5.9 容器管理命令
#mermaid-svg-ETd7gf4y7pcEz7xE{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ETd7gf4y7pcEz7xE .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ETd7gf4y7pcEz7xE .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ETd7gf4y7pcEz7xE .error-icon{fill:#552222;}#mermaid-svg-ETd7gf4y7pcEz7xE .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ETd7gf4y7pcEz7xE .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ETd7gf4y7pcEz7xE .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ETd7gf4y7pcEz7xE .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ETd7gf4y7pcEz7xE .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ETd7gf4y7pcEz7xE .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ETd7gf4y7pcEz7xE .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ETd7gf4y7pcEz7xE .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ETd7gf4y7pcEz7xE .marker.cross{stroke:#333333;}#mermaid-svg-ETd7gf4y7pcEz7xE svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ETd7gf4y7pcEz7xE p{margin:0;}#mermaid-svg-ETd7gf4y7pcEz7xE .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ETd7gf4y7pcEz7xE .cluster-label text{fill:#333;}#mermaid-svg-ETd7gf4y7pcEz7xE .cluster-label span{color:#333;}#mermaid-svg-ETd7gf4y7pcEz7xE .cluster-label span p{background-color:transparent;}#mermaid-svg-ETd7gf4y7pcEz7xE .label text,#mermaid-svg-ETd7gf4y7pcEz7xE span{fill:#333;color:#333;}#mermaid-svg-ETd7gf4y7pcEz7xE .node rect,#mermaid-svg-ETd7gf4y7pcEz7xE .node circle,#mermaid-svg-ETd7gf4y7pcEz7xE .node ellipse,#mermaid-svg-ETd7gf4y7pcEz7xE .node polygon,#mermaid-svg-ETd7gf4y7pcEz7xE .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ETd7gf4y7pcEz7xE .rough-node .label text,#mermaid-svg-ETd7gf4y7pcEz7xE .node .label text,#mermaid-svg-ETd7gf4y7pcEz7xE .image-shape .label,#mermaid-svg-ETd7gf4y7pcEz7xE .icon-shape .label{text-anchor:middle;}#mermaid-svg-ETd7gf4y7pcEz7xE .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ETd7gf4y7pcEz7xE .rough-node .label,#mermaid-svg-ETd7gf4y7pcEz7xE .node .label,#mermaid-svg-ETd7gf4y7pcEz7xE .image-shape .label,#mermaid-svg-ETd7gf4y7pcEz7xE .icon-shape .label{text-align:center;}#mermaid-svg-ETd7gf4y7pcEz7xE .node.clickable{cursor:pointer;}#mermaid-svg-ETd7gf4y7pcEz7xE .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ETd7gf4y7pcEz7xE .arrowheadPath{fill:#333333;}#mermaid-svg-ETd7gf4y7pcEz7xE .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ETd7gf4y7pcEz7xE .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ETd7gf4y7pcEz7xE .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ETd7gf4y7pcEz7xE .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ETd7gf4y7pcEz7xE .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ETd7gf4y7pcEz7xE .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ETd7gf4y7pcEz7xE .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ETd7gf4y7pcEz7xE .cluster text{fill:#333;}#mermaid-svg-ETd7gf4y7pcEz7xE .cluster span{color:#333;}#mermaid-svg-ETd7gf4y7pcEz7xE div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ETd7gf4y7pcEz7xE .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ETd7gf4y7pcEz7xE rect.text{fill:none;stroke-width:0;}#mermaid-svg-ETd7gf4y7pcEz7xE .icon-shape,#mermaid-svg-ETd7gf4y7pcEz7xE .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ETd7gf4y7pcEz7xE .icon-shape p,#mermaid-svg-ETd7gf4y7pcEz7xE .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ETd7gf4y7pcEz7xE .icon-shape .label rect,#mermaid-svg-ETd7gf4y7pcEz7xE .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ETd7gf4y7pcEz7xE .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ETd7gf4y7pcEz7xE .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ETd7gf4y7pcEz7xE :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} up -d
创建+启动
运行中
stop
停止不删
Exited
数据保留
start
重新启动
restart
重启进程
down
停止+删除容器
| 命令 | 容器 | 数据 |
|---|---|---|
stop |
停止,不删除 | 保留 |
start |
启动已停止的 | 保留 |
restart |
重启进程 | 保留 |
down |
停止并删除 | 保留(在宿主机目录) |
up -d |
创建并启动(幂等) | 保留 |
ps / logs:
sudo docker compose ps # 状态
sudo docker compose logs -f redis # 实时日志
进入容器:
sudo docker exec -it redis_server redis-cli -a redis123 # 进 redis-cli
sudo docker exec -it redis_server bash # 进 shell
| 进入方式 | 用途 |
|---|---|
redis-cli |
直接进入 Redis 命令行,执行数据操作 |
bash |
进入容器操作系统 shell,执行 ls/cat/ps 等深度排查 |
redis-cli 内常用命令解析
| 命令 | 作用 |
|---|---|
INFO |
查看服务综合信息(内存、连接、持久化、CPU)。最重要的运维命令 |
DBSIZE |
当前库 key 数量 |
MEMORY USAGE <key> |
查看单个 key 占用内存(定位大 key) |
CLIENT LIST |
列出当前所有连接的客户端 |
SLOWLOG GET 10 |
查看最近 10 条慢查询(超过 10ms 的命令) |
📌
CONFIG GET已被禁用 :因为我们在 conf 里rename-command CONFIG ""。运行时查/改配置必须进 conf 文件,这正是安全加固的代价与收益。
六、第六章「验证连接」逐条解析
6.1 服务器本地验证
sudo docker exec -it redis_server redis-cli -a redis123
已在 4.8 详解。容器内零依赖验证------不依赖网络、IP、防火墙。这一步通过即证明 Redis 本身正常,后续「连不上」可缩小到网络层排查。
6.2 Windows 本地连接(Python 测试)
安装依赖
pip install redis
| 片段 | 作用 |
|---|---|
redis |
Python 的 Redis 客户端库(推荐用官方 redis-py,支持集群/哨兵/async) |
Python 测试脚本
python
# test01.py
import redis
try:
r = redis.Redis(
host="192.168.1.128",
port=6379,
password="redis123",
decode_responses=True,
)
r.set("hello", "redis-world")
print("连接成功!hello =", r.get("hello"))
print("Redis 版本:", r.info()["redis_version"])
except Exception as e:
print("连接失败:", e)
finally:
r.close()
逐行解析:
| 行 | 代码 | 作用 |
|---|---|---|
| 3 | import redis |
导入 redis-py 驱动 |
| 5 | try: |
异常捕获块。网络连接可能失败,必须 try-except |
| 6 | r = redis.Redis(...) |
创建客户端连接对象 |
| 7 | host="192.168.1.128" |
服务器 IP。⚠️ 替换为你的实际 IP |
| 8 | port=6379 |
端口,与 compose 映射一致 |
| 9 | password="redis123" |
密码,与 conf 的 requirepass 一致 |
| 10 | decode_responses=True |
返回值自动解码为 str(默认 bytes) |
| 12 | r.set("hello", "redis-world") |
写入一个 key |
| 13 | r.get("hello") |
读取并打印 |
| 14 | r.info()["redis_version"] |
调用 INFO 命令取版本 |
| 17 | r.close() |
关闭连接释放资源 |
连接验证流程:
#mermaid-svg-711Vo3noXueboUVQ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-711Vo3noXueboUVQ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-711Vo3noXueboUVQ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-711Vo3noXueboUVQ .error-icon{fill:#552222;}#mermaid-svg-711Vo3noXueboUVQ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-711Vo3noXueboUVQ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-711Vo3noXueboUVQ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-711Vo3noXueboUVQ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-711Vo3noXueboUVQ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-711Vo3noXueboUVQ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-711Vo3noXueboUVQ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-711Vo3noXueboUVQ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-711Vo3noXueboUVQ .marker.cross{stroke:#333333;}#mermaid-svg-711Vo3noXueboUVQ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-711Vo3noXueboUVQ p{margin:0;}#mermaid-svg-711Vo3noXueboUVQ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-711Vo3noXueboUVQ .cluster-label text{fill:#333;}#mermaid-svg-711Vo3noXueboUVQ .cluster-label span{color:#333;}#mermaid-svg-711Vo3noXueboUVQ .cluster-label span p{background-color:transparent;}#mermaid-svg-711Vo3noXueboUVQ .label text,#mermaid-svg-711Vo3noXueboUVQ span{fill:#333;color:#333;}#mermaid-svg-711Vo3noXueboUVQ .node rect,#mermaid-svg-711Vo3noXueboUVQ .node circle,#mermaid-svg-711Vo3noXueboUVQ .node ellipse,#mermaid-svg-711Vo3noXueboUVQ .node polygon,#mermaid-svg-711Vo3noXueboUVQ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-711Vo3noXueboUVQ .rough-node .label text,#mermaid-svg-711Vo3noXueboUVQ .node .label text,#mermaid-svg-711Vo3noXueboUVQ .image-shape .label,#mermaid-svg-711Vo3noXueboUVQ .icon-shape .label{text-anchor:middle;}#mermaid-svg-711Vo3noXueboUVQ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-711Vo3noXueboUVQ .rough-node .label,#mermaid-svg-711Vo3noXueboUVQ .node .label,#mermaid-svg-711Vo3noXueboUVQ .image-shape .label,#mermaid-svg-711Vo3noXueboUVQ .icon-shape .label{text-align:center;}#mermaid-svg-711Vo3noXueboUVQ .node.clickable{cursor:pointer;}#mermaid-svg-711Vo3noXueboUVQ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-711Vo3noXueboUVQ .arrowheadPath{fill:#333333;}#mermaid-svg-711Vo3noXueboUVQ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-711Vo3noXueboUVQ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-711Vo3noXueboUVQ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-711Vo3noXueboUVQ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-711Vo3noXueboUVQ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-711Vo3noXueboUVQ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-711Vo3noXueboUVQ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-711Vo3noXueboUVQ .cluster text{fill:#333;}#mermaid-svg-711Vo3noXueboUVQ .cluster span{color:#333;}#mermaid-svg-711Vo3noXueboUVQ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-711Vo3noXueboUVQ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-711Vo3noXueboUVQ rect.text{fill:none;stroke-width:0;}#mermaid-svg-711Vo3noXueboUVQ .icon-shape,#mermaid-svg-711Vo3noXueboUVQ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-711Vo3noXueboUVQ .icon-shape p,#mermaid-svg-711Vo3noXueboUVQ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-711Vo3noXueboUVQ .icon-shape .label rect,#mermaid-svg-711Vo3noXueboUVQ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-711Vo3noXueboUVQ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-711Vo3noXueboUVQ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-711Vo3noXueboUVQ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} TCP 握手
AUTH redis123
成功
失败
Python 脚本
宿主机 6379
redis_server 容器
认证
SET hello
GET hello
返回 redis-world
连接失败: NOAUTH
⚠️ 注意 :请将
192.168.1.128替换为您自己的服务器 IP 地址。
七、第七章「备份与恢复」逐条解析
Redis 的备份有两条路:RDB 快照 与 AOF 文件 ,都在
/opt/redis/data。没有备份等于裸奔。
7.1 手动备份
sudo docker exec redis_server redis-cli -a redis123 BGSAVE
sudo cp /opt/redis/data/dump.rdb /opt/redis/backup/dump_$(date +%F).rdb
sudo cp /opt/redis/data/appendonly.aof /opt/redis/backup/appendonly_$(date +%F).aof 2>/dev/null
命令 1:BGSAVE
| 片段 | 作用 |
|---|---|
BGSAVE |
后台保存。fork 子进程写 RDB,主进程不阻塞,可继续服务 |
BGSAVE 与 SAVE 的区别:
| 命令 | 行为 | 影响 |
|---|---|---|
SAVE |
主进程同步写 RDB | 阻塞所有客户端,生产禁用 |
BGSAVE |
fork 子进程后台写 | 主进程几乎无感知,推荐 |
命令 2/3:cp
| 片段 | 作用 |
|---|---|
cp |
拷贝文件到备份目录 |
$(date +%F) |
命令替换,生成当前日期如 2026-07-03 |
2>/dev/null |
把报错丢弃(AOF 可能因 multi-part 格式不是单文件,避免噪音) |
📌 务必先 BGSAVE 再拷贝 :否则拷到的是上一次自动快照,可能丢最近写入。BGSAVE 是异步的,需
sleep 30等其完成再拷。
7.2 定时备份(crontab)
30 2 * * * docker exec redis_server redis-cli -a redis123 BGSAVE && sleep 30 && cp /opt/redis/data/dump.rdb /opt/redis/backup/dump_$(date +\%F).rdb && find /opt/redis/backup -name "dump_*.rdb" -mtime +14 -delete
cron 表达式:
#mermaid-svg-aceVV88hdN4yykCB{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-aceVV88hdN4yykCB .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-aceVV88hdN4yykCB .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-aceVV88hdN4yykCB .error-icon{fill:#552222;}#mermaid-svg-aceVV88hdN4yykCB .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-aceVV88hdN4yykCB .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-aceVV88hdN4yykCB .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-aceVV88hdN4yykCB .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-aceVV88hdN4yykCB .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-aceVV88hdN4yykCB .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-aceVV88hdN4yykCB .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-aceVV88hdN4yykCB .marker{fill:#333333;stroke:#333333;}#mermaid-svg-aceVV88hdN4yykCB .marker.cross{stroke:#333333;}#mermaid-svg-aceVV88hdN4yykCB svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-aceVV88hdN4yykCB p{margin:0;}#mermaid-svg-aceVV88hdN4yykCB .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-aceVV88hdN4yykCB .cluster-label text{fill:#333;}#mermaid-svg-aceVV88hdN4yykCB .cluster-label span{color:#333;}#mermaid-svg-aceVV88hdN4yykCB .cluster-label span p{background-color:transparent;}#mermaid-svg-aceVV88hdN4yykCB .label text,#mermaid-svg-aceVV88hdN4yykCB span{fill:#333;color:#333;}#mermaid-svg-aceVV88hdN4yykCB .node rect,#mermaid-svg-aceVV88hdN4yykCB .node circle,#mermaid-svg-aceVV88hdN4yykCB .node ellipse,#mermaid-svg-aceVV88hdN4yykCB .node polygon,#mermaid-svg-aceVV88hdN4yykCB .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-aceVV88hdN4yykCB .rough-node .label text,#mermaid-svg-aceVV88hdN4yykCB .node .label text,#mermaid-svg-aceVV88hdN4yykCB .image-shape .label,#mermaid-svg-aceVV88hdN4yykCB .icon-shape .label{text-anchor:middle;}#mermaid-svg-aceVV88hdN4yykCB .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-aceVV88hdN4yykCB .rough-node .label,#mermaid-svg-aceVV88hdN4yykCB .node .label,#mermaid-svg-aceVV88hdN4yykCB .image-shape .label,#mermaid-svg-aceVV88hdN4yykCB .icon-shape .label{text-align:center;}#mermaid-svg-aceVV88hdN4yykCB .node.clickable{cursor:pointer;}#mermaid-svg-aceVV88hdN4yykCB .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-aceVV88hdN4yykCB .arrowheadPath{fill:#333333;}#mermaid-svg-aceVV88hdN4yykCB .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-aceVV88hdN4yykCB .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-aceVV88hdN4yykCB .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aceVV88hdN4yykCB .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-aceVV88hdN4yykCB .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aceVV88hdN4yykCB .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-aceVV88hdN4yykCB .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-aceVV88hdN4yykCB .cluster text{fill:#333;}#mermaid-svg-aceVV88hdN4yykCB .cluster span{color:#333;}#mermaid-svg-aceVV88hdN4yykCB div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-aceVV88hdN4yykCB .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-aceVV88hdN4yykCB rect.text{fill:none;stroke-width:0;}#mermaid-svg-aceVV88hdN4yykCB .icon-shape,#mermaid-svg-aceVV88hdN4yykCB .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aceVV88hdN4yykCB .icon-shape p,#mermaid-svg-aceVV88hdN4yykCB .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-aceVV88hdN4yykCB .icon-shape .label rect,#mermaid-svg-aceVV88hdN4yykCB .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aceVV88hdN4yykCB .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-aceVV88hdN4yykCB .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-aceVV88hdN4yykCB :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 每天
30 分钟
2 点
凌晨 2:30 执行
| 字段 | 值 | 含义 |
|---|---|---|
| 分钟 | 30 | 第 30 分钟 |
| 小时 | 2 | 凌晨 2 点 |
| 日 | * | 每天 |
| 月 | * | 每月 |
| 周 | * | 不限星期 |
命令链:
| 片段 | 作用 |
|---|---|
BGSAVE |
触发后台保存 |
&& sleep 30 |
等 30 秒让 BGSAVE 完成 |
&& cp ... |
拷贝 RDB 到备份目录 |
&& find ... -mtime +14 -delete |
删除 14 天前的旧备份 |
⚠️ 注意 :crontab 中
%必须转义为\%,否则命令会被截断。
7.3 恢复
cd /opt/redis && sudo docker compose stop
sudo cp /opt/redis/backup/dump_2026-07-03.rdb /opt/redis/data/dump.rdb
sudo docker compose start
恢复流程:
#mermaid-svg-0mzonrtRN9fAwi3Z{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0mzonrtRN9fAwi3Z .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0mzonrtRN9fAwi3Z .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0mzonrtRN9fAwi3Z .error-icon{fill:#552222;}#mermaid-svg-0mzonrtRN9fAwi3Z .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0mzonrtRN9fAwi3Z .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0mzonrtRN9fAwi3Z .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0mzonrtRN9fAwi3Z .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0mzonrtRN9fAwi3Z .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0mzonrtRN9fAwi3Z .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0mzonrtRN9fAwi3Z .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0mzonrtRN9fAwi3Z .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0mzonrtRN9fAwi3Z .marker.cross{stroke:#333333;}#mermaid-svg-0mzonrtRN9fAwi3Z svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0mzonrtRN9fAwi3Z p{margin:0;}#mermaid-svg-0mzonrtRN9fAwi3Z .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-0mzonrtRN9fAwi3Z .cluster-label text{fill:#333;}#mermaid-svg-0mzonrtRN9fAwi3Z .cluster-label span{color:#333;}#mermaid-svg-0mzonrtRN9fAwi3Z .cluster-label span p{background-color:transparent;}#mermaid-svg-0mzonrtRN9fAwi3Z .label text,#mermaid-svg-0mzonrtRN9fAwi3Z span{fill:#333;color:#333;}#mermaid-svg-0mzonrtRN9fAwi3Z .node rect,#mermaid-svg-0mzonrtRN9fAwi3Z .node circle,#mermaid-svg-0mzonrtRN9fAwi3Z .node ellipse,#mermaid-svg-0mzonrtRN9fAwi3Z .node polygon,#mermaid-svg-0mzonrtRN9fAwi3Z .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0mzonrtRN9fAwi3Z .rough-node .label text,#mermaid-svg-0mzonrtRN9fAwi3Z .node .label text,#mermaid-svg-0mzonrtRN9fAwi3Z .image-shape .label,#mermaid-svg-0mzonrtRN9fAwi3Z .icon-shape .label{text-anchor:middle;}#mermaid-svg-0mzonrtRN9fAwi3Z .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0mzonrtRN9fAwi3Z .rough-node .label,#mermaid-svg-0mzonrtRN9fAwi3Z .node .label,#mermaid-svg-0mzonrtRN9fAwi3Z .image-shape .label,#mermaid-svg-0mzonrtRN9fAwi3Z .icon-shape .label{text-align:center;}#mermaid-svg-0mzonrtRN9fAwi3Z .node.clickable{cursor:pointer;}#mermaid-svg-0mzonrtRN9fAwi3Z .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0mzonrtRN9fAwi3Z .arrowheadPath{fill:#333333;}#mermaid-svg-0mzonrtRN9fAwi3Z .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0mzonrtRN9fAwi3Z .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0mzonrtRN9fAwi3Z .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0mzonrtRN9fAwi3Z .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0mzonrtRN9fAwi3Z .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0mzonrtRN9fAwi3Z .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0mzonrtRN9fAwi3Z .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0mzonrtRN9fAwi3Z .cluster text{fill:#333;}#mermaid-svg-0mzonrtRN9fAwi3Z .cluster span{color:#333;}#mermaid-svg-0mzonrtRN9fAwi3Z div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0mzonrtRN9fAwi3Z .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0mzonrtRN9fAwi3Z rect.text{fill:none;stroke-width:0;}#mermaid-svg-0mzonrtRN9fAwi3Z .icon-shape,#mermaid-svg-0mzonrtRN9fAwi3Z .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0mzonrtRN9fAwi3Z .icon-shape p,#mermaid-svg-0mzonrtRN9fAwi3Z .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0mzonrtRN9fAwi3Z .icon-shape .label rect,#mermaid-svg-0mzonrtRN9fAwi3Z .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0mzonrtRN9fAwi3Z .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0mzonrtRN9fAwi3Z .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0mzonrtRN9fAwi3Z :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 仅 RDB
RDB + AOF 都在
- stop 容器
- 备份覆盖 dump.rdb
- start 容器
启动时加载
读 dump.rdb 恢复
优先加载 AOF
AOF 重放命令恢复
⚠️ RDB 与 AOF 加载优先级 :两者同时存在时,Redis 优先加载 AOF(数据更完整)。若只用 RDB 恢复,建议先把 AOF 文件移走或临时关闭 AOF。重要数据务必先在测试库演练。
八、第八章「监控与告警」逐条解析
8.1 容器层面
sudo docker stats redis_server
sudo docker inspect --format='{{.State.Health.Status}}' redis_server
| 命令 | 作用 |
|---|---|
stats |
实时显示容器 CPU/内存/网络/IO,类似 top |
inspect --format=... |
Go 模板提取健康状态,输出 healthy/unhealthy/starting |
8.2 Redis 层面
进入 redis-cli 后执行 INFO,重点关注以下字段:
#mermaid-svg-6P176PD0vJOlUCVx{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-6P176PD0vJOlUCVx .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-6P176PD0vJOlUCVx .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-6P176PD0vJOlUCVx .error-icon{fill:#552222;}#mermaid-svg-6P176PD0vJOlUCVx .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-6P176PD0vJOlUCVx .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-6P176PD0vJOlUCVx .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-6P176PD0vJOlUCVx .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-6P176PD0vJOlUCVx .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-6P176PD0vJOlUCVx .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-6P176PD0vJOlUCVx .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-6P176PD0vJOlUCVx .marker{fill:#333333;stroke:#333333;}#mermaid-svg-6P176PD0vJOlUCVx .marker.cross{stroke:#333333;}#mermaid-svg-6P176PD0vJOlUCVx svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-6P176PD0vJOlUCVx p{margin:0;}#mermaid-svg-6P176PD0vJOlUCVx .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-6P176PD0vJOlUCVx .cluster-label text{fill:#333;}#mermaid-svg-6P176PD0vJOlUCVx .cluster-label span{color:#333;}#mermaid-svg-6P176PD0vJOlUCVx .cluster-label span p{background-color:transparent;}#mermaid-svg-6P176PD0vJOlUCVx .label text,#mermaid-svg-6P176PD0vJOlUCVx span{fill:#333;color:#333;}#mermaid-svg-6P176PD0vJOlUCVx .node rect,#mermaid-svg-6P176PD0vJOlUCVx .node circle,#mermaid-svg-6P176PD0vJOlUCVx .node ellipse,#mermaid-svg-6P176PD0vJOlUCVx .node polygon,#mermaid-svg-6P176PD0vJOlUCVx .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-6P176PD0vJOlUCVx .rough-node .label text,#mermaid-svg-6P176PD0vJOlUCVx .node .label text,#mermaid-svg-6P176PD0vJOlUCVx .image-shape .label,#mermaid-svg-6P176PD0vJOlUCVx .icon-shape .label{text-anchor:middle;}#mermaid-svg-6P176PD0vJOlUCVx .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-6P176PD0vJOlUCVx .rough-node .label,#mermaid-svg-6P176PD0vJOlUCVx .node .label,#mermaid-svg-6P176PD0vJOlUCVx .image-shape .label,#mermaid-svg-6P176PD0vJOlUCVx .icon-shape .label{text-align:center;}#mermaid-svg-6P176PD0vJOlUCVx .node.clickable{cursor:pointer;}#mermaid-svg-6P176PD0vJOlUCVx .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-6P176PD0vJOlUCVx .arrowheadPath{fill:#333333;}#mermaid-svg-6P176PD0vJOlUCVx .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-6P176PD0vJOlUCVx .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-6P176PD0vJOlUCVx .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-6P176PD0vJOlUCVx .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-6P176PD0vJOlUCVx .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-6P176PD0vJOlUCVx .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-6P176PD0vJOlUCVx .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-6P176PD0vJOlUCVx .cluster text{fill:#333;}#mermaid-svg-6P176PD0vJOlUCVx .cluster span{color:#333;}#mermaid-svg-6P176PD0vJOlUCVx div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-6P176PD0vJOlUCVx .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-6P176PD0vJOlUCVx rect.text{fill:none;stroke-width:0;}#mermaid-svg-6P176PD0vJOlUCVx .icon-shape,#mermaid-svg-6P176PD0vJOlUCVx .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-6P176PD0vJOlUCVx .icon-shape p,#mermaid-svg-6P176PD0vJOlUCVx .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-6P176PD0vJOlUCVx .icon-shape .label rect,#mermaid-svg-6P176PD0vJOlUCVx .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-6P176PD0vJOlUCVx .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-6P176PD0vJOlUCVx .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-6P176PD0vJOlUCVx :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} INFO 命令
server 段
redis_version/run_id/uptime
clients 段
connected_clients/blocked_clients
memory 段
used_memory/maxmemory/mem_fragmentation_ratio
persistence 段
rdb_last_bgsave_status/aof_last_bgrewrite_status
stats 段
keyspace_hits/keyspace_misses/rejected_connections
keyspace 段
各库 key 数与过期数
| 指标 | 含义 | 健康信号 |
|---|---|---|
used_memory |
已用内存 | 接近 maxmemory 需扩容或调淘汰策略 |
connected_clients |
当前连接数 | 异常飙升可能为连接泄漏 |
rdb_last_bgsave_status |
最近一次 RDB 结果 | 必须 ok |
rejected_connections |
被拒连接数 | 持续 > 0 说明 somaxconn/并发超限 |
keyspace_hits/misses |
命中/未命中 | 未命中突增可能为缓存穿透 |
mem_fragmentation_ratio |
内存碎片率 | > 1.5 说明碎片严重,需重启整理 |
8.3 专业监控
redis_exporter + Prometheus + Grafana 架构:
#mermaid-svg-rsIXKbi1x6Du1jay{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rsIXKbi1x6Du1jay .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rsIXKbi1x6Du1jay .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rsIXKbi1x6Du1jay .error-icon{fill:#552222;}#mermaid-svg-rsIXKbi1x6Du1jay .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rsIXKbi1x6Du1jay .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rsIXKbi1x6Du1jay .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rsIXKbi1x6Du1jay .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rsIXKbi1x6Du1jay .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rsIXKbi1x6Du1jay .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rsIXKbi1x6Du1jay .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rsIXKbi1x6Du1jay .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rsIXKbi1x6Du1jay .marker.cross{stroke:#333333;}#mermaid-svg-rsIXKbi1x6Du1jay svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rsIXKbi1x6Du1jay p{margin:0;}#mermaid-svg-rsIXKbi1x6Du1jay .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-rsIXKbi1x6Du1jay .cluster-label text{fill:#333;}#mermaid-svg-rsIXKbi1x6Du1jay .cluster-label span{color:#333;}#mermaid-svg-rsIXKbi1x6Du1jay .cluster-label span p{background-color:transparent;}#mermaid-svg-rsIXKbi1x6Du1jay .label text,#mermaid-svg-rsIXKbi1x6Du1jay span{fill:#333;color:#333;}#mermaid-svg-rsIXKbi1x6Du1jay .node rect,#mermaid-svg-rsIXKbi1x6Du1jay .node circle,#mermaid-svg-rsIXKbi1x6Du1jay .node ellipse,#mermaid-svg-rsIXKbi1x6Du1jay .node polygon,#mermaid-svg-rsIXKbi1x6Du1jay .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rsIXKbi1x6Du1jay .rough-node .label text,#mermaid-svg-rsIXKbi1x6Du1jay .node .label text,#mermaid-svg-rsIXKbi1x6Du1jay .image-shape .label,#mermaid-svg-rsIXKbi1x6Du1jay .icon-shape .label{text-anchor:middle;}#mermaid-svg-rsIXKbi1x6Du1jay .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-rsIXKbi1x6Du1jay .rough-node .label,#mermaid-svg-rsIXKbi1x6Du1jay .node .label,#mermaid-svg-rsIXKbi1x6Du1jay .image-shape .label,#mermaid-svg-rsIXKbi1x6Du1jay .icon-shape .label{text-align:center;}#mermaid-svg-rsIXKbi1x6Du1jay .node.clickable{cursor:pointer;}#mermaid-svg-rsIXKbi1x6Du1jay .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-rsIXKbi1x6Du1jay .arrowheadPath{fill:#333333;}#mermaid-svg-rsIXKbi1x6Du1jay .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rsIXKbi1x6Du1jay .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rsIXKbi1x6Du1jay .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rsIXKbi1x6Du1jay .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-rsIXKbi1x6Du1jay .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rsIXKbi1x6Du1jay .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-rsIXKbi1x6Du1jay .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rsIXKbi1x6Du1jay .cluster text{fill:#333;}#mermaid-svg-rsIXKbi1x6Du1jay .cluster span{color:#333;}#mermaid-svg-rsIXKbi1x6Du1jay div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rsIXKbi1x6Du1jay .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rsIXKbi1x6Du1jay rect.text{fill:none;stroke-width:0;}#mermaid-svg-rsIXKbi1x6Du1jay .icon-shape,#mermaid-svg-rsIXKbi1x6Du1jay .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rsIXKbi1x6Du1jay .icon-shape p,#mermaid-svg-rsIXKbi1x6Du1jay .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-rsIXKbi1x6Du1jay .icon-shape .label rect,#mermaid-svg-rsIXKbi1x6Du1jay .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rsIXKbi1x6Du1jay .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rsIXKbi1x6Du1jay .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rsIXKbi1x6Du1jay :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 暴露 INFO/慢日志
/metrics
告警
redis_server
redis_exporter
Prometheus
时序存储
Grafana
可视化大盘
Alertmanager
邮件/钉钉/飞书
可图形化监控内存使用率、命中率、持久化延迟、淘汰频率、主从复制延迟等,并配置告警阈值。
九、第九章「故障排查」逐条解析
9.1 故障对照表
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 容器启动后立即退出 | daemonize yes 导致无前台进程 |
conf 中必须 daemonize no;查 docker compose logs redis |
连接提示 NOAUTH |
未带密码 / 密码错误 | redis-cli -a redis123,确认与 requirepass 一致 |
连接提示 MISCONF Redis is configured to save RDB... |
fork 失败,vm.overcommit_memory=0 |
sudo sysctl -w vm.overcommit_memory=1 |
| 远程连接被拒绝 | 未监听 / 防火墙拦截 | 确认 bind 0.0.0.0;`ss -tlnp |
| 内存打满被频繁淘汰 | maxmemory 过小 / 大 key | INFO memory 查看;MEMORY USAGE 定位大 key |
| BGSAVE 卡顿/延迟高 | THP 未关闭 | echo never > .../enabled |
| 磁盘写满 | AOF 文件/日志未轮转 | 配置 AOF 自动重写;确认 compose 已配 logging 轮转 |
启动报 Bad file descriptor |
conf 路径或挂载错误 | 确认 volume 挂载与 dir /data 一致;确认 conf 文件非目录 |
典型故障 1:容器立即退出
#mermaid-svg-3i77iKXu7i4kvaf8{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-3i77iKXu7i4kvaf8 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3i77iKXu7i4kvaf8 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3i77iKXu7i4kvaf8 .error-icon{fill:#552222;}#mermaid-svg-3i77iKXu7i4kvaf8 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3i77iKXu7i4kvaf8 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3i77iKXu7i4kvaf8 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3i77iKXu7i4kvaf8 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3i77iKXu7i4kvaf8 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3i77iKXu7i4kvaf8 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3i77iKXu7i4kvaf8 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3i77iKXu7i4kvaf8 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3i77iKXu7i4kvaf8 .marker.cross{stroke:#333333;}#mermaid-svg-3i77iKXu7i4kvaf8 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3i77iKXu7i4kvaf8 p{margin:0;}#mermaid-svg-3i77iKXu7i4kvaf8 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-3i77iKXu7i4kvaf8 .cluster-label text{fill:#333;}#mermaid-svg-3i77iKXu7i4kvaf8 .cluster-label span{color:#333;}#mermaid-svg-3i77iKXu7i4kvaf8 .cluster-label span p{background-color:transparent;}#mermaid-svg-3i77iKXu7i4kvaf8 .label text,#mermaid-svg-3i77iKXu7i4kvaf8 span{fill:#333;color:#333;}#mermaid-svg-3i77iKXu7i4kvaf8 .node rect,#mermaid-svg-3i77iKXu7i4kvaf8 .node circle,#mermaid-svg-3i77iKXu7i4kvaf8 .node ellipse,#mermaid-svg-3i77iKXu7i4kvaf8 .node polygon,#mermaid-svg-3i77iKXu7i4kvaf8 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3i77iKXu7i4kvaf8 .rough-node .label text,#mermaid-svg-3i77iKXu7i4kvaf8 .node .label text,#mermaid-svg-3i77iKXu7i4kvaf8 .image-shape .label,#mermaid-svg-3i77iKXu7i4kvaf8 .icon-shape .label{text-anchor:middle;}#mermaid-svg-3i77iKXu7i4kvaf8 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-3i77iKXu7i4kvaf8 .rough-node .label,#mermaid-svg-3i77iKXu7i4kvaf8 .node .label,#mermaid-svg-3i77iKXu7i4kvaf8 .image-shape .label,#mermaid-svg-3i77iKXu7i4kvaf8 .icon-shape .label{text-align:center;}#mermaid-svg-3i77iKXu7i4kvaf8 .node.clickable{cursor:pointer;}#mermaid-svg-3i77iKXu7i4kvaf8 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-3i77iKXu7i4kvaf8 .arrowheadPath{fill:#333333;}#mermaid-svg-3i77iKXu7i4kvaf8 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3i77iKXu7i4kvaf8 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3i77iKXu7i4kvaf8 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3i77iKXu7i4kvaf8 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3i77iKXu7i4kvaf8 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3i77iKXu7i4kvaf8 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-3i77iKXu7i4kvaf8 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3i77iKXu7i4kvaf8 .cluster text{fill:#333;}#mermaid-svg-3i77iKXu7i4kvaf8 .cluster span{color:#333;}#mermaid-svg-3i77iKXu7i4kvaf8 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3i77iKXu7i4kvaf8 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3i77iKXu7i4kvaf8 rect.text{fill:none;stroke-width:0;}#mermaid-svg-3i77iKXu7i4kvaf8 .icon-shape,#mermaid-svg-3i77iKXu7i4kvaf8 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3i77iKXu7i4kvaf8 .icon-shape p,#mermaid-svg-3i77iKXu7i4kvaf8 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-3i77iKXu7i4kvaf8 .icon-shape .label rect,#mermaid-svg-3i77iKXu7i4kvaf8 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3i77iKXu7i4kvaf8 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-3i77iKXu7i4kvaf8 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-3i77iKXu7i4kvaf8 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} yes
no
容器启动
daemonize?
redis-server 后台化
无前台进程
Docker 判定退出
容器立即停止
前台运行
持续运行
排查:sudo docker compose logs redis,看到 daemonize 相关即改 conf 重启。
典型故障 2:MISCONF 拒绝写入
Redis 检测到 BGSAVE 失败(fork 被拒),为保护数据一致性主动拒绝所有写入 。根因是 vm.overcommit_memory=0。修复后写入自动恢复。
典型故障 3:远程连不上
#mermaid-svg-tQaZ37AW2VQ57G7u{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-tQaZ37AW2VQ57G7u .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-tQaZ37AW2VQ57G7u .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-tQaZ37AW2VQ57G7u .error-icon{fill:#552222;}#mermaid-svg-tQaZ37AW2VQ57G7u .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-tQaZ37AW2VQ57G7u .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-tQaZ37AW2VQ57G7u .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-tQaZ37AW2VQ57G7u .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-tQaZ37AW2VQ57G7u .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-tQaZ37AW2VQ57G7u .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-tQaZ37AW2VQ57G7u .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-tQaZ37AW2VQ57G7u .marker{fill:#333333;stroke:#333333;}#mermaid-svg-tQaZ37AW2VQ57G7u .marker.cross{stroke:#333333;}#mermaid-svg-tQaZ37AW2VQ57G7u svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-tQaZ37AW2VQ57G7u p{margin:0;}#mermaid-svg-tQaZ37AW2VQ57G7u .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-tQaZ37AW2VQ57G7u .cluster-label text{fill:#333;}#mermaid-svg-tQaZ37AW2VQ57G7u .cluster-label span{color:#333;}#mermaid-svg-tQaZ37AW2VQ57G7u .cluster-label span p{background-color:transparent;}#mermaid-svg-tQaZ37AW2VQ57G7u .label text,#mermaid-svg-tQaZ37AW2VQ57G7u span{fill:#333;color:#333;}#mermaid-svg-tQaZ37AW2VQ57G7u .node rect,#mermaid-svg-tQaZ37AW2VQ57G7u .node circle,#mermaid-svg-tQaZ37AW2VQ57G7u .node ellipse,#mermaid-svg-tQaZ37AW2VQ57G7u .node polygon,#mermaid-svg-tQaZ37AW2VQ57G7u .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-tQaZ37AW2VQ57G7u .rough-node .label text,#mermaid-svg-tQaZ37AW2VQ57G7u .node .label text,#mermaid-svg-tQaZ37AW2VQ57G7u .image-shape .label,#mermaid-svg-tQaZ37AW2VQ57G7u .icon-shape .label{text-anchor:middle;}#mermaid-svg-tQaZ37AW2VQ57G7u .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-tQaZ37AW2VQ57G7u .rough-node .label,#mermaid-svg-tQaZ37AW2VQ57G7u .node .label,#mermaid-svg-tQaZ37AW2VQ57G7u .image-shape .label,#mermaid-svg-tQaZ37AW2VQ57G7u .icon-shape .label{text-align:center;}#mermaid-svg-tQaZ37AW2VQ57G7u .node.clickable{cursor:pointer;}#mermaid-svg-tQaZ37AW2VQ57G7u .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-tQaZ37AW2VQ57G7u .arrowheadPath{fill:#333333;}#mermaid-svg-tQaZ37AW2VQ57G7u .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-tQaZ37AW2VQ57G7u .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-tQaZ37AW2VQ57G7u .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tQaZ37AW2VQ57G7u .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-tQaZ37AW2VQ57G7u .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tQaZ37AW2VQ57G7u .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-tQaZ37AW2VQ57G7u .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-tQaZ37AW2VQ57G7u .cluster text{fill:#333;}#mermaid-svg-tQaZ37AW2VQ57G7u .cluster span{color:#333;}#mermaid-svg-tQaZ37AW2VQ57G7u div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-tQaZ37AW2VQ57G7u .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-tQaZ37AW2VQ57G7u rect.text{fill:none;stroke-width:0;}#mermaid-svg-tQaZ37AW2VQ57G7u .icon-shape,#mermaid-svg-tQaZ37AW2VQ57G7u .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tQaZ37AW2VQ57G7u .icon-shape p,#mermaid-svg-tQaZ37AW2VQ57G7u .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-tQaZ37AW2VQ57G7u .icon-shape .label rect,#mermaid-svg-tQaZ37AW2VQ57G7u .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tQaZ37AW2VQ57G7u .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-tQaZ37AW2VQ57G7u .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-tQaZ37AW2VQ57G7u :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 1. TCP
2. 转发
3. AUTH
4. 响应
防火墙拦截?
bind 限制?
requirepass?
客户端
宿主机 6379
容器
Redis
失败
失败
NOAUTH
逐层排查:ss -tlnp | grep 6379(端口监听)→ 防火墙/安全组 → bind → 密码。
9.2 常用排查命令汇总
sudo docker compose logs --tail 200 redis # 最近 200 行日志
sudo docker exec -it redis_server bash # 进容器排查
ss -tlnp | grep 6379 # 端口监听
df -h # 磁盘空间
sysctl vm.overcommit_memory net.core.somaxconn # 内核参数
cat /sys/kernel/mm/transparent_hugepage/enabled # THP 状态
| 命令 | 作用 |
|---|---|
ss -tlnp |
socket statistics,替代已弃用的 netstat。-t TCP、-l 监听、-n 数字、-p 进程 |
df -h |
disk free,-h 人类可读(KB/MB/GB) |
sysctl ... |
查看内核参数当前值 |
十、第十章「升级与回滚」逐条解析
10.1 升级前必做
sudo docker exec redis_server redis-cli -a redis123 BGSAVE
sleep 30
sudo cp /opt/redis/data/dump.rdb /opt/redis/backup/pre_upgrade_$(date +%F).rdb
cd /opt/redis && sudo docker compose down
为什么必须备份: 升级有风险------新版本可能不兼容旧持久化格式,失败需回滚。
为什么先 down: 避免新旧容器同时挂载同一数据目录导致文件损坏。
10.2 升级
修改 docker-compose.yml 中 image: redis:7.2 为新版本(如 redis:7.4),然后:
sudo docker compose up -d
升级流程:
#mermaid-svg-9NnuJ8YsWUeTLJZ3{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .error-icon{fill:#552222;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .marker.cross{stroke:#333333;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 p{margin:0;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .cluster-label text{fill:#333;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .cluster-label span{color:#333;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .cluster-label span p{background-color:transparent;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .label text,#mermaid-svg-9NnuJ8YsWUeTLJZ3 span{fill:#333;color:#333;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .node rect,#mermaid-svg-9NnuJ8YsWUeTLJZ3 .node circle,#mermaid-svg-9NnuJ8YsWUeTLJZ3 .node ellipse,#mermaid-svg-9NnuJ8YsWUeTLJZ3 .node polygon,#mermaid-svg-9NnuJ8YsWUeTLJZ3 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .rough-node .label text,#mermaid-svg-9NnuJ8YsWUeTLJZ3 .node .label text,#mermaid-svg-9NnuJ8YsWUeTLJZ3 .image-shape .label,#mermaid-svg-9NnuJ8YsWUeTLJZ3 .icon-shape .label{text-anchor:middle;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .rough-node .label,#mermaid-svg-9NnuJ8YsWUeTLJZ3 .node .label,#mermaid-svg-9NnuJ8YsWUeTLJZ3 .image-shape .label,#mermaid-svg-9NnuJ8YsWUeTLJZ3 .icon-shape .label{text-align:center;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .node.clickable{cursor:pointer;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .arrowheadPath{fill:#333333;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .cluster text{fill:#333;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .cluster span{color:#333;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 rect.text{fill:none;stroke-width:0;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .icon-shape,#mermaid-svg-9NnuJ8YsWUeTLJZ3 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .icon-shape p,#mermaid-svg-9NnuJ8YsWUeTLJZ3 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .icon-shape .label rect,#mermaid-svg-9NnuJ8YsWUeTLJZ3 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-9NnuJ8YsWUeTLJZ3 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
当前 7.2 运行
BGSAVE 备份
down 停删容器
改 image 为 7.4
up -d 拉新镜像启动
启动成功?
升级完成
回滚
⚠️ 跨大版本升级 (如 6.x → 7.x)需关注兼容性:Redis 7 默认启用 multi-part AOF (AOF 拆成
manifest+ 多个增量文件),旧版单文件 AOF 会被自动迁移。升级前请读官方 Release Notes,并在测试库演练。小版本升级(7.2.4 → 7.2.5)通常可直接升级。
10.3 回滚
#mermaid-svg-0L3twDqYwgJaKcIj{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0L3twDqYwgJaKcIj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0L3twDqYwgJaKcIj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0L3twDqYwgJaKcIj .error-icon{fill:#552222;}#mermaid-svg-0L3twDqYwgJaKcIj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0L3twDqYwgJaKcIj .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0L3twDqYwgJaKcIj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0L3twDqYwgJaKcIj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0L3twDqYwgJaKcIj .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0L3twDqYwgJaKcIj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0L3twDqYwgJaKcIj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0L3twDqYwgJaKcIj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0L3twDqYwgJaKcIj .marker.cross{stroke:#333333;}#mermaid-svg-0L3twDqYwgJaKcIj svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0L3twDqYwgJaKcIj p{margin:0;}#mermaid-svg-0L3twDqYwgJaKcIj .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-0L3twDqYwgJaKcIj .cluster-label text{fill:#333;}#mermaid-svg-0L3twDqYwgJaKcIj .cluster-label span{color:#333;}#mermaid-svg-0L3twDqYwgJaKcIj .cluster-label span p{background-color:transparent;}#mermaid-svg-0L3twDqYwgJaKcIj .label text,#mermaid-svg-0L3twDqYwgJaKcIj span{fill:#333;color:#333;}#mermaid-svg-0L3twDqYwgJaKcIj .node rect,#mermaid-svg-0L3twDqYwgJaKcIj .node circle,#mermaid-svg-0L3twDqYwgJaKcIj .node ellipse,#mermaid-svg-0L3twDqYwgJaKcIj .node polygon,#mermaid-svg-0L3twDqYwgJaKcIj .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0L3twDqYwgJaKcIj .rough-node .label text,#mermaid-svg-0L3twDqYwgJaKcIj .node .label text,#mermaid-svg-0L3twDqYwgJaKcIj .image-shape .label,#mermaid-svg-0L3twDqYwgJaKcIj .icon-shape .label{text-anchor:middle;}#mermaid-svg-0L3twDqYwgJaKcIj .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0L3twDqYwgJaKcIj .rough-node .label,#mermaid-svg-0L3twDqYwgJaKcIj .node .label,#mermaid-svg-0L3twDqYwgJaKcIj .image-shape .label,#mermaid-svg-0L3twDqYwgJaKcIj .icon-shape .label{text-align:center;}#mermaid-svg-0L3twDqYwgJaKcIj .node.clickable{cursor:pointer;}#mermaid-svg-0L3twDqYwgJaKcIj .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0L3twDqYwgJaKcIj .arrowheadPath{fill:#333333;}#mermaid-svg-0L3twDqYwgJaKcIj .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0L3twDqYwgJaKcIj .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0L3twDqYwgJaKcIj .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0L3twDqYwgJaKcIj .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0L3twDqYwgJaKcIj .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0L3twDqYwgJaKcIj .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0L3twDqYwgJaKcIj .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0L3twDqYwgJaKcIj .cluster text{fill:#333;}#mermaid-svg-0L3twDqYwgJaKcIj .cluster span{color:#333;}#mermaid-svg-0L3twDqYwgJaKcIj div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0L3twDqYwgJaKcIj .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0L3twDqYwgJaKcIj rect.text{fill:none;stroke-width:0;}#mermaid-svg-0L3twDqYwgJaKcIj .icon-shape,#mermaid-svg-0L3twDqYwgJaKcIj .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0L3twDqYwgJaKcIj .icon-shape p,#mermaid-svg-0L3twDqYwgJaKcIj .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0L3twDqYwgJaKcIj .icon-shape .label rect,#mermaid-svg-0L3twDqYwgJaKcIj .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0L3twDqYwgJaKcIj .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0L3twDqYwgJaKcIj .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0L3twDqYwgJaKcIj :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 升级后异常
stop 容器
改回旧 image 如 7.2
用 pre_upgrade 备份恢复 RDB
start
回滚完成
| 情况 | 回滚方式 |
|---|---|
| 新版本未改写数据格式 | 改回旧 image → up -d 直接回退 |
| 新版本已改写持久化文件 | 无法直接回退 → 从 pre_upgrade_*.rdb 恢复 |
十一、附录解析
附录 A:安全加固清单
| 加固项 | 原理 |
|---|---|
| 修改默认密码 | redis123 是公开凭证,必须替换为 24 位以上强密码 |
收紧 bind |
改为内网 IP,不要 0.0.0.0 暴露公网 |
| 网络隔离 | 6379 不直接暴露公网,防火墙/安全组限制来源 IP |
| 禁用危险命令 | FLUSHALL/FLUSHDB/CONFIG/KEYS 重命名为空,防误删/误扫 |
| 开启 ACL(进阶) | Redis 6+ 的 ACL,为不同应用分配独立账号与最小命令权限 |
| 启用 TLS(进阶) | Redis 6+ 原生 TLS,或用 Stunnel/SSH 隧道加密传输 |
| 内核三项 | vm.overcommit_memory=1、somaxconn≥1024、关闭 THP |
| 凭证管理 | 密码用环境变量/密钥管理服务注入,禁止硬编码 |
| 定期备份 + 演练 | 有备份不等于能恢复,必须实际演练 |
| 版本补丁 | 关注 Redis 安全公告,及时升级小版本 |
附录 B:配置参数速查表
| 类别 | 参数 | 值 | 说明 |
|---|---|---|---|
| 连接 | 端口 | 6379 | Redis 默认端口 |
| 连接 | 密码 | redis123 | 教程默认,生产必须修改 |
| 持久化 | 数据目录(宿主机) | /opt/redis/data | 绑定挂载路径 |
| 持久化 | 数据目录(容器内) | /data | Redis dir 指向 |
| 持久化 | RDB 文件 | dump.rdb | 快照文件 |
| 持久化 | AOF 文件 | appendonly.aof | 追加日志文件 |
| 持久化 | appendfsync | everysec | 每秒刷盘,兼顾性能与安全 |
| 内存 | maxmemory | 1gb | 应用层上限 |
| 内存 | 淘汰策略 | allkeys-lru | 达上限淘汰最近最少使用 |
| 部署 | compose 目录 | /opt/redis | docker-compose.yml 所在目录 |
| 部署 | 配置文件 | /opt/redis/conf/redis.conf | 自定义配置 |
| 镜像 | 版本 | redis:7.2 | 官方镜像 |
| 容器 | 名称 | redis_server | 统一命名 |
| 重启 | 策略 | unless-stopped | 宕机自动拉起,手动停止不拉起 |
| 内核 | vm.overcommit_memory | 1 | 允许超分,避免 fork 失败 |
| 内核 | somaxconn | 1024 | 增大连接队列 |
| 内核 | THP | never | 关闭透明大页,降低 fork 延迟 |
| 时区 | TZ | Asia/Shanghai | compose 中设置 |
十二、全流程串联总览
各步骤核心作用与不做会怎样
| 步骤 | 解决的核心问题 | 不做会怎样 |
|---|---|---|
| 4.1 拉取镜像 | 获取 Redis 运行时 | up 时才拉,首次启动慢 |
| 4.2 准备目录 | 给 compose 和数据标准位置 | 命令散落,每次带 -f 路径 |
| 4.3 内核三项 | 让 fork/COW 正常工作 | BGSAVE 失败、fork 延迟飙升、连接被拒 |
| 4.4 写 redis.conf | 持久化+内存有界+安全加固 | 裸跑:无密码、无持久化、内存无限增长 |
| 4.5 授权 999:999 | 解决容器内外 UID 不一致 | 容器启动报 Permission denied |
| 4.6 写 compose | 声明式配置,可复现可版本化 | 散落命令,难维护难复现 |
| 4.7 启动 | 把描述变成运行容器 | 没有运行实例 |
| 4.8 验证 | 确认 Redis 自身可用 | 不知是 DB 坏还是网络坏 |
| 7. 备份恢复 | 数据安全兜底 | 数据丢失无法恢复 |
| 8. 监控告警 | 及时发现故障 | 问题发生后才知道 |
| 9. 故障排查 | 快速定位问题 | 出问题后无从下手 |
| 10. 升级回滚 | 安全升级 + 出问题能退回 | 升级失败后数据丢失 |
关键技术点回顾
#mermaid-svg-PxNpBIJYkTYqEuoq{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-PxNpBIJYkTYqEuoq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-PxNpBIJYkTYqEuoq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-PxNpBIJYkTYqEuoq .error-icon{fill:#552222;}#mermaid-svg-PxNpBIJYkTYqEuoq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-PxNpBIJYkTYqEuoq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-PxNpBIJYkTYqEuoq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-PxNpBIJYkTYqEuoq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-PxNpBIJYkTYqEuoq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-PxNpBIJYkTYqEuoq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-PxNpBIJYkTYqEuoq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-PxNpBIJYkTYqEuoq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-PxNpBIJYkTYqEuoq .marker.cross{stroke:#333333;}#mermaid-svg-PxNpBIJYkTYqEuoq svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-PxNpBIJYkTYqEuoq p{margin:0;}#mermaid-svg-PxNpBIJYkTYqEuoq .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-PxNpBIJYkTYqEuoq .cluster-label text{fill:#333;}#mermaid-svg-PxNpBIJYkTYqEuoq .cluster-label span{color:#333;}#mermaid-svg-PxNpBIJYkTYqEuoq .cluster-label span p{background-color:transparent;}#mermaid-svg-PxNpBIJYkTYqEuoq .label text,#mermaid-svg-PxNpBIJYkTYqEuoq span{fill:#333;color:#333;}#mermaid-svg-PxNpBIJYkTYqEuoq .node rect,#mermaid-svg-PxNpBIJYkTYqEuoq .node circle,#mermaid-svg-PxNpBIJYkTYqEuoq .node ellipse,#mermaid-svg-PxNpBIJYkTYqEuoq .node polygon,#mermaid-svg-PxNpBIJYkTYqEuoq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-PxNpBIJYkTYqEuoq .rough-node .label text,#mermaid-svg-PxNpBIJYkTYqEuoq .node .label text,#mermaid-svg-PxNpBIJYkTYqEuoq .image-shape .label,#mermaid-svg-PxNpBIJYkTYqEuoq .icon-shape .label{text-anchor:middle;}#mermaid-svg-PxNpBIJYkTYqEuoq .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-PxNpBIJYkTYqEuoq .rough-node .label,#mermaid-svg-PxNpBIJYkTYqEuoq .node .label,#mermaid-svg-PxNpBIJYkTYqEuoq .image-shape .label,#mermaid-svg-PxNpBIJYkTYqEuoq .icon-shape .label{text-align:center;}#mermaid-svg-PxNpBIJYkTYqEuoq .node.clickable{cursor:pointer;}#mermaid-svg-PxNpBIJYkTYqEuoq .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-PxNpBIJYkTYqEuoq .arrowheadPath{fill:#333333;}#mermaid-svg-PxNpBIJYkTYqEuoq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-PxNpBIJYkTYqEuoq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-PxNpBIJYkTYqEuoq .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-PxNpBIJYkTYqEuoq .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-PxNpBIJYkTYqEuoq .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-PxNpBIJYkTYqEuoq .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-PxNpBIJYkTYqEuoq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-PxNpBIJYkTYqEuoq .cluster text{fill:#333;}#mermaid-svg-PxNpBIJYkTYqEuoq .cluster span{color:#333;}#mermaid-svg-PxNpBIJYkTYqEuoq div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-PxNpBIJYkTYqEuoq .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-PxNpBIJYkTYqEuoq rect.text{fill:none;stroke-width:0;}#mermaid-svg-PxNpBIJYkTYqEuoq .icon-shape,#mermaid-svg-PxNpBIJYkTYqEuoq .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-PxNpBIJYkTYqEuoq .icon-shape p,#mermaid-svg-PxNpBIJYkTYqEuoq .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-PxNpBIJYkTYqEuoq .icon-shape .label rect,#mermaid-svg-PxNpBIJYkTYqEuoq .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-PxNpBIJYkTYqEuoq .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-PxNpBIJYkTYqEuoq .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-PxNpBIJYkTYqEuoq :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 工程化四支柱
数据安全
RDB+AOF 双持久化 + 定时备份
内存有界
maxmemory + 淘汰策略 + cgroup 限制
安全加固
密码 + bind + rename-command
可观测可恢复
healthcheck + 监控 + 演练
生产级 Redis 部署
📝 结语 :工程化部署的核心不是「能跑起来」,而是「可维护、可复现、可恢复、可观测 」。Redis 的工程化相比其他数据库多了两个独有命题------fork/COW 对内核参数的依赖 (vm.overcommit_memory / somaxconn / THP),以及内存有界管理(maxmemory + 淘汰策略)。把这两点配好,再叠加持久化双保险、安全加固、健康检查与备份恢复,才构成一个真正生产可用的 Redis 部署方案。