向量索引缓存管理
用户可以参考本文档,来修改向量索引的缓存设置,并管理向量索引缓存。
功能说明
为了保证向量检索查询请求的低延迟,很多向量索引需要保持索引结构常驻内存,避免查询时产生磁盘io。
BES数据节点默认会预留一半内存给 JVM(最大不超过30G内存),分配剩余内存的 50% 为向量索引使用,当内存中的向量索引结构大小超过阈值,会触发驱逐操作。例如,对于64GB内存的节点,会有30GB分配给JVM,剩余的34GB有一半用来存储向量索引结构。
向量索引的最大内存占用比例可以通过circuit_breaker_limit
参数调节,默认设置为 50%,不建议调整得过高,因为ES高度依赖操作系统的 filesystem cache 来提升其数据读取效率,向量索引的内存占用过高可能导致系统可用的内存不足,影响ES集群的性能。调节方式如下:
PUT /_cluster/settings
{
"persistent" : {
"bpack.knn.memory.circuit_breaker.limit" : "70%"
}
}
在向量数据写入索引,构建好向量索引以后,第一次查询会触发索引加载到内存的操作,往往导致查询耗时较高。为了避免这种情况,可以在构建好向量索引以后,主动调用warmup API将向量索引结构加载到内存。同时,用户也可以通过stats API查看向量索引的内存使用情况,也可以用dorp API主动驱逐内存中的指定向量索引。
管理API
向量索引预热
GET /_bpack/_knn/warmup/index1,index2
通过warmup API,可以主动将向量索引加载到缓存,避免首次查询因为索引加载导致延迟升高到情况。 其中,index1,index2可以替换为用户的实际索引名称,多个名称支持通过逗号分隔。
向量索引状态查询
查询缓存状态的方式如下:
GET /_bpack/_knn/stats
GET /_bpack/_knn/nodeId1,nodeId2/stats/statName1,statName2
结果示例如下,缓存使用情况可以关注graph_memory_usage_percentage
、graph_memory_usage
等字段,缓存使用的明细情况可以关注indices_in_cache
部分:
{
"_nodes" : {
"total" : 1,
"successful" : 1,
"failed" : 0
},
"cluster_name" : "my-cluster",
"circuit_breaker_triggered" : false,
"nodes" : {
"JdfxIkOS1-43UxqNz98nw" : {
"graph_memory_usage_percentage" : 3.68,
"graph_query_requests" : 1420920,
"graph_memory_usage" : 2,
"cache_capacity_reached" : false,
"load_success_count" : 179,
"training_memory_usage" : 0,
"indices_in_cache" : {
"myindex" : {
"graph_memory_usage" : 2,
"graph_memory_usage_percentage" : 3.68,
"graph_count" : 2
}
},
"script_query_errors" : 0,
"hit_count" : 1420775,
"knn_query_requests" : 147092,
"total_load_time" : 2436679306,
"miss_count" : 179,
"training_memory_usage_percentage" : 0.0,
"graph_index_requests" : 656,
"load_exception_count" : 0,
"training_errors" : 0,
"eviction_count" : 0,
"script_compilations" : 0,
"script_query_requests" : 0,
"graph_query_errors" : 0,
"indexing_from_model_degraded" : false,
"graph_index_errors" : 0,
"training_requests" : 17,
"script_compilation_errors" : 0
}
}
}
向量索引驱逐
GET /_bpack/_knn/drop/index1,index2
通过drop API可以主动将指定index的向量索引从缓存中驱逐,释放缓存空间。其中,index1,index2可以替换为用户的实际索引名称,多个名称支持通过逗号分隔。
集群参数配置
Setting | 默认值 | 说明 |
---|---|---|
bpack.knn.cache.item.expiry.enabled | false | 此参数表示缓存数据是否会过期删除。 |
bpack.knn.cache.item.expiry.minutes | 3h | 此参数表示当数据持续这个时间不被访问时,将从缓存中清除。使用TimeUnit格式表示,例如『10s』、『10m』、『3h』等,不可设置为小数值,如『1.5h』。建议设置超过30分钟,使缓存结果能够被接下来的查询有效命中;如果设置过小,则会很快被清除。 |
bpack.knn.memory.circuit_breaker.limit | 50% | 此参数表示向量索引内存缓存的最大容量。当向量索引结构超过了缓存的最大容量限制,将触发驱逐操作,并将circuit_breaker_triggered状态设置为true(可以通过查询统计信息api查询)。该值可以设置为百分数,代表除去Elasticsearch的JVM外,服务器剩余内存用于向量索引缓存的百分比;也可以设置为一个带有存储容量单位的值,例如『10kb』、『10mb』、『3g』等,不建议设置为小数值,如『1.5g』。例如,一台机器拥有128GB内存,Elasticsearch的JVM使用了30GB,bpack.knn.memory.circuit_breaker.limit的默认值为50%,那么向量索引缓存可用的内存空间为 50% * (128 - 30) = 49GB。 |
bpack.knn.circuit_breaker.unset.percentage | 75% | 此参数表示Circuit Breaker的解除百分比,当缓存容量大小低于bpack.knn.circuit_breaker.unset.percentage时,Circuit Breaker将解除触发,将circuit_breaker_triggered状态设置为false(可以通过查询状态api查询)。 |
设置方式示例如下:
PUT /_cluster/settings
{
"persistent" : {
"bpack.knn.cache.item.expiry.enabled" : true,
"bpack.knn.cache.item.expiry.minutes": "1d"
}
}