问题的历史
从词汇搜索到语义检索的转变在过去十年中根本改变了数据基础设施的需求。早期的信息检索依赖于倒排索引和 TF-IDF 计算,但现代多模态 AI 系统需要在高维向量空间中进行近似搜索,这些空间的维度通常超过 1000。随着基于变换器模型的普及,生成了数十亿个密集嵌入,传统数据库无法高效地进行暴力扫描。挑战从简单存储演变为在地理分散的节点上维护近似最近邻图,同时与事务源系统保持一致性。
问题
根据 CAP 定理,向量数据库面临独特限制,因为精确的 k 最近邻计算需要对数据集的全球知识,从而使得分区容忍和低延迟在十亿向量规模下相互排斥。高维嵌入消耗大量内存——通常在使用 float32 的 1024 维度下,每个向量占用 4KB——造成数据引力问题,给边缘部署带来复杂性。此外,“维度诅咒”使得基于树的空间索引失效,因此需要采用更新代价高昂的基于图的算法,如 HNSW。在可变的事务数据存储 PostgreSQL 与不可变的向量索引之间保持一致性会引入双写异常,而跨区域复制索引则因嵌入负载大小而加剧带宽成本。
解决方案
采用基于单元的架构,利用层次可导航的小世界图和产品量化压缩,使查询时间降低到小于 10 毫秒,同时将内存占用减少 90%。区域向量单元通过 Apache Kafka 流和 Debezium CDC 连接器获取嵌入,确保真实数据库与索引构建的开销隔离。动态分片采用局部敏感哈希来将查询路由到特定分区,将搜索空间从数十亿个候选者缩小至数百万个。使用带有向量版本控制和软删除墓碑的最终一致性模型允许非阻塞索引更新,而 Raft 共识则协调各单元的元数据更改,而不集中处理热点查询路径。
问题描述
全球视觉商务平台 "LuxeSearch" 在时尚和家具类别中维护 4 亿个产品 SKU,需要视觉相似性搜索,用户上传照片以找到相同或互补的商品。遗留的 Elasticsearch 基础设施在 768 维 CLIP 嵌入的余弦相似度计算的计算负载下崩溃,导致在高峰流量期间的延迟激增至 800 毫秒。此外,产品元数据的更新在闪购期间发生频率达 50,000 个事务每秒,当并发更新与搜索操作发生冲突时,导致索引损坏,从而造成每小时超过 200 万美元的收入损失。
解决方案 1:单体全球集群
初始提案在 us-east-1 部署了一个单一的 Milvus 集群,并使用全球 CDN 边缘缓存查询结果集。该方法提供了强一致性保证,并通过维护单一的索引状态简化了操作开销。然而,亚太地区用户的跨区域延迟超过 180 毫秒,违反了小于 50 毫秒的移动应用程序要求,并且在假日购物季节单点故障的风险变得不可接受。
解决方案 2:夜间批处理区域索引
另外一种架构提出通过从 S3 快照夜间批处理作业重建区域 FAISS 索引。这实现了小于 5 毫秒的查询延迟,通过本地 CPU 推理消除了搜索过程中的网络往返。然而,24 小时的数据陈旧性导致客户对“幽灵产品”出现在视觉搜索结果中提出投诉,并且索引重建所需的六小时维护窗口违反了 99.99% 的正常运行时间服务水平协议。
选择的解决方案
团队实现了使用 Redis 及其 RedisSearch 模块的自主向量单元,用于包含按查询量排名前 10% 的热索引,由存储在 S3 中的内存映射 HNSW 图支持的冷数据。Debezium 将 PostgreSQL 的变更捕获到 Kafka,为区域本地索引构建器提供数据,这些构建器实现使用出口模式的增量 HNSW 更新。产品量化将 768 维的 float32 向量缩减至 96 字节的编码,召回率达到 98% 召回@10。该解决方案被选中,因为它在 500 毫秒内提供可调的一致性,处理每秒 100K 的嵌入更新而不阻塞查询,并在所有 12 个全球区域内保持 8 毫秒的 p99 延迟。
结果
经过六个月的生产运行,该架构实现了 99.97% 的可用性,支持每天 5000 万次视觉搜索,基础设施成本相比单体提案降低了 40%,通过智能分层。召回@10 指标稳固在 99.2%,超过了业务需求,系统在黑色星期五期间成功吸收了 300% 的流量激增,而无需人工干预或缓存风暴。
为什么欧几里得距离在高维空间中变得无效,这如何影响索引选择?
在超过 100 维的高维空间中,最近邻和最远邻之间的比率趋于 1,这是由于超球体表面的体积浓缩,导致欧几里得距离在统计上不可区分且在空间上无信息。这一现象使得基于树的空间划分(如 kd 树或 R 树)失效,而这些树依赖于有意义的距离差异来有效修剪搜索分支。因此,基于图的方法,如 HNSW 或 FAISS IVF 索引变得必要,因为它们通过相对邻域连接而非绝对坐标距离来导航接近性,尽管它们需要显著更多的内存和复杂的增量维护程序。
如何处理“双写问题”,当事务数据库和向量索引都必须原子更新时?
双写问题发生在 OLTP 存储和向量数据库之间的分布式事务失败时,导致搜索结果返回已删除的项目或因部分提交状态而错过新嵌入。架构师应避免实现会阻碍小于10毫秒延迟要求的双阶段提交协议,而应采用事务出口模式,在 ACID 事务内 PostgreSQL 写入出口表。Debezium 读取此出口并异步发布到 Kafka,确保向量索引构建器的准确一次交付;向量条目包含单调版本号,搜索 API 通过验证 OLTP 元数据存储来筛选结果,以排除过时版本,有效掩盖不一致性而不阻塞查询。
在增量更新期间,基于图的 ANN 索引对内存的影响是什么,如何减轻写放大?
HNSW 和类似的图结构在边插入期间需要锁定或写时复制机制,导致显著的写放大,因为添加一个向量可能会触发数百条边的重新连接以保持层次可导航性特性。在内存受限的环境中,这造成页面故障和垃圾回收压力,当工作集合超出 DRAM 容量时,查询延迟可能不可预测地降低。减轻策略包括使用分层存储,其中热图层保留在内存中,冷图层保存在持久内存或快速 NVMe SSD 中;将更新批处理到微分段,利用日志结构合并技术在低流量期间异步合并;以及采用量化感知图构建,其中压缩向量决定图拓扑,同时原始向量仅在最终重排名时提取,从而在保持目标召回指标的同时减少 70% 的内存消耗。