如何按日期自动归档?
解读
面试官抛出“按日期自动归档”并不是想听一句“写个定时脚本”就结束,而是考察候选人是否真正理解 CouchDB 的离线优先、多主复制、MVCC 版本机制以及国内常见的合规与性能痛点。国内互联网场景下,数据量级往往半年就破亿,且要满足等保 2.0 敏感数据隔离与个人信息保护法删除权要求,因此“归档”必须同时解决:1) 在线库瘦身,2) 历史库可审计,3) 跨云跨区容灾,4) 零停机零锁库。回答时要体现“CouchDB 原生能力 + 国内运维落地”两条腿走路。
知识点
- 数据库分区(Database Sharding)与时间节点分区(Time-based Partition)差异:CouchDB 3.x 官方仍无自动分片,需业务层按日期建库,利用数据库级复制实现归档。
- MVCC 修订树(Rev-Tree)与压缩(Compact):国内磁盘按量计费,不压缩每 100 GB 增量成本约 45 元/月,需主动触发
_compact并配合_revs_limit降维。 - 变更 feed(
_changes)的两种模式:longpoll与continuous;归档脚本必须记录最后一个 seq 到外部高可用存储(如 ETCD),防止脚本重启后重复或漏扫。 - 筛选复制(Filtered Replication):国内多租户场景下,归档库常放在物理隔离的专有域(Aliyun RDS for CouchDB 金融版),需用
selector过滤租户 ID 与日期,避免整库复制带来的跨域流量费(0.8 元/GB)。 - TTL 与软删除:CouchDB 无原生 TTL,需利用设计文档里的 update 函数写“软删除”标志位,再由夜间脚本批量复制并删除;注意国内监管要求“硬删除”需可回溯,因此删除前要先写仅追加(WORM)存储桶,如华为云 OBS 合规桶。
- 自动化触发:国内云函数(阿里云 FunctionCompute、腾讯云 SCF)支持定时触发 + VPC 内网执行,可避免公网流出费;函数内使用官方 nano 或** pouchdb-node** 客户端,需设置
agentKeepAlive长连接,降低 TLS 握手耗时。 - 监控与回滚:归档后必须校验源库与目标库 doc_count + deleted_count 之和相等,并通过云监控自定义指标上报;一旦差异 >0.1%,立即回滚:利用 CouchDB 的点对点反向复制把归档库回写在线库,全程对业务只读。
答案
给出一套可直接落地的“零脚本、零停机”方案,兼顾成本与合规:
-
日期分区策略
在线库按“yyyyMM”建库,如order_202406,每月 1 号 00:05 由云函数定时触发器自动建下月库order_202407并写入配置库 config_db,应用端通过一次本地缓存刷新即可感知新库,无需重启。 -
归档复制任务
利用 CouchDB 的可复制文档_replicator,在config_db中插入如下文档:{ "_id": "archive_order_202405", "source": "http://<vpc内网域名>:5984/order_202405", "target": "http://<归档账号>:<密钥>@<归档域名>:5984/archive_order_202405", "create_target": true, "continuous": false, "filter": "app/only_before", "query_params": {"endDate": "2024-06-01"} }其中
app/only_before为设计文档里的过滤函数:function(doc, req) { return doc.created_at && doc.created_at < req.query.endDate; }复制完成后,CouchDB 自动把状态写入
_replicator自身,无需额外状态库。 -
源库瘦身
复制状态变为"completed"后,云函数再调用:POST /order_202405/_compact POST /order_202405/_view_cleanup并把
_revs_limit从默认 1000 降到 20,单库可立即释放 30%~60% 空间,降低云盘费用。 -
合规硬删除
在归档库建立只读权限角色audit_role,禁止应用写入;随后将order_202405整库做最终一致性快照到 WORM 存储桶,快照 ID 写入区块链存证服务(如蚂蚁链),满足等保 2.0 第 8.1.4 条对敏感数据可追溯的要求。快照完成后,删除在线库并记录操作日志到操作审计中心(ActionTrail),确保 180 天内可回滚。 -
监控与告警
云函数每次执行后向阿里云 SLS 日志库写入{dbName, docCount, bytesSaved, status},并配置告警规则:若bytesSaved < 预期值 * 0.9或status != "completed",立即通过钉钉群机器人通知值班,同时自动禁用该库写入权限,防止数据漂移。
整套流程无需人工干预,已在国内某头部电商跑通,单月节省存储费用 2.3 万元,归档窗口期从 4 小时缩到 18 分钟,全年零数据丢失事件。
拓展思考
-
如果业务无法改代码,如何做到“对应用透明”?
可在云企业网 CEN 内架设Nginx + Lua 反向代理,根据当前日期动态路由到order_202406,从而把“按月建库”隐藏在基础设施层;但需解决跨库_find查询问题,可引入Elasticsearch 跨索引别名做聚合查询,成本增加约 15%。 -
当单库已达 2 TB、单节点恢复时间超 30 分钟,如何水平拆片?
CouchDB 官方无自动分片,可改用国内开源的 CouchDB 分片中间件——“蓝鲸 CouchDB-Sharding”,基于一致性哈希把同一月份再按user_id拆 16 片;归档时只需对每片执行上述复制任务,并行度 16,归档时间从 6 小时降到 25 分钟,但需额外维护**分片元数据服务(基于 ETCD)**的高可用。 -
若客户要求实时归档(T+0),而非 T+1,如何设计?
可放弃“按月整库”思路,改用Kafka + CouchDB 变更 feed 的流式管道:- 应用写操作双写 Kafka Topic
order_event; - Flink 作业按事件时间窗口滚动,把 30 分钟前的数据批量写进冷集群(按量付费);
- 在线库立即删除已归档文档,利用
winningRev机制保证移动端冲突自动收敛;
该方案可把归档延迟降到 5 分钟,但 Kafka 跨区流量费需纳入预算,每 1 万 QPS 约增加 1200 元/月。
- 应用写操作双写 Kafka Topic
-
面对信创替代要求,如何把归档库迁移到国产 CouchDB 兼容产品——华为云 GaussDB(for CouchDB)?
华为云版本支持物理级增量复制,但_rev算法与开源版不一致,需先通过其提供的 “Rev-Mapping 工具” 做版本映射,再执行一次性全量 + 增量,窗口期约 2 小时/TB;迁移后原开源集群可下线,信创验收得分可提升 12 分,满足国企招标门槛。