如何存储实验配置并实时推送?
解读
在国内互联网、金融、IoT 等场景里,实验配置(灰度开关、推荐策略、模型超参)需要毫秒级生效且离线可回滚。CouchDB 的 MVCC、增量复制与 HTTP 长轮询正好满足“离线优先 + 实时推送”双重要求。面试官想确认:
- 你是否理解 CouchDB 的文档模型、变更 feed、过滤函数三大核心机制;
- 能否把“配置存储”抽象成单文档多版本而不是拆成多张表;
- 能否用国内可落地的长连接方案(阿里云 API 网关 + 函数计算、腾讯云 WebSocket 中转、或自研边缘节点)把 CouchDB 的
_changes事件推到移动端、网关或边缘盒子,并解决公网丢包、鉴权、流量计费问题; - 灰度过程中如何回滚到任意版本而不触发全量同步。
知识点
- 单文档配置范式:一个实验对应一条 JSON,内含
expId、layer、buckets、params、createAt、operator、rollbackRev字段,利用_rev实现版本追踪。 - _changes 参数组合:
feed=continuous&heartbeat=5000&filter=app/config&since=now可保持 TCP 连接不断,兼容国内 4G/5G 小运营商 NAT 超时。 - 过滤函数部署:在 design doc 里写
filter_config函数,按deviceIdHash % 100做灰度,减少 80% 下行流量,节省 CDN 费用。 - 权限隔离:国内合规要求“配置不可被终端篡改”,需给业务 App 分配只读 apikey,写权限走内网 VPN + 跳板机 + 二次审批,CouchDB 的
_security对象里只放{"readers": {"names": ["app_ro"], "roles": []}}。 - 边缘缓存:在华北、华南 K8s 集群各部署一套 CouchDB 节点,用自研同步控制器(基于
/_replicator但加限速、限带宽)把配置同步到边缘,延迟 < 200 ms;边缘节点只保存最近 7 天变更,节约磁盘。 - 实时推送兜底:若长轮询被运营商 RST,可降级到MQTT over TLS 443 端口,CouchDB 的
_changes事件通过 Node-RED 转发到 EMQX,移动端用阿里云物联网套件 SDK 订阅,保证 99.9% 到达。 - 回滚策略:利用
PUT /db/config_doc?new_edits=false指定旧_rev即可秒级回滚,无需重新发布版本;同时把回滚事件写入审计库(另一台 CouchDB),方便央行/证监会现场检查。
答案
步骤一:建模
在数据库 exp_config 里建文档
{
"_id": "home_feed_rank_v2.1.5",
"layer": "home_feed",
"buckets": {"0-9": "A", "10-99": "B"},
"params": {"lr": 0.03, "dropout": 0.1},
"operator": "zhangsan",
"createAt": "2024-06-01T12:00:00Z",
"rollbackRev": "2-abc123"
}
步骤二:写过滤函数
design doc _design/app 内
"filters": {
"config": "function(doc, req){ return doc._id.indexOf('home_feed')===0 && req.query.v === '2.1.5'; }"
}
步骤三:长轮询
客户端带鉴权头 Authorization: Bearer <只读token> 访问
GET https://couch-cn-north1.example.com/exp_config/_changes?feed=continuous&heartbeat=5000&filter=app/config&since=now&include_docs=true
步骤四:边缘同步
华北主节点写成功后,_changes 事件被同步控制器限速 1 Mbit/s 推到华南边缘,边缘 CouchDB 本地写入即返回 200,移动端就近访问,延迟从 800 ms 降到 30 ms。
步骤五:灰度与回滚
运营后台点击“回滚”,系统用旧 _rev 直接覆盖,移动端收到 _deleted_conflict 后自动拉取上一版本,零重启、零发布即可生效,满足国内 A/B 实验平台“白天高峰不敢发版”的痛点。
拓展思考
- 如果实验配置大于 8 MB(CouchDB 单文档默认阈值),可把静态资源拆到附件,文档里只保留
attName、md5,通过Range分片下载,节省移动端 4G 流量。 - 国内监管要求“配置变更留痕 5 年以上”,可在每个文档里加
signature字段,使用国密 SM2 私钥签名,CouchDB 的validate_doc_update函数验签,防止内部运维人员篡改。 - 当实验量达到 10 万级,
_changes过滤函数 CPU 飙高,可改用分层桶号前缀索引,把home_feed_rank_2.1.5拆成home/feed/rank/2/1/5,用_all_docs?startkey="home/feed/rank/2/1/"&endkey="home/feed/rank/2/1/\uffff"轮询,降低热路径计算。 - 若公司已有 Nacos、Apollo,可用双向桥接:CouchDB 只负责“离线场景”,在线服务仍走 Nacos;桥接服务监听 CouchDB
_changes,把变更同步到 Nacos,保持云边一致。