向量检索插件是阿里云Elasticsearch团队自主开发的向量检索引擎插件,基于阿里巴巴达摩院proxima向量检索库实现,能够帮助您快速实现图像搜索、视频指纹采样、人脸识别、语音识别和商品推荐等向量检索场景的需求。本文介绍如何使用向量检索插件。
前提条件
- 安装向量检索插件(英文名为aliyun-knn)。插件的默认安装情况与阿里云Elasticsearch的实例版本和内核版本相关,具体说明如下:
- 实例版本为6.7.0,内核版本为1.2.0及以上:向量检索插件默认集成在apack插件中(默认已安装),安装或卸载向量检索插件都需对apack插件进行操作。详细信息,请参见使用apack插件的物理复制功能。
- 实例版本为6.7.0以上版本,或者实例版本为6.7.0且内核版本小于1.2.0:需在插件配置页面手动安装向量检索插件,安装方法请参见安装或卸载系统默认插件。
注意- 仅6.7.0及以上版本的阿里云Elasticsearch实例支持向量检索插件。
- 在安装向量检索插件前,需要确保实例的数据节点规格为2核8GB及以上(2核8GB仅可用于功能测试,生产环境需要数据节点为4核16GB及以上)。如果不满足,请先将数据节点规格升级至2核8GB及以上。详细信息,请参见升配集群。
- 完成索引规划和集群规划。
背景信息
- 应用场景
目前在阿里巴巴集团内,阿里云Elasticsearch向量检索引擎已成熟应用于拍立淘、阿里云图像搜索服务、优酷视频指纹采样、趣头条视频指纹采样、猜你喜欢、搜索个性化、CrossMedia搜索等大规模生产应用场景。
- 原理
阿里云Elasticsearch向量检索功能基于Elasticsearch插件扩展机制实现,能够完全兼容原生Elasticsearch版本,您无需任何额外的学习成本即可使用向量检索引擎。向量索引除了支持实时增量写入、近实时(Near Real Time,简称NRT)搜索查询,还具备了所有原生Elasticsearch的分布式能力,同时支持多副本、错误恢复、快照等功能。
向量检索插件还具有打分机制,该机制依赖于向量间的欧式距离。以两个n维向量A和B为例,根据欧几里德数学知识,距离及打分计算公式如下:- 未开方欧式距离= (A1-B1)² + (A2-B2)² + ... + (An-Bn)²
- 分数= 1/(距离+1)
其中距离为未开方欧氏距离。例如两个二维向量[0,0]和[1,2],未开方欧式距离= (1-0)² + (2-0)² = 5;分数= 1/(5+1) =0.167。说明 实际应用中,您可以通过查询分数反推向量间的距离,优化向量数据,提升打分。
- 算法说明
在算法上,目前向量检索引擎已经支持了hnsw算法以及linear算法,适用于单机数据量小(全内存)的业务场景。两种算法性能对比如下。
表 1. hnsw算法和linear算法性能对比 表格中为阿里云Elasticsearch 6.7.0版本环境实测数据,测试环境配置如下:- 机器配置:数据节点16核64GB*2 + 100GB SSD云盘。
- 数据集:sift128维float向量。
- 数据总量:2千万条。
- 索引配置:全部采用默认参数。
性能指标 hnsw linear top10召回率 98.6% 100% top50召回率 97.9% 100% top100召回率 97.4% 100% 延迟(p99) 0.093s 0.934s 延迟(p90) 0.018s 0.305s 说明 表中的p表示百分比,例如延迟(p99)表示99%的查询能在多少秒返回。
索引规划
算法 | 适用场景 | 是否全内存 | 其他 |
---|---|---|---|
hnsw |
|
是 |
|
linear |
|
是 | 无 。 |
集群规划
规划项 | 说明 |
---|---|
数据节点规格(必须) | 生产环境需要数据节点为4核16GB及以上,2核8GB仅可用于功能测试。 |
单机最大数据量 | 数据节点总内存/2。 |
写入限流 | 向量索引的构建属于CPU密集型任务,建议业务控制写入流量不要太高。以16核64GB的数据节点为例,建议单节点写入峰值控制在5000tps以内。
同时,由于在向量索引的查询过程中,会把索引文件全部加载到系统内存,因此建议在业务查询期间,不要同时进行大批量的写入,避免因节点内存紧张导致分片重启的情况。 |
操作步骤
参数说明
参数 | 描述 | 默认值 |
---|---|---|
index.vector.algorithm |
指定索引使用的算法,目前支持hnsw和linear。 | hnsw |
参数 | 描述 | 默认值 |
---|---|---|
index.vector.hnsw.builder.max_scan_num |
用于控制构图过程中的近邻考察范围,保证最坏情况的性能。 | 100000 |
index.vector.hnsw.builder.neighbor_cnt |
hnsw 0层图每个节点的邻居数。建议配置为100。该值越大,离线索引存储消耗越大,图构建质量越高。 | 100 |
index.vector.hnsw.builder.upper_neighbor_cnt |
hnsw上层图(除0层之外)中每个节点的邻居上限数。一般建议配置为neighbor_cnt 的一半。
|
50 |
index.vector.hnsw.builder.efconstruction |
控制图构建过程中近邻扫描区域大小,该值越大,离线构图质量越好,索引构建越慢。建议初始值设置为400。 | 400 |
index.vector.hnsw.builder.max_level |
hnsw总层数,包含0层图和上层图。例如总共1000万文档,scaling_factor 为30,那么层数可以以max level=30为底,取1000万的对数向上取整,计算得5。
|
6 |
index.vector.hnsw.builder.scaling_factor |
下层图是上层图数据的多少倍,呈指数关系。通常设置在10~100之间。scaling_factor 越大,实际生成的图层数越低。建议初始配置50。
|
50 |
参数 | 描述 | 默认值 |
---|---|---|
ef |
用于控制在线检索时,考察的子图的范围大小。该值越大,召回越高,性能越差。建议取值[100,1000]。 | 100 |
查询示例如下。
GET test/_search
{
"query": {
"hnsw": {
"feature": {
"vector": [1.5, 2.5],
"size": 10,
"ef": 100
}
}
}
}
参数 | 描述 | 默认值 |
---|---|---|
indices.breaker.vector.native.indexing.limit |
如果堆外内存使用超过该值,写入操作会被熔断;等待后台构建完成释放内存后,写入恢复正常。出现熔断错误表示当前系统内存消耗已经过高,建议业务上降低写入流量。不建议初学者调整这个参数值。 | 70% |
indices.breaker.vector.native.total.limit |
向量索引后台构建时,最多使用的堆外内存比例。如果实际使用的堆外内存超过了这个比例,可能会发生shard重启的情况,不建议初学者调整这个参数值。 | 80% |
常见问题
-
Q:如何评估查询的召回率?
A:可以同时创建两个索引,一个为hnsw算法,一个为linear算法,其他配置相同。客户端向两个索引同时推送相同的向量数据,刷新后,用同样的查询向量对比linear索引和hnsw索引召回的文档ID,交集的文档ID个数/召回总数,即为待测向量的召回率。说明 交集的文档ID个数是指两个索引召回的文档ID的交集。 -
Q:集群写入期间报错“circuitBreakingException”,如何处理?
A:这个错误表明此时系统的堆外内存使用率超过了
indices.breaker.vector.native.indexing.limit
指定的比例(默认为70%),触发了写入的熔断操作,一般等待后台的索引构建任务完成后会自动释放。建议客户端写入时添加错误重试机制。 -
Q:为什么写入任务已经停止了,CPU依然在工作?
A:向量索引的构建发生在refresh或flush期间,虽然写入流量已经停止,但后台的向量索引构建任务可能仍然在继续。等待最后一轮refresh结束后,计算资源就会被释放。