根本原因是容器重启后未读取原有持久化文件:dump.rdb或appendonly.aof被锁在旧容器可写层,新容器挂载空目录或新volume;必须确保-v挂载路径与redis.conf中dir配置严格一致,并重建容器而非仅restart。

配置了持久化却仍丢数据,根本原因不是Redis没写盘,而是容器启动时压根没读到你存的文件——dump.rdb 或 appendonly.aof 被锁在旧容器的可写层里,新容器启动后挂载的是空目录或全新Volume。
Redis容器重启后找不到dump.rdb?检查挂载路径是否真实生效
很多人改完 redis.conf 里的 dir 和 dbfilename,就以为万事大吉。但Docker里Redis进程实际看到的路径,取决于你是否用 -v 正确挂载了宿主机目录,以及挂载点是否覆盖了Redis配置中指定的 dir。
- 如果只改配置但没挂载:
dir /data指向容器内默认路径,而该路径未绑定宿主机,容器一删,/data/dump.rdb就消失 - 如果挂载了但路径不匹配:比如
-v /host/redis:/data,但配置里写的是dir /var/lib/redis,那Redis会往/var/lib/redis写,而这个路径根本没挂载,数据仍在临时可写层 - 验证方法:进容器执行
redis-cli CONFIG GET dir和ls -l $(redis-cli CONFIG GET dir | awk '{print $2}')/dump.rdb,确认文件真正在挂载点下存在
docker restart 不等于 redis-server 重新加载配置
docker restart 只是把容器进程杀掉再拉起,不会触发Redis的配置重载逻辑。如果你改了 redis.conf 但没重建容器,新配置根本没生效;更隐蔽的是,有些镜像(如官方 redis:alpine)默认用 ENTRYPOINT ["docker-entrypoint.sh"] 启动,它会把 redis.conf 复制进容器,但只在首次启动时生效 —— 后续 restart 不会再覆盖。
- 改配置后必须重建容器:
docker rm -f redis && docker run ...,不能只靠restart - 避免硬编码路径:用
-v /host/conf/redis.conf:/usr/local/etc/redis/redis.conf:ro挂载配置,并确保redis.conf中的dir指向一个同样被挂载的目录(如/data) - 启动时加
--config-file /usr/local/etc/redis/redis.conf显式指定,防止 entrypoint 覆盖
AOF开启但没刷盘?看 fsync 策略和容器信号处理
AOF默认是 appendfsync everysec,看起来每秒刷一次,但容器收到 SIGTERM(如 docker stop)时,Redis只有1秒窗口来完成最后一次 fsync。如果恰巧卡在日志写入和刷盘之间,appendonly.aof 文件末尾就缺了一段命令,重启时 replay 失败,整个AOF被截断或忽略。
- 测试时别用
docker kill:它发SIGKILL,Redis来不及做任何清理,AOF大概率损坏 - 生产建议设为
appendfsync always(仅限低QPS场景),或至少确认no-appendfsync-on-rewrite yes,避免BGREWRITEAOF期间阻塞主进程 - 容器停止前加健康检查:用
docker exec redis redis-cli BGSAVE手动触发一次RDB,作为兜底快照
最常被忽略的一点:Redis的 dir 配置值和挂载路径必须严格一致,且挂载必须在容器启动时完成——没有“运行中热挂载”这回事。哪怕只差一个斜杠(/data vs /data/),都可能导致Redis往不可见的位置写文件。数据不在挂载点,就等于不存在。











