简介:Vearch 是一个分布式向量搜索系统,可用来存储、计算海量的特征向量,为 AI
领域的向量检索提供基础系统支撑与保障。该系统能够广泛地应用于图像, 音视频和自然语言处理等各个机器学习领域。本篇文章主要是介绍Vearch v3.2.0版本的更新内容,如果你是第一次接触Vearch,可以在这里看到更多关于Vearch的介绍文档Wiki。另外提供Vearch一键式安装脚本百度网盘, 提取码: 6u4b; 谷歌云盘, 脚本使用方式参考BinaryInstallation.md。
v3.2.0 是针对原有版本的一次重大更新,新版本拥有更丰富的API,更好的性能和更稳定的服务。
v3.2.0 版本之前只支持单条记录查询和删除,如果需要删除多个指定的id,就必须使用循环遍历的方式,v3.2.0版本开始支持批量查询和删除功能,具体使用方式如下:
# 获取单个ID的全部字段信息
curl -XGET 127.0.0.1:9001/your-db-name/your-space-name/id1
# 获取多个ID的全部字段信息
curl -XGET 127.0.0.1:9001/your-db-name/your-space-name /id1,id2,id3
# 删除单个ID
curl -XGET 127.0.0.1:9001/your-db-name/your-space-name/id1
# 删除多个ID
curl -XGET 127.0.0.1:9001/your-db-name/your-space-name/id1,id2,id3
curl -H "content-type: application/json" -XPOST -d'
{
"query": {
"ids": ["id1", "id2"],
"fields": ["your-field1", "your-field2"]
}
}
' 127.0.0.1:9001/your-db-name/your-space-name/_query_byids
根据用户反馈,v3.2.0版本之前使用Vearch进行搜索时经常需要现根据id查询出该id对应的向量,然后再拿获取到的向量进行相似搜索,每次search都需要两次请求。为了方便用户使用起来更方便,我们添加了通过id直接进行相似搜索的接口,使用方式如下:
curl -H "content-type: application/json" -XPOST -d'
{
"size": 50,
"query": {
"ids": ["id1"],
"sum": [{
"field": "vector",
"min_score": 0.7
}]
}
}
' 127.0.0.1:9001/your-db-name/your-space-name/_query_byids_feature
gRPC是一个高性能、通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf(Protocol Buffers)序列化协议开发,且支持众多开发语言。v3.2.0版新增gRPC接口,可以支持多种语言通过TCP调用Vearch。通过TCP调用,不仅减少建立连接的开销还减少了HTTP接口中JSON序列化和反序列的消耗
使用案例可以参考grpc_client_test.go, 后续会提供go、java、c和python的客户端。
max_size
的移除:v3.2.0版本之前建表时需要通过设置max_size
来一次性申请系统所需要的内存,v3.2.0之后删除了这一特性,内存会随着插入记录数的增加而递增。注意:用户使用的时候要注意内存的消耗,当内存不足时可能造成系统的崩溃!metric_type
的移除:v3.2.0版本之前建表时需要设置metric_type
为InnerProduct
或者L2
, v3.2.0之后该参数移动到search的时候指定,具体参考search document by query and vector for GPU。store_type
的修改:v3.2.0版本之后store_type
的值在原有的MMap
和RocksDB
之上又新增了MemoryOnly
类型。v3.2.0版本之前router和ps之间采用JSON数据协议进行交互,大大影响了router和ps之间的交互,导致服务的吞吐率低,因此v3.2.0版本之后,我们使用protobuf替代JSON, 大大提升了ps和router的吞吐率,增加了插入和搜索的速度。
v3.2.0版本之前raft接收的是JSON序列化的字节数组,这样的缺点有两个:
因此v3.2.0版本之后,我们在raft之前对请求进行加工并序列化,减少raft提交日志后数据进入Gamma引擎前这段时间的数据操作,以此来提升ps和Gamma引擎之间的吞吐率,大大提高数据插入和搜索的性能。
向量和正排字段采用分段存储的方案,避免在初始化的时候就固定最大容量max size
导致后续无法动态扩展;另外业务的数据量都是缓慢增长的,用户可能无法预估最大容量,同时如果初始化就申请大量内存,大部分内存在较长的时期内都无法被利用,会浪费内存空间。
分段连续存储的方案主要是对内存空间进行分段处理,每个段存储固定数量的原始向量或者正排字段,且段内仍然是一块连续的内存。初始化时,只创建一个段0,当段0被写满之后,再分配段1,依次按需增加段。这样就实现了一个按需分配内存的方案。
原始向量利用 zfp 来压缩 float 特征,同时正排字段利用 zstd 来压缩变长字段,能够大大降低内存和磁盘的占用,尤其对于k8s集群中部署使用有限内存、磁盘资源的docker比较友好。
经内部测试,v3.2.0版本相对于v3.1.0版本有较大的性能提升,插入数据速度提升了35%,搜索速度也有所提高,通过灵活配置使用ivfpq
或者hnsw
等检索模型。该版本可满足大部分业务场景的性能要求。
在之前的版本中etcd和master是绑定再一起的,这样做的坏处有:
自动恢复
只需要在config.toml中添加auto_recover_ps = true
,具体可以参考config.toml
手动恢复
# 查询失败节点的ip和nodeid
curl http://127.0.0.1:8817/schedule/fail_server/list
# 删除失败的节点nodeid1
curl -XPOST -H "content-type:application/json" -d '{
"fail_node_id":1
}' http://127.0.0.1:8817/meta/remove_server
# 重新启动一个ps并将该节点替换掉失败的节点
curl -XPOST -H "content-type:application/json" -d '{
"fail_node_addr":”192.168.1.1",
"new_node_addr":”192.168.1.2"
}'http://127.0.0.1:8817/schedule/recover_server
Vearch使用raft日志和gamma引擎的持久化保证数据的安全。历史数据会通过调用Gamma的dump接口持久化到磁盘,实时的数据会持续通过raft的log记录下来。当Vearch重启的时候首先会加载持久化到磁盘的历史数据,然后通过raft将没有持久化的数据从日志中取出来从新加载到引擎中,这样避免了没有持久化而导致的数据丢失。
Gamma引擎索引接口进行进一步的抽象,简单清晰化,用户可以更方便地自定义索引和向量检索模型到Gamma引擎,能够更好地进行定制化开发。