最近买了一本《从零构建向量数据库》读了一下,这里简单记录一些笔记。
TLDR:
我感觉整体内容不多,尤其是我比较关注的向量算法/存储格式各种相关的地方。但是这本书讲的比较全,抛去向量的地方,还有挺多周边的工作,但是和向量关联都不大了。
整体来说适合刚对数据库有一定了解的人读一读,如果对这块比较熟悉的话,基本上就不用看了,或者速度一下2H也够了。
chp2
- 向量数据库的发展受益于深度学习的发展,让embedding这个技术有了更好的发挥空间
- 深度学习模型可以比较好的处理非结构化的数据(通过转化成embedding),然后利用向量数据库做存储,以及近似查询
-
2017年,Facebook的FAISS开源,实现了多种向量索引的类型
-
同时期,HNSWlib开源,基于HNSW算法
-
Zilliz(Milvus), Pinecone, Qdrant, Chroma等公司开发向量数据库
- 其他成熟企业也开始开发自己的向量数据库
- 传统数据库开始集成向量管理功能(pg vector 2021年,redis vector search 2022年)
有一个挺不错的产品能力对比:
有一些典型的技术架构:
* 插件式,redis vector search
* vector模块的输入和输出以json形式进行交互,对redis内核影响很小
* 单机,chroma
* 感觉是偏嵌入式的东西
* shared nothing架构
* 这本书的作者所在腾讯的向量数据库就是这个。单机和单机数据库基本类似
* shared storage(Pinecone/Milvus)
* 架在S3上
* 并且这套基本架构都是写入请求走MQ,应该是做批量写入什么的。也和业务场景类似,因为向量数据库和在线业务还是有一些区别,对实时读写要求不高
chp3
- 向量数据库有一些基本的概念
- 库
- 集合(类似表,用来指定索引类型)
- 文档(对标一行)一般是弱类型的。然后会有一个字段用来指定具体的向量数据
- 搜索的时候可以通过文档中的向量字段做近似搜索,也可以用其他字段做进一步的过滤
- 基本的索引类型
- 扁平索引
- 铺平存储,查询的时候一个一个查。查询精度/召回率高
- HNSW
- 查询性能好,吃内存多
- IVF索引
- 基本思路是对向量数据做聚类(细节我也不太清楚)
- 召回率低,性能好
- 扁平索引
- 部分索引类型不支持动态写入,所以需要周期性重建。所以向量数据库也提供了重建索引的能力
-
关键指标
- 除了数据库常看的吞吐,延迟,主要还有一个召回率。用来看近似搜索的数据是不是正确的
- 高阶能力
- 别名机制:因为可能业务有切换向量模型的需求,需要一把切换到新的数据上,不能慢慢写入。所以有一个表的别名机制,可以把数据先写到一个新表上,然后alias旧表,这样旧表的流量就导入到新表上了
- 向量化:就是向量数据库自动支持向量化
chp4
- 一大部分是将flat索引,和hnsw怎么构建的。这里他貌似是用的faiss中的代码,如果希望研究的话,可以直接去看看faiss的代码
- ckpt/WAL的机制是:
- 写数据会写WAL,就是本次写入的一行数据
- 全量ckpt,然后截断WAL。
- 没啥增量/部分ckpt的能力
chp5
- 实现分布式向量数据库,上面套了NuRaft
- 这里整理上也没啥要说的,不过他这里就直接用了raft的log/snapshot的逻辑。状态机就是纯内存的东西了。
- 然后引入了metaserver用来做分片管理,以及节点的路由。比如写入请求路由到raft leader,读请求可以round robin
- 引入了proxy,用来和metaserver交互确定路由信息,然后请求raft组中的节点
- metaserver中还有故障探测的能力(虽然比较基础,但是比较适合新人了解这些基本的流程)
-
有一个我之前没想到的,是这里的分片,如果加了向量数据库的分片,然后做近似搜索的话,会把请求发到所有的节点请求top k,然后在sdk再做merge
chp6
- 性能优化
- 利用SIMD做向量计算,计算相似度会快很多
- 查询计划(向量+filter一起搜索的时候,可以有一些策略,比如先filter,再向量什么的)
- 优化通信协议,没啥看的
- 成本优化
- 优化TCO
- 混部,把metaserver/proxy/vector db server一起部署
- 把盘拉远,放到EBS上。就是resource disaggregation的优势。这样也不用走raft了
- 易用性优化
- 这里还教了怎么搞一个python sdk封装下向量数据库的使用
- 然后还有在python里搞jwt鉴权
- 数据备份,把snapshot/wal备份到对象存储中
chp8
最后是一些向量数据库的展望:讨论了一下向量数据库的定位。是说之前的数据操作方式是:
业务 -> 程序员 -> 数据/算力。通过程序员来操作数据,调动算力。
有了大模型之后,变成了人通过自然语言和大模型交互,然后大模型去通过向量数据库来和数据交互(因为向量数据库可以embedding统一数据格式,无论什么都用embedding搜)。这样变成了人通过自然语言调度算力了。
这块我还没有什么很深入的思考,因为既然大模型是用自然语言做处理,那让大模型去和向量数据库也不一定是更好的选择,可能选择一些自然语言语意比较强的,比如通过SQL去交互更好?
文章评论