如何存储实验配置并实时推送?

解读

在国内互联网、金融、IoT 等场景里,实验配置(灰度开关、推荐策略、模型超参)需要毫秒级生效离线可回滚。CouchDB 的 MVCC、增量复制与 HTTP 长轮询正好满足“离线优先 + 实时推送”双重要求。面试官想确认:

  1. 你是否理解 CouchDB 的文档模型、变更 feed、过滤函数三大核心机制;
  2. 能否把“配置存储”抽象成单文档多版本而不是拆成多张表;
  3. 能否用国内可落地的长连接方案(阿里云 API 网关 + 函数计算、腾讯云 WebSocket 中转、或自研边缘节点)把 CouchDB 的 _changes 事件推到移动端、网关或边缘盒子,并解决公网丢包、鉴权、流量计费问题;
  4. 灰度过程中如何回滚到任意版本而不触发全量同步。

知识点

  1. 单文档配置范式:一个实验对应一条 JSON,内含 expId、layer、buckets、params、createAt、operator、rollbackRev 字段,利用 _rev 实现版本追踪。
  2. _changes 参数组合feed=continuous&heartbeat=5000&filter=app/config&since=now 可保持 TCP 连接不断,兼容国内 4G/5G 小运营商 NAT 超时。
  3. 过滤函数部署:在 design doc 里写 filter_config 函数,按 deviceIdHash % 100 做灰度,减少 80% 下行流量,节省 CDN 费用。
  4. 权限隔离:国内合规要求“配置不可被终端篡改”,需给业务 App 分配只读 apikey,写权限走内网 VPN + 跳板机 + 二次审批,CouchDB 的 _security 对象里只放 {"readers": {"names": ["app_ro"], "roles": []}}
  5. 边缘缓存:在华北、华南 K8s 集群各部署一套 CouchDB 节点,用自研同步控制器(基于 /_replicator 但加限速、限带宽)把配置同步到边缘,延迟 < 200 ms;边缘节点只保存最近 7 天变更,节约磁盘。
  6. 实时推送兜底:若长轮询被运营商 RST,可降级到MQTT over TLS 443 端口,CouchDB 的 _changes 事件通过 Node-RED 转发到 EMQX,移动端用阿里云物联网套件 SDK 订阅,保证 99.9% 到达。
  7. 回滚策略:利用 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 实验平台“白天高峰不敢发版”的痛点。

拓展思考

  1. 如果实验配置大于 8 MB(CouchDB 单文档默认阈值),可把静态资源拆到附件,文档里只保留 attName、md5,通过 Range 分片下载,节省移动端 4G 流量。
  2. 国内监管要求“配置变更留痕 5 年以上”,可在每个文档里加 signature 字段,使用国密 SM2 私钥签名,CouchDB 的 validate_doc_update 函数验签,防止内部运维人员篡改。
  3. 当实验量达到 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" 轮询,降低热路径计算。
  4. 若公司已有 Nacos、Apollo,可用双向桥接:CouchDB 只负责“离线场景”,在线服务仍走 Nacos;桥接服务监听 CouchDB _changes,把变更同步到 Nacos,保持云边一致