Skip to content

存储、索引与缓存的一致性

哪个系统是事实来源

系统保存内容可以丢弃重建吗典型错误
业务数据库订单、退款、库存等事实依赖数据备份/确定性生成用控制库账户执行生成 SQL
PostgreSQL Control Plane元数据、指标、关系、权限、版本、评测需要备份恢复直接改已发布指标
OpenSearch文本、关键词、别名与值索引可由控制资产重建mapping 未更新、旧列被召回
Milvus各类语义向量可按源数据与模型版本重建维度变化还写旧 collection
Redis缓存、会话、配额计数、锁缓存可丢;会话与任务需明确耐久要求撤权后仍命中旧结果

Redis 同时服务 broker 与缓存时需要明确命名空间、容量和驱逐策略。生产是否拆实例由 V4 容量与可靠性验收决定,不能假设驱逐缓存对排队任务无影响。

发布一份 schema 的建议过程

text
采集业务库 → 控制库保存 snapshot(version=N, building)
          → Celery 构建 OpenSearch 与 Milvus 的 N 版本
          → 校验数量、版本与可检索性
          → 标记 N ready → 切换 active_version
          → 失效旧缓存 → 延迟清理旧索引

这是本次提出的落地方案,不在三种数据库间建立分布式事务。通过版本快照和发布指针避免混用半成品;失败任务记录原因并幂等重试。V0 可先实现简单 job 表和明确重建命令,达到需要时再引入更复杂的 outbox。

缓存键必须反映查询语境

概念示例:

text
query:{datasource}:{data_version}:{schema_version}:{semantic_version}
     :{policy_fingerprint}:{model_prompt_retriever_version}:{normalized_request_hash}

真实在线数据通常没有每秒递增的完整 data_version,因此结果缓存还需要 TTL 或上游更新时间水位策略;固定 Benchmark 才能使用精确数据快照版本。

请求 hash 应包含时间窗口、参数、会话解析结果和结果限制。两个用户权限看似相同但列脱敏策略不同,也不能共享未经再次验证的缓存值。缓存命中仍记录 trace,并在撤权时失效。

Celery 的幂等不是可选装饰

一次元数据索引任务在 worker 断连后可能重新投递。用 datasource + snapshot_version + index_type 建立逻辑任务键,对任务状态和分批写入去重;重试不能自动推进发布指针。分布式锁使用持有者 token、有效期和安全释放,不能只依赖“执行完 DEL lock”。

失败实验

  • 构建 N 版本 Milvus 时断连:查询继续使用 N-1,管理端看到失败任务。
  • 发布指标新版本后立刻查询:本次响应各层都使用同一语义版本。
  • 撤销用户成本列权限后重复同一问题:缓存不能泄露原结果。
  • 清空一个派生索引:能够重建,不能通过手动写索引修补控制库缺失。

这些实验分别对应 V0-S05、V3-S02 和 V4-S02。

需求 → 代码 → 验证 → 复盘