LanceDB: failure modes and migration¶
Owner: Tianming
1) 引入 LanceDB 后的失败模式与防护点(红队视角)¶
- 数据一致性漂移(dual-write/异步写导致)
- 失败模式: 主库/对象存储已更新,但向量库写入失败、延迟或乱序,导致召回命中旧版本或缺失。
-
防护点: 写入必须带
doc_id + version;采用幂等 upsert;对“主库版本号”做读时校验;提供回填/重放队列。 -
索引/文件损坏与不可恢复的 silent corruption
- 失败模式: 本地/网络盘异常、进程中断、落盘不完整导致索引文件损坏,但服务仍可部分读,结果质量悄然变差。
-
防护点: 索引构建/compaction 生成校验和;启动时快速校验;定期抽样校验召回质量;关键表做快照与可回滚版本。
-
schema/embedding 版本不兼容(维度变化、模型切换)
- 失败模式: embedding 维度变化或模型升级后,新旧向量混入同表,距离计算失真;或查询侧用错 encoder。
-
防护点: 将
embedding_model_id/dim作为强约束;按模型版本分表或分区;查询路由必须显式指定版本;灰度期间双写双查对比。 -
查询质量退化但不报错(过滤条件/元数据错误)
- 失败模式: 元数据字段缺失/类型漂移导致过滤条件失效;返回结果看似正常但相关性下降。
-
防护点: 写入侧做 schema 校验;关键过滤字段设置 NOT NULL/默认值;监控 topK overlap、CTR/人工评审指标;对异常分布告警。
-
资源/成本 DoS(大批量写入、无界增长、热点查询)
- 失败模式: 重算 embedding 或批量导入时 CPU/IO 打满;向量表无限增长导致查询/compaction 变慢;热点 query 造成尾延迟。
- 防护点: 写入限流 + 分批;后台 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 三层纳入方式(从轻到重)¶
- 旁路检索层(最轻)
- LanceDB 只做候选召回;最终排序仍由现有系统负责。
-
适合快速验证质量与成本。
-
主检索层(中等)
- LanceDB 成为主要召回来源;旧系统作为回退。
-
需要完善监控、回放、数据一致性校验。
-
检索 + 存储一体(最重)
- LanceDB 承担更多元数据/版本管理职责。
- 需要严格 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 与查询尾延迟。我的建议是按业务价值分层:热数据保证质量与时延,温数据用于补全召回,冷数据只保留离线回放能力。这样我们既能把新系统带来的收益兑现,也能把风险控制在可测、可回滚、可恢复的范围内。