从0到1手写向量索引(二):整体方案设计

130 阅读2分钟

一、需求分析

  • 向量的检索:向量索引提供的主要功能。需要支持精确搜索,模糊搜索,批量检索等。
  • 向量的存储:需要支持添加和删除功能,修改可以表示为先查询,如果存在则删除后再将新的内容写入。

二、技术选型

  • 预期存在大量内存操作,对性能要求较高,编程语言以C++为主,使用C++17或更新的版本
  • 操作系统只支持Linux,不考虑跨平台可移植性
  • 既然是手写,就规定边界是主体功能除STL库之外不依赖其他库,从0开始,周边功能可以使用第三方库
  • 目标是做library, 不是framework,也不是server,需要考虑通用性

三、起个名字

  • 方便后文指代
  • 代码中要定义命名空间使用
  • 暂时命名HyperVector,Hyper表示超前和高效,强调高性能

四、详细实现

1. 核心功能

  • 支持多种索引类型,包括倒排索引(IVF)、积量化(PQ)、HNSW等,以适应不同的搜索需求
  • 支持多种距离度量方式,如L2、内积等

2. 索引结构

  • 参考Faiss的设计,将KNN问题的解决过程抽象为train、add和search三个步骤
  • 从Index基类派生出各种功能实现或流程包装的Index子类,以支持不同的索引策略
  • 提供集中和分桶(IVF)两种存储方式,以及SQ和PQ两种量化编码工具

3. 并行化与分布式搜索:

  • 作为高性能索引,需要支持多线程并行,可以通过设置控制使用的CPU核心数
  • 对于超大规模数据集,需要支持分布式架构,多节点部署,允许在多台服务器上分布索引和存储

五、测试与优化

  1. 单元测试:对生产者、消费者、消息队列和存储等模块进行单元测试,确保各个模块的功能正确。
  2. 集成测试:测试整个系统的集成,确保各个模块之间的协作正常。
  3. 性能测试:测试系统的性能,如消息的生产和消费速度、系统的吞吐量等。
  4. 优化:根据测试结果对系统进行优化,如优化查询耗时,优化CPU使用率等。

六、Road map

  1. 定义通用查询接口
  2. 开发针对接口的单元测试
  3. 开发原文存储功能,无任何优化
  4. 开发暴力搜索功能,无任何优化
  5. 开发性能测试代码
  6. 根据性能测试结果和需求一步步增加功能
  7. 性能达到预定指标时,在此基础上开发一个智能问答server