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 自动扩容怎么做?

自动扩容不是万能的,但能争取时间。常见的做法有两种:

  1. 动态卷扩展:如果底层存储支持在线扩容(比如 LVM、Ceph),直接给快照池加空间。
  2. 临时快照池:预留一个备用存储池,当主池空间不足时,自动把新快照写到备用池。

代码示例(基于 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 快照空间管理流程图

下面这张图,把整个流程串起来了。从预留空间计算,到告警监控,再到自动扩容和回收,一目了然。

快照空间管理流程图 1. 预留空间计算 2. 设置告警阈值 3. 监控快照空间 4. 判断使用率 低于阈值 继续监控 高于阈值 触发告警 5. 自动扩容 / 空间回收 6. 释放空间,恢复监控 循环监控 说明:虚线箭头表示循环监控流程,实线箭头表示正常流程

4.5 总结几个关键点

聊了这么多,最后划几个重点:

  • 预留空间别拍脑袋:先监控,再计算,留余量。
  • 告警要分级:70% 提醒,85% 行动,95% 止损。
  • 自动扩容设上限:别让快照池无限膨胀,否则源数据卷都受影响。
  • 回收策略要灵活:按时间、按空间、按标签,组合使用效果更好。
  • 删除快照不是立即释放:等后台清理完成,再确认空间。

嗯,快照空间管理这块,说白了就是「算、看、收」三个字。算清楚预留,看好告警,收好空间。做到这三点,快照就不会给你惹麻烦。