4、快照空间管理:快照预留空间计算、快照空间告警与自动扩容、快照空间回收策略
快照这东西,用起来很爽,但空间管理搞不好就是个坑。我见过太多团队,快照开着开着,存储池突然就满了,然后整个业务都跟着遭殃。说白了,快照不是免费的,它占用的空间你得心里有数。
这一节,咱们就聊聊快照空间怎么管。从预留空间怎么算,到告警怎么设,再到空间怎么回收,一条线捋清楚。
4.1 快照预留空间计算
先问个问题:你给快照留多少空间合适?留少了,快照写不下去,数据一致性就崩了。留多了,浪费存储,老板不高兴。
我个人习惯,先看数据变化率。你想想看,一个数据库每天写 10GB 新数据,那快照空间就得按这个量级来算。但光看一天不够,得看峰值。
核心公式:
快照预留空间 = 源数据大小 × 预期变化率 × 保留快照数量 × 安全系数
安全系数一般取 1.2 ~ 1.5,别卡太死。
举个例子:
| 参数 | 值 | 说明 |
|---|---|---|
| 源数据大小 | 500 GB | 业务卷总容量 |
| 日变化率 | 5% | 每天约 25 GB 数据变动 |
| 保留快照数 | 7 个 | 保留最近一周的快照 |
| 安全系数 | 1.3 | 留点余量,防止突发写入 |
| 预留空间 | ≈ 113.75 GB | 500 × 0.05 × 7 × 1.3 |
我在项目中遇到过一种情况:业务方说数据变化率只有 2%,结果上线后实际跑到了 8%。为什么?因为有个日志系统没算进去。所以我的建议是——先跑两周监控,拿到真实数据再定预留值。
小技巧:如果用的是 ZFS 或 btrfs,可以用 zfs list -t snapshot 或 btrfs qgroup show 查看每个快照的实际空间占用,比估算准得多。
4.2 快照空间告警与自动扩容
预留空间算好了,但业务不会按你的计划走。突发写入、异常流量,都可能让快照空间瞬间爆掉。这时候,告警和自动扩容就是救命稻草。
4.2.1 告警阈值怎么设?
我一般设三级告警:
- 警告级(70%):发通知,让运维看一眼。这时候还有操作空间。
- 严重级(85%):触发自动扩容流程,或者通知值班人员介入。
- 紧急级(95%):立即停止新快照创建,防止数据损坏。
你可能会问:为什么 95% 才停?因为有些文件系统在空间耗尽时,快照元数据写不进去,整个卷都可能挂掉。嗯,这个我吃过亏。
我曾经踩过的坑:有一次快照空间到了 98%,我心想「再撑一会儿」,结果文件系统直接只读了。所有写入都失败,业务中断了 20 分钟。从那以后,95% 就是我的红线,谁也别劝我放宽。
4.2.2 自动扩容怎么做?
自动扩容不是万能的,但能争取时间。常见的做法有两种:
- 动态卷扩展:如果底层存储支持在线扩容(比如 LVM、Ceph),直接给快照池加空间。
- 临时快照池:预留一个备用存储池,当主池空间不足时,自动把新快照写到备用池。
代码示例(基于 LVM 的快照池自动扩容脚本):
#!/bin/bash
# 快照池自动扩容脚本
THRESHOLD=85
POOL="/dev/vg_snap/snap_pool"
EXTEND_SIZE="10G"
USAGE=$(df -h | grep "$POOL" | awk '{print $5}' | sed 's/%//')
if [ "$USAGE" -ge "$THRESHOLD" ]; then
echo "[WARN] 快照池使用率已达 ${USAGE}%,触发自动扩容"
lvextend -L +${EXTEND_SIZE} $POOL
if [ $? -eq 0 ]; then
echo "[OK] 扩容成功,增加 ${EXTEND_SIZE}"
else
echo "[ERROR] 扩容失败,请手动介入"
fi
fi
这个脚本我放在 cron 里每 5 分钟跑一次。注意一点:自动扩容不能无限扩,得设个上限。我一般设最大不超过源数据卷的 2 倍。
4.3 快照空间回收策略
空间回收,说白了就是把没用的快照删掉,把空间腾出来。但怎么删、什么时候删,有讲究。
4.3.1 基于时间的回收
最常用的策略。保留最近 N 天的快照,更老的自动删除。比如:
- 保留最近 7 天的每小时快照
- 保留最近 30 天的每天快照
- 超过 30 天的全部删除
这种策略简单,但有个问题:如果某天数据出问题,你想恢复 45 天前的数据,对不起,已经删了。
4.3.2 基于空间的回收
当快照池使用率超过阈值时,按优先级删除最旧的快照。优先级规则:
| 优先级 | 快照类型 | 删除顺序 |
|---|---|---|
| 1(最先删) | 临时快照、测试快照 | 按创建时间从旧到新 |
| 2 | 日常备份快照 | 保留最近 3 个,其余删除 |
| 3(最后删) | 关键业务快照、归档快照 | 需人工确认 |
我的习惯:给每个快照打标签。比如 daily、weekly、critical。回收脚本根据标签决定删不删。这样比单纯按时间删灵活得多。
4.3.3 增量快照的回收陷阱
这里有个很多人忽略的点:删除中间的快照,不会释放全部空间。因为后面的快照可能还依赖前面的数据块。
举个例子:
- 快照 A(周一)占用 10 GB
- 快照 B(周二)基于 A,新增 2 GB
- 快照 C(周三)基于 B,新增 3 GB
如果你删了快照 B,A 和 C 之间的依赖链会合并。释放的空间可能只有 1 GB,而不是 2 GB。为什么?因为 C 引用了 B 的部分数据块,这些块不能删。
注意:在 btrfs 和 ZFS 中,删除快照是异步的。你执行删除命令后,空间不会立刻释放。得等后台的清理线程跑完。我建议删除后等几分钟再检查空间。
4.4 快照空间管理流程图
下面这张图,把整个流程串起来了。从预留空间计算,到告警监控,再到自动扩容和回收,一目了然。
4.5 总结几个关键点
聊了这么多,最后划几个重点:
- 预留空间别拍脑袋:先监控,再计算,留余量。
- 告警要分级:70% 提醒,85% 行动,95% 止损。
- 自动扩容设上限:别让快照池无限膨胀,否则源数据卷都受影响。
- 回收策略要灵活:按时间、按空间、按标签,组合使用效果更好。
- 删除快照不是立即释放:等后台清理完成,再确认空间。
嗯,快照空间管理这块,说白了就是「算、看、收」三个字。算清楚预留,看好告警,收好空间。做到这三点,快照就不会给你惹麻烦。