当网关磁盘仅剩 5% 时,如何自动触发“purge”旧版本日志?
解读
面试官把“磁盘只剩 5%”与“CouchDB purge”两个关键词绑在一起,考察的是:
- 你是否理解 CouchDB 的 purge 与 compact 的本质区别(purge 真正删除墓碑,compact 只是回收空间);
- 你是否能在 生产级网关/边缘节点 上,用 最稳、最可控、最可观测 的方式,把“磁盘水位 → purge → 空间回收 → 业务无损”整条链路串起来;
- 你是否熟悉 国内运维生态(systemd、crontab、Prometheus、阿里云云监控、华为云 AOM、开源 Alertmanager 等)并能把 CouchDB 的 purge 接口无缝接入。
一句话:不是问“purge 命令怎么敲”,而是问“在只剩 5% 的生死线时,如何 100% 自动、安全、可灰度地 purge 掉旧版本日志,并把现场留下来”。
知识点
- CouchDB 墓碑机制:delete 操作只加 _deleted:true,数据仍在文件里,只有 purge 才能从 B+Tree 里物理摘除。
- purge 与 compact 区别:compact 回收已删文档空间,但墓碑还在;purge 把墓碑也清掉,真正缩小 .couch 文件。
- purge 请求格式:POST /{db}/_purge JSON {"docid":["rev1","rev2"]},返回 201,异步执行,需再 GET /_active_tasks 观察。
- 磁盘水位判断:
- 系统层:statvfs、df -h、node_exporter 的 node_filesystem_avail_bytes / node_filesystem_size_bytes。
- 网关层:CouchDB 本身不暴露磁盘百分比,需要 sidecar 脚本或 exporter。
- 国内常用告警通道:Prometheus + Alertmanager webhook、阿里云 CMS 事件、华为云 AOM 策略、蓝鲸监控、夜莺。
- 安全阈值:
- 5% 是红线,触发 purge;
- 但 purge 前必须二次确认“过去 5 分钟写入速率 < 阈值”,防止 purge 与高峰写入抢 IO;
- 保留最近 N 小时或 M 次版本的日志,避免 purge 过度。
- 自动化手段:
- systemd path 单元监控 .couch 所在挂载点;
- shell + jq 轮询;
- Python/go-sidecar 暴露 metrics;
- 最终统一调 CouchDB _purge 接口。
- 可观测:
- 每次 purge 记录 docid 数量、rev 数量、耗时、回收空间;
- 写本地日志并通过 stdout 让 systemd/journal 收集,同时推送到 Loki/ELK。
答案
给出一套在国内生产环境落地过、灰度可控、可回滚、可观测的完整方案,按“监测 → 决策 → 执行 → 观测 → 兜底”五步回答,面试时可直接口述。
-
监测层(秒级)
- 在网关宿主机部署 node_exporter,采集 node_filesystem_avail_bytes 与 node_filesystem_size_bytes;
- Prometheus 规则:
(node_filesystem_avail_bytes{mountpoint="/var/lib/couchdb"} / node_filesystem_size_bytes) < 0.05
持续 30s 即触发告警,通过 Alertmanager webhook 推送到自研 purge-gateway 服务(或脚本)。
-
决策层(防抖动)
- purge-gateway 收到告警后,先调 CouchDB _stats 取 httpd_request_methods.POST 速率;
- 若过去 5min 平均 POST QPS > 200(业务高峰),则延迟 10min 再评估,避免 IO 抢占;
- 否则进入执行阶段。
-
执行层(灰度 purge)
- 扫描 日志库 log_gateway_yyyyMM 的 _changes?filter=_doc_ids 或 _all_docs,按业务规则选出 7 天前且已删除 的文档 id 与 rev;
- 每批 1000 条打包,POST /log_gateway_yyyyMM/_purge,立即返回 201;
- 循环调用直到处理完或磁盘回到 >10% 即停止;
- 全程记录 purge 批次号、耗时、回收字节数到本地 /var/log/couchdb_purge.log。
-
观测层
- purge-gateway 把“couchdb_purge_docs_total”“couchdb_purge_reclaimed_bytes”写成 Prometheus metrics;
- Grafana 大盘展示:磁盘曲线与 purge 事件竖线对应,方便复盘;
- 若 purge 后 2min 磁盘仍未回升,则升级告警给值班电话。
-
兜底与回滚
- 所有 purge 请求前,先对库做 增量备份(s3cmd sync 到阿里云 OSS 或华为云 OBS);
- 提供 一键回滚脚本:从备份恢复单库到新建库,验证后切流量;
- 若出现 purge 误删活跃 rev,CouchDB 会返回 409,脚本捕获后自动跳过并告警,不会破坏数据一致性。
通过以上五层,把“只剩 5%”的极端场景变成可灰度、可观测、可回滚的例行操作,既体现对 CouchDB purge 机制的深入理解,也符合国内互联网“监控+告警+自动化+兜底”的运维规范。
拓展思考
-
为什么不直接 rm 日志文件?
网关节点常是 移动设备离线同步源,rm 会导致 其他副本重新拉取全量,引发同步风暴;purge 只删墓碑,不会触发 replication 风暴。 -
如果磁盘瞬间掉到 0%,purge 也跑不起来怎么办?
提前设置 2% 预留空间(tune2fs -m 2)给 root,确保脚本可写;同时把 CouchDB 的 pid 与 view 索引文件放到独立小盘,保证核心进程不死。 -
云厂商托管 CouchDB(阿里云 HBase Serverless、腾讯云 TCB)不让调 _purge 接口?
国内主流托管版通常 屏蔽 _purge;此时应改用 TTL 插件(若云商支持)或 主动把旧日志写入冷存(OSS)后整库删除,再重建空库,面试时可作为“Plan B”抛出,体现 多云场景 的兜底思路。 -
如何验证 purge 真的释放了空间?
除了看 df,还要 GET /{db}/_info 的 disk_size 与 data_size,计算 fragmentation = 1 - data_size/disk_size;purge 后 fragmentation 应显著下降,否则说明 compact 没跟上,需要再调 /_compact。 -
未来演进:把“磁盘 5%”换成“成本 5%”
在 Serverless 计费场景,磁盘不限但 每万次 purge 请求收费;此时策略改为 按“存储费用 > 预算 5%”触发 purge,把同一套框架接入 云账单 API,体现 FinOps 思维,可让面试官眼前一亮。