从0到1手写向量索引(二):整体方案设计
一、需求分析
- 向量的检索:向量索引提供的主要功能。需要支持精确搜索,模糊搜索,批量检索等。
- 向量的存储:需要支持添加和删除功能,修改可以表示为先查询,如果存在则删除后再将新的内容写入。
二、技术选型
- 预期存在大量内存操作,对性能要求较高,编程语言以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核心数
- 对于超大规模数据集,需要支持分布式架构,多节点部署,允许在多台服务器上分布索引和存储
五、测试与优化
- 单元测试:对生产者、消费者、消息队列和存储等模块进行单元测试,确保各个模块的功能正确。
- 集成测试:测试整个系统的集成,确保各个模块之间的协作正常。
- 性能测试:测试系统的性能,如消息的生产和消费速度、系统的吞吐量等。
- 优化:根据测试结果对系统进行优化,如优化查询耗时,优化CPU使用率等。
六、Road map
- 定义通用查询接口
- 开发针对接口的单元测试
- 开发原文存储功能,无任何优化
- 开发暴力搜索功能,无任何优化
- 开发性能测试代码
- 根据性能测试结果和需求一步步增加功能
- 性能达到预定指标时,在此基础上开发一个智能问答server