CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Redis 缓存入门/课时/Docker 运行 Redis
RawBlame
课时目录12 节

Redis 缓存入门

  1. 01Redis 是什么
  2. 02CLI 与键命名
  3. 03String 与计数
  4. 04Hash / List / Set / ZSet
  5. 05过期与淘汰
  6. 06缓存模式
  7. 07Spring Data Redis
  8. 08会话与 Sa-Token
  9. 09Docker 运行 Redis
  10. 10Pub/Sub 入门
  11. 11测试与监控
  12. 12综合练习

Docker 运行 Redis

镜像、持久化 AOF/RDB 概念。

25 分钟

Docker 跑 Redis:持久化与生产形态

这一课你将能做到

  1. 用带数据卷、密码、AOF 的 docker run 命令启动一个「重启不丢数据」的 Redis,并解释每个参数
  2. 亲手做一次「删容器数据全丢」实验,理解 RDB 快照和 AOF 日志的分工与取舍
  3. 写出生产形态的 docker-compose 片段,说清容器里 host 为什么写 redis 而不是 127.0.0.1

为什么要学

第 1 课你用一行 docker run 起了 Redis——那是个「一次性玩具」:容器一删,所有 key 蒸发。而本站生产环境里 Redis 存着所有人的登录态:没有持久化,Redis 重启 = 全站用户被踢下线。

这一课补上生产视角的三块拼图:数据怎么不丢(持久化)、进程怎么常驻(restart 策略 + compose)、服务怎么被发现(容器网络里的 host)。学完你就能照着本站生产配置搭出一个像样的 Redis 实例。

先建立图像

持久化的两条路:

RDB(快照):每隔一段时间,把整个内存「拍照」存成 dump.rdb
  ✔ 文件小、恢复快        ✘ 两次快照之间的数据会丢

AOF(日志):每条写命令追加记录到 appendonly.aof,重启时重放
  ✔ 丢得少(每秒刷盘)    ✘ 文件更大、恢复更慢

生产常见组合:AOF 开(everysec)+ RDB 兜底
本站会话场景:会话丢 = 用户重登 → AOF everysec 的 1 秒丢失窗口可接受

跟着做

步骤 1:复现「数据蒸发」

先确认 restart 不会丢:

docker exec -it redis-dev redis-cli
SET precious "data"
exit
docker restart redis-dev
docker exec redis-dev redis-cli GET precious    # "data" 还在(重启前有 RDB 落盘)

再验证「删容器 = 一切归零」:

docker exec redis-dev redis-cli SET precious2 "gone-soon"
docker rm -f redis-dev
docker run -d --name redis-dev -p 6379:6379 redis:7-alpine
docker exec redis-dev redis-cli GET precious2
# (nil) —— 没有数据卷,容器即数据,删了就没了

步骤 2:带卷 + 密码 + AOF 重启

docker rm -f redis-dev
docker run -d --name redis-dev \
  -p 6379:6379 \
  -v redis-data:/data \
  --restart unless-stopped \
  redis:7-alpine \
  redis-server --requirepass "devpass123" --appendonly yes

参数拆解:-v redis-data:/data 命名卷持久化数据目录;--restart unless-stopped 宿主机重启后容器自动拉起;--requirepass 密码认证(生产必开);--appendonly yes 开 AOF。

从这一步起,本课容器带密码,后面所有 redis-cli 命令都要带 -a devpass123。

步骤 3:验证持久化真的生效

docker exec redis-dev redis-cli -a devpass123 SET persist:test "survived"
docker restart redis-dev
docker exec redis-dev redis-cli -a devpass123 GET persist:test
# "survived" ✅
docker exec redis-dev redis-cli -a devpass123 CONFIG GET appendonly
# appendonly → yes

(-a 会把密码留在 shell 历史里,教学环境无妨;生产脚本用 交互输入。)

--askpass

步骤 4:看 RDB 和 AOF 长什么样

docker exec redis-dev ls -la /data
# dump.rdb、appendonlydir/
docker exec redis-dev sh -c 'ls -la /data/appendonlydir/'
# appendonly.aof.* :里面是 RESP 格式的写命令流

步骤 5:写一段 docker-compose(生产形态缩影)

services:
  redis:
    image: redis:7-alpine
    restart: unless-stopped
    command: redis-server --requirepass ${REDIS_PASSWORD} --appendonly yes --maxmemory 512mb --maxmemory-policy allkeys-lru
    ports:
      - "127.0.0.1:6379:6379"   # 只绑本机/内网,不对公网暴露
    volumes:
      - redis-data:/data
volumes:
  redis-data:

注意 127.0.0.1:6379:6379——本站的安全约定是 6379(和 3306 一样)不对 0.0.0.0 暴露,应用走内网/本机访问。

步骤 6:host 写谁?——容器网络的思考题

backend 也在容器里跑时,spring.data.redis.host 应写 compose 里的服务名 redis(Docker 内置 DNS 解析);backend 裸跑在宿主机时才写 127.0.0.1。本站生产通过 REDIS_HOST 环境变量注入,两种形态都只需改环境变量,代码零改动。

讲清楚要点

  1. restart ≠ 持久化:restart 不删容器,数据可能靠 RDB 捡回来;rm 掉容器没有卷,数据必丢。「卷」才是数据的家。
  2. AOF everysec 是本站场景的甜点位:最多丢 1 秒写入 = 极端情况少数人重新登录;对缓存无感,对会话可接受。
  3. requirepass + 不暴露公网是最低安全配置:Redis 未授权访问是经典入侵入口(写 crontab 反弹 shell)。呼应本站「3306/6379 不开 0.0.0.0」的硬约定。
  4. maxmemory + allkeys-lru 是纯缓存实例标准搭配;含会话的实例容量要给足并监控(会话被挤 = 用户被踢,见第 5 课的分级讨论)。
  5. CONFIG SET 运行时改,CONFIG REWRITE 落盘;容器里更推荐把参数写进 command/配置文件,重启即生效。

你可能会懵的地方

  • RDB 和 AOF 同时开会冲突吗? 不冲突,互补:恢复优先用 AOF(更全),RDB 做定期快照兜底和快速恢复。

  • 为什么默认配置其实也有 RDB? 默认 save 规则(如 3600 秒内 1 次修改就快照)在工作,但它救不了高频写入的实时数据——两次快照间的写入还是会丢。

  • 数据卷放在哪?删卷会怎样? docker volume inspect redis-data 看路径;docker volume rm redis-data 才是真正删数据,谨慎。

  • 生产 Redis 要不要上集群/哨兵? 单实例 + 持久化 + 监控对本站量级足够;集群解决的是单机内存/写瓶颈,别过早设计。

  • maxmemory-policy 对会话实例该设什么? 慎用 allkeys-lru(可能挤会话)。要么容量富余 + 监控,要么会话/缓存分实例——回到「数据分级」思想。

错法对照

错法问题正解
docker run 不挂卷rm 容器数据蒸发-v redis-data:/data
6379 映射 0.0.0.0 且无密码未授权访问被入侵127.0.0.1 绑定 + requirepass
只 restart 不持久化还当高可用重启可能丢数据AOF + 卷 + 监控
所有实例 allkeys-lru会话被挤用户掉线按数据类型分实例/策略
backend 容器里 host 写 127.0.0.1连的是容器自己compose 服务名 redis
密码明文进 shell 历史泄露--askpass 或环境变量

卡点急救

  1. NOAUTH Authentication required:设了密码没带。redis-cli -a 密码 或先 AUTH。
  2. --requirepass 后旧连接全断:正常,重新带密码连接即可。
  3. 想重置数据:docker volume rm redis-data 前确认不再需要——这是真删数据。
  4. AOF 文件损坏启动失败:redis-check-aof --fix appendonly.aof.*(先备份)。
  5. compose 起来 backend 连不上:确认两服务在同一网络、host 用服务名;docker compose logs redis 排查。

面试常问

  • RDB 和 AOF 怎么选? RDB 恢复快、丢窗口大;AOF 丢得少(everysec 最多 1 秒)、文件大恢复慢。生产常 AOF 为主、RDB 兜底。结合会话场景说明选择依据:1 秒丢失 = 少数人重登,可接受。

  • Redis 重启后数据还在吗? 取决于持久化:有 AOF/RDB 就在;纯内存裸跑全丢。还要分数据类型回答:缓存丢了回源重建,会话丢了用户重登,MySQL 权威数据不受影响。

  • 你们 Redis 的安全配置? requirepass + 绑定内网/127.0.0.1 不对公网暴露 + 密码走环境变量;呼应本站「3306/6379 不开 0.0.0.0」的硬约定。

自测三问

  1. restart 和「挂了卷」分别保证了什么?删容器后哪个能救回数据?
  2. AOF everysec 对本站会话意味着最坏丢多少数据?为什么可接受?
  3. backend 在容器里时 host 应该写什么?为什么 127.0.0.1 会连错对象?

小结一句话

生产 Redis = 卷(数据的家)+ AOF(少丢)+ 密码与内网(安全)+ restart 策略(常驻),host 由部署形态决定。

延伸

  • Redis 持久化官方文档
  • 下一课:发布订阅——跨实例广播消息的轻量方案,以及它「不保证送达」的三大陷阱。
加载本节练习…
← 上一课会话与 Sa-Token下一课 →Pub/Sub 入门