容器化的两个坑
容器里跑 Redis,持久化最容易出问题的地方有两处。一是挂载:数据目录必须挂到持久卷或宿主机路径,匿名卷与容器内路径都会随容器重建一起消失。二是停止:容器收到停止信号后需要足够时间跑完保存流程,编排平台的默认停止超时往往只有十秒,大实例来不及保存就被强杀,表现为每次发布都丢一段数据。
基本信息
| 卷 | 数据目录挂到持久卷或明确的宿主机路径 |
|---|---|
| 停止信号 | 先发终止信号,留足保存时间再强杀 |
| 超时参数 | 容器运行时的停止超时与编排平台的宽限期 |
| 检查方式 | 重启后核对最近保存时间与键总数 |
| 前提 | 持久卷不能由容器生命周期管理 |
典型使用场景
- 容器化部署 Redis 时确定数据卷方案与挂载路径
- 发布流程中容器频繁重建,需要确认数据不会随容器消失
- 编排平台滚动更新导致实例被强杀,需要调整宽限期参数
- 排查每次发布后数据量轻微下降的现象
- 容量与稳定性评审时核对编排平台健康检查与停止超时是否匹配
思路示例
思路示例
docker run -v /data/redis:/data redis:7 redis-server /etc/redis/redis.conf # 明确挂载宿主机路径
docker stop -t 60 redis # 给足 60 秒优雅停止时间
docker inspect -f '{{.State.ExitCode}}' redis # 退出码可辅助判断是否被强杀
docker volume ls # 确认没有落到匿名卷检查项与风险
| 检查项 | 正确做法 | 做错的风险 |
|---|---|---|
| 数据目录 | 挂载到持久卷或宿主机路径 | 容器重建后数据全部消失 |
| 停止超时 | 大于最坏情况下的保存耗时 | 保存中途被强杀,尾部数据丢失 |
| 卷的生命周期 | 与容器解耦,独立管理 | 误删卷把数据一起清掉 |
| 健康检查 | 与就绪状态匹配 | 未加载完成就接流量,请求报错 |
编排平台的健康检查与停止超时要和持久化耗时匹配,超时强杀可能跳过保存;给出终止信号到强杀之间的宽限期尤其容易被忽略。
容器化并不改变持久化语义,只是把磁盘与进程生命周期的管理责任转移到了编排层,配置项本身仍需按单机经验设置。