概述
百度智能云VectorDB产品基于自研的“莫愁”向量数据库内核构建,充分利用了百度内部在分布式存储&数据库领域的成熟经验,实现了高可靠、高可用、强扩展和大规模的能力。
产品架构
VectorDB产品是经典的托管型产品架构,除了前端和控制台(Console),后端由两大层次构成:管控层和内核层,分别简介如下:
管控层 :与控制台协作,完成产品实例的购买/释放/计费/扩缩容等各类操作,并将产品信息通过控制台暴露给客户;在内部,管控层负责创建虚拟机资源并在虚拟机中完成数据库内核系统的部署以及后续的运维和监控等。 内核层 :数据库内核系统,提供数据库核心能力,负责完成客户的一些列数据相关的操作,例如建库建表,增删查改等。
因此,我们可以看到,VectorDB产品的接口被划分为OpenAPI和SDK两大部分。其中OpenAPI对应的是管控层,负责完成一些控制台和管控层面的操作,SDK(包括相应的HTTP API)负责与莫愁内核交互,完成各类数据库访问和操作。
内核物理架构
在物理架构层面,莫愁内核由代理节点、数据节点和管理节点等角色构成,分别简介如下:
代理节点(Proxy) :一组无状态,采用对等部署模式的节点,负责接入、转换并执行用户的请求,支持负载均衡。
管理节点(Master) :集群的中控角色,管理集群的物理拓扑、逻辑拓扑、数据库元数据、各类资源等,基于Raft协议构建,支持高可用。
数据节点(DataNode) :集群的数据服务角色,内置朱雀引擎 ,提供标量/向量数据的存储、索引和检索等服务,负责数据的增删改查和检索等,是数据流的核心。通过Raft协议管理表/集合数据的分片及其副本,支持自动Failover和弹性伸缩等。
下图展示了这些节点之间的关系:
从资源层面来看,VectorDB的一张表,支持横向划分为多个分区,每个分区称为一个Tablet。支持设定分区的副本数(Replication),系统自动将每个分区的不同副本尽量分布到不同的数据节点上,尽可能降低数据节点故障对各副本的影响,尽可能的实现更高的可用性和可靠性。副本之间,采用Raft一致性协议进行管理,多个副本之间自动选主并由主副本来接受更新类操作。当存在数据节点宕机导致某些副本缺失之后,Master会检测到该异常,然后找到一个合适的数据节点,触发对该分片建立新的副本,这就是自动Failover机制。此外,Master还会频繁检测各个数据节点之间的副本数(或主副本数)或者数据量是不是处于均衡的状态,如果出现了严重的不均衡,则会触发一系列的再均衡机制,具体而言,就是计算出哪些副本放到哪些节点会更合适,并建立副本迁移任务,推进副本迁移,最终实现平衡。通过上述的各类机制,可以轻松实现自动化地应对数据节点的上下线,从而支撑弹性伸缩。
Raft协议基于多数派原理,因此,在一个Raft复制组中,只要大多数副本正常,那么就不会影响整个复制组的更新操作,从而可以容忍少数副本异常,实现更高的可用性。在成熟的分布式实践中,如果对可用性没有极为苛刻的要求,推荐采用3副本即可,3的大多数是2,因此在一组3副本的复制组中,可以容忍1个副本异常,一般可以实现99.9%~99.99%的可用性(可用性还受其它因素影响)。若副本数只有2,由于2的大多数仍然是2,故无法容忍任何副本异常。另一方面,若业务对可用性有着极高的要求,那么可以考虑采用更高的副本数,例如采用5副本,那么可以容忍2个副本异常。当然,较高的副本数也会带来较高的资源重复代价,在设定这些分布式层面的参数时,建议客户根据业务的实际需求来权衡可用性、可靠性以及资源成本来综合考量。
在VectorDB产品的管控层面,当发现有虚拟机节点宕机时,会自动创建出新的虚拟机来代替故障的虚拟机,然后通过莫愁内核的管控接口(不对客户暴露)执行内核系统的节点上下线机制,当内核系统收到新的节点上下线时,通过上述的机制自动化地完成副本再均衡。这一切操作对客户都是透明的,轻度异常情况下,基本不会影响客户的正常使用。
VectorDB产品的管控,会对每个数据库实例自动创建一个VIP,并将该集群所有的代理节点都绑定到该VIP。当用户通过该VIP访问数据库时,会自动通过负载均衡机制将用户的HTTP请求均匀分发给每一个代理节点。只要不是所有的代理节点都异常了,客户的访问一般不会受到影响。
逻辑概念与架构
从逻辑层面来看,数据库的概念包括库、表、字段,除此之外还包含索引以及字段的各类属性等概念,我们先通过一张图来了解一下这些逻辑概念之间的关系:
下面对上述概念进行详细描述:
Instance(实例) :一个实例就是一个基本的产品对象,从产品层面看,实例是各类管控操作的基本单位;从内核层面看,一个实例包含且仅包含一个完整的分布式数据库集群;从逻辑资源层面来看,一个实例可以包含多个库(Database)。
Database(库) :在一个实例内部,库就是顶级的资源概念,一个库内部可以包含多个表(Table)。通常而言,不同的业务建议建立不同的库,从而实现隔离。
Table(表) :表是数据库中最核心的概念之一,它定义了数据的组织形式,包括该表有哪些行或者记录(Row)、Schema详情,以及一些统计信息(Statistics)等。表也是逻辑概念和物理概念的正交点。通常而言,一个库中的多个表,共同服务于该库对应的同一个业务。
Statisitics(统计) :表的统计信息,例如有多少行、占用了多少存储空间等等。
Schema(模式) :Schema是描述表的形态和行为的元信息,Schema描述了该表的详细情况,例如包含哪些字段(Field)及字段的属性,对哪些字段建立何种类型的标量索引(Scalar Index),对哪些字段建立何种类型向量索引(Vector Index)等等。
Field(字段) :字段又称为列(Column),一般来说,字段不再进一步划分为更小的单位了(复合类型字段除外),字段会存在非常多的属性,通过这些属性可以告知数据库如何处理该字段对应的数据。
Scalar Index(标量索引) :针对标量字段建立的各种索引,用以加速基于标量字段值的精确查询/检索。
Vector Index(向量索引) :针对向量字段建立的各种索引,用以加速基于向量字段值的近似检索或暴力检索。
VectorDB的字段当前支持如下属性:
Primary Key(主键) :表明某字段是否是主键,在数据库中,主键是用来区分不同记录的关键字段。
Partition Key(分区键) :表明某字段是否是分区键,在数据库内部,通过计算行的分区键值的哈希值,然后对分片数量取模,就可以得到该行所对应的目标分片。在VectorDB中,当分区键是某个主键字段时,则主键取值是全表唯一的;若分区键是独立指定的,并非某个主键字段,则主键值仅在分片内部唯一。不论如何使用主键和分区键,主键值加上分区键值始终是全表唯一的。
Auto Increment(自增) :表明某字段是否由数据库内部自动通过自增的方式赋值,用户在写入一行时不需要指定自增字段的值,该属性仅适用于主键字段。
Not Null(非空) :表明某字段是否允许空值,用户在写入一行时不需要指定可空字段的值。主键、分区键、索引键以及向量字段默认为非空。
Data Type(数据类型) :字段的数据类型,VectorDB支持非常丰富的标量/向量数据类型,各数据类型的详细说明请参见数据类型 。
Sort Type(排序类型) :字段的排序类型,指明了在排序时,该字段的比较采用升序(Ascend)还是降序(Descend)。该属性仅适用于主键和索引键,目前不对外暴露,默认为升序。
VectorDB已经支持和即将支持的标量索引类型说明如下:
Primary Index(主键索引) :主键索引是根据主键取值的顺序来组织数据存储的索引,用以加速基于主键取值的查询/扫描操作等。主键索引是数据库默认存在的索引,无需特殊指定。
Secondary Index(二级索引) :二级索引是相对于主键索引而言的。业务如果存在较多的根据某个非主键字段的取值进行查询或者过滤的操作,那么可以考虑针对该字段建立索引,通过该索引,可以快速定位到该行的主键取值,然后通过主键取值快速查询整行。VectorDB的一个二级索引只支持一个字段,但可以对一个表的不同字段建立多个不同的二级索引。
Inverted Index(倒排索引) :倒排索引是服务于基于关键词的全文检索能力的索引机制,倒排索引还涉及到文本分词技术,所以一般只适用于字符串或者文本类型字段。
VectorDB已经支持和即将支持的向量索引类型说明如下:
FLAT :平坦向量索引,其本质是没有索引,故亦可理解为暴力检索(Brute Force),可以提供100%召回率(Recall)的向量检索能力,但是检索过程计算开销大,性能相对较低,仅适用于数据量较小同时对检索召回率有极为苛刻要求的场景。相比于没有索引,FLAT索引会将向量数据进行全内存放置,这是二者之间的关键区别。
HNSW :HNSW的全称是Hierarchical Navigable Small World,即分层可导航小世界,是一种经典的图结构索引,该索引的优势在于性能和召回率都比较稳定,整体效果受向量数据集的分布/倾斜的影响很小。召回率可根据参数来定制,可高可低,性能则与召回率呈相反的关系,其整体性能远超暴力检索。该索引有所不足的是,向量数据需要全部缓存到内存,同时图结构的边信息也会带来一定的额外内存开销(这部分开销在FLAT索引上是没有的)。HNSW索引是目前最为广泛使用的索引方法之一。
HNSW_PQ :PQ的全称是Product Quantization,即乘积量化。HNSW_PQ即基于HNSW的PQ量化索引,通过引入PQ量化机制,减少HNSW原生索引对内存的占用,但会导致一定程度的召回率下降。
HNSW_SQ :SQ的全称是Scalar Quantization,即标量量化。HNSW_SQ即基于HNSW的SQ量化索引,通过引入SQ量化机制,减少HNSW原生索引对内存的占用,但会导致一定程度的召回率下降。
Puck :Puck是百度搜索部门自主研发并发展出来的一种向量索引,在百度内部被广泛使用。该索引基于倒排思想(类似IVF),但在基础倒排模式上进行了大量的改进和优化,大大提升了索引的效果。
Puck_PQ :Puck_PQ即基于Puck的PQ量化索引机制,通过引入PQ量化机制,减少Puck原生索引对内存的占用,但对召回率有少量影响。
数据库引擎
百度智能云针对VectorDB自研了高性能数据库引擎——朱雀,具备如下强大的能力:
⽀持常⻅标量类型数据、文本类型数据、稠密浮点向量、稀疏浮点向量和二进制向量。
⽀持Schema,⽀持多主键、⾃增主键、分区键、多向量字段,支持列族。
⽀持标量数据的⼆级索引,支持文本数据的倒排索引,⽀持各类丰富的稠密向量索引和稀疏向量索引,支持过滤索引。
⽀持标量数据的点查、扫描和带条件查询,⽀持稠密向量检索、稀疏向量检索和二进制向量检索,⽀持带任意标量过滤条件的向量检索。
⽀持关键词和全⽂检索,集成百度NLP中英文混合分词器。
⽀持基于上述各类检索模式的多路混合检索以及结果的融合排序。
⽀持标量数据和向量数据的增、删、改,⽀持批量处理。
基于LSM模型,支持行存、列存、行列混存。
支持KV分离存储模式。
支持压缩和透明加密。
支持快照及恢复。
支持引擎内再分片,支持自动化及细粒度向量索引构建调度。
支持SIMD指令集优化、CPU硬件优化和其它硬件优化等。
数据库引擎的逻辑架构如下图所示: