跳转至

LanceDB: failure modes and migration

Owner: Tianming

1) 引入 LanceDB 后的失败模式与防护点(红队视角)

  1. 数据一致性漂移(dual-write/异步写导致)
  2. 失败模式: 主库/对象存储已更新,但向量库写入失败、延迟或乱序,导致召回命中旧版本或缺失。
  3. 防护点: 写入必须带 doc_id + version;采用幂等 upsert;对“主库版本号”做读时校验;提供回填/重放队列。

  4. 索引/文件损坏与不可恢复的 silent corruption

  5. 失败模式: 本地/网络盘异常、进程中断、落盘不完整导致索引文件损坏,但服务仍可部分读,结果质量悄然变差。
  6. 防护点: 索引构建/compaction 生成校验和;启动时快速校验;定期抽样校验召回质量;关键表做快照与可回滚版本。

  7. schema/embedding 版本不兼容(维度变化、模型切换)

  8. 失败模式: embedding 维度变化或模型升级后,新旧向量混入同表,距离计算失真;或查询侧用错 encoder。
  9. 防护点: 将 embedding_model_id/dim 作为强约束;按模型版本分表或分区;查询路由必须显式指定版本;灰度期间双写双查对比。

  10. 查询质量退化但不报错(过滤条件/元数据错误)

  11. 失败模式: 元数据字段缺失/类型漂移导致过滤条件失效;返回结果看似正常但相关性下降。
  12. 防护点: 写入侧做 schema 校验;关键过滤字段设置 NOT NULL/默认值;监控 topK overlap、CTR/人工评审指标;对异常分布告警。

  13. 资源/成本 DoS(大批量写入、无界增长、热点查询)

  14. 失败模式: 重算 embedding 或批量导入时 CPU/IO 打满;向量表无限增长导致查询/compaction 变慢;热点 query 造成尾延迟。
  15. 防护点: 写入限流 + 分批;后台 compaction 窗口化;引入 TTL/归档;缓存热点 query;设定表级容量水位与自动降级策略。

2) 迁移路线(并行期)+ 验收指标 + 三层纳入方式 + 剪枝/去重/TTL/归档

2.1 迁移路线(并行期)

Phase 0 - 准备

  • 确定 doc_id 规范与版本字段(如 source_updated_at 或单调 version
  • 定义 embedding 标准: embedding_model_id, dim, normalize, chunking_strategy
  • 设计写入协议: upsert 幂等、失败可重放、可回填

Phase 1 - 并行写 (dual write)

  • 主流程写入现有检索系统的同时写入 LanceDB
  • 对 LanceDB 写入失败不影响主链路(降级/旁路)
  • 全量 backfill: 扫描主库历史数据补齐向量表

Phase 2 - 并行读 (shadow read)

  • 线上请求仍以旧系统返回为准
  • 同时对 LanceDB 做 shadow 查询记录对比指标(不影响用户)
  • 建立 “差异分析”: topK overlap、NDCG proxy、人审抽检、失败样本回放

Phase 3 - 灰度切流

  • 按租户/流量百分比切到 LanceDB 返回
  • 保留回退开关(秒级)
  • 持续观察质量/延迟/成本

Phase 4 - 收敛与下线

  • 当验收指标稳定达标后,逐步下线旧系统读路径
  • 保留旧索引一段时间作为回滚备份

2.2 验收指标(建议)

  • 质量
  • TopK overlap >= 0.7(与旧系统对比,按场景分桶)
  • 人工评审通过率 >= 90%(定义明确的标注标准)
  • 关键 query 的回归集:相关性不下降
  • 稳定性
  • 写入失败率 < 0.1%,且可重放成功率 ~100%
  • 查询错误率 < 0.01%
  • 数据一致性: “主库版本号校验失败” 低于阈值并可定位
  • 性能/成本
  • P95 延迟不劣于旧系统 + 10%(或按业务 SLO)
  • 存储增长可控(有剪枝/TTL/归档策略)

2.3 三层纳入方式(从轻到重)

  1. 旁路检索层(最轻)
  2. LanceDB 只做候选召回;最终排序仍由现有系统负责。
  3. 适合快速验证质量与成本。

  4. 主检索层(中等)

  5. LanceDB 成为主要召回来源;旧系统作为回退。
  6. 需要完善监控、回放、数据一致性校验。

  7. 检索 + 存储一体(最重)

  8. LanceDB 承担更多元数据/版本管理职责。
  9. 需要严格 schema、权限、合规、备份与灾备策略。

2.4 剪枝/去重/TTL/归档

  • 剪枝
  • source/tenant/doc_type 设定最大保留量与优先级
  • 低价值内容(低访问、过旧、重复)优先淘汰
  • 去重
  • doc_id + version 幂等;chunk 级别可用 content_hash 去重
  • 对重复 chunk 可只保留一份向量并多处引用(视实现复杂度)
  • TTL
  • 对时效性内容设置 TTL(如 30/90/180 天),过期进入归档表或删除
  • TTL 触发需可观测(删除计数、命中率影响)
  • 归档
  • 热/温/冷三层存储: 热表在线查询,温表低频查询,冷表仅离线回放
  • 归档后仍保留可重建索引的原始文本与 embedding 元信息

3) Tianming 视角 700 字说明

引入 LanceDB 的核心价值不在于“又换了一个向量库”,而在于我们能把检索链路的可控性做得更强:数据版本、向量版本、回放与对比、以及成本水位的治理。红队视角下最大的风险是 silent failure:写入没完全成功、索引部分损坏、schema 漂移、过滤字段缺失,这些问题往往不会以 500 报错出现,而是以“相关性下降、召回变差、线上指标缓慢滑坡”的形式出现。要避免这种慢性事故,迁移期必须把一致性与可观测性放到第一优先级:写入协议要幂等(doc_id+version)、失败可重放;查询侧要强制指定 embedding_model_id 与 dim,避免新旧向量混表;并且要有 shadow read 的对比体系,让差异可以被量化和定位。

在并行期,我建议坚持“先旁路、后主路、再收敛”的节奏。先用 LanceDB 做候选召回,不影响线上返回,同时建立一套回归集与人审抽检机制,把 topK overlap、关键 query 的相关性、延迟与失败样本都沉淀下来。只要这套对比闭环跑起来,我们就能很快知道问题出在 embedding、chunking、过滤字段,还是索引构建本身。随后进入灰度切流阶段,要确保回退开关足够快、足够简单,避免出现切流后无法回滚的局面。

成本治理同样需要前置设计。向量表天然会增长,如果没有剪枝、去重、TTL 和归档,短期看起来还能撑住,长期一定拖垮 compaction 与查询尾延迟。我的建议是按业务价值分层:热数据保证质量与时延,温数据用于补全召回,冷数据只保留离线回放能力。这样我们既能把新系统带来的收益兑现,也能把风险控制在可测、可回滚、可恢复的范围内。