聚类压缩
聚类压缩旨在提高搜索性能并降低大型集合的成本。本指南将帮助您了解聚类压缩以及该功能如何提高搜索性能。
概述
Milvus 会将输入的实体存储在集合内的分段中,并在分段已满时将其封存。如果出现这种情况,就会创建一个新的段来容纳更多的实体。因此,实体会任意地分布在不同的段中。这种分布要求 Milvus 搜索多个分段,以找到与给定查询向量最近的邻居。
无聚类压缩
如果 Milvus 能根据特定字段中的值将实体分配到各个网段,那么搜索范围就能限制在一个网段内,从而提高搜索性能。
聚类压缩(Clustering Compaction)是 Milvus 的一项功能,可根据标量字段中的值在集合中的段之间重新分配实体。要启用此功能,首先需要选择一个标量字段作为聚类键。这样,当实体的聚类键值在特定范围内时,Milvus 就能将实体重新分配到段中。当你触发聚类压缩时,Milvus 会生成/更新一个名为PartitionStats 的全局索引,它记录了段和聚类键值之间的映射关系。
使用聚类压缩
PartitionStats作为参考,Milvus 可以在收到带有聚类键值的搜索/查询请求时,剪切不相关的数据,并将搜索范围限制在与键值映射的段内,从而提高搜索性能。有关性能改进的详细信息,请参阅基准测试。
使用聚类压缩
Milvus 的聚类压缩功能具有高度可配置性。你可以选择手动触发,也可以将其设置为由 Milvus 每隔一段时间自动触发。要启用聚类压缩,请执行以下操作:
全局配置
您需要修改 Milvus 配置文件,如下所示。
dataCoord:
compaction:
clustering:
enable: true
autoEnable: false
triggerInterval: 600
minInterval: 3600
maxInterval: 259200
newDataSizeThreshold: 512m
timeout: 7200
queryNode:
enableSegmentPrune: true
datanode:
clusteringCompaction:
memoryBufferRatio: 0.1
workPoolSize: 8
common:
usePartitionKeyAsClusteringKey: true
dataCoord.compaction.clustering
配置项 默认值 默认值 enable
指定是否启用聚类压缩。
如果需要为每个具有聚类密钥的集合启用此功能,请将其设置为true
。false
autoEnable
指定是否启用自动触发压缩。
将此项设置为true
表示 Milvus 在指定的时间间隔内压缩具有聚类密钥的集合。false
triggerInterval
以毫秒为单位指定 Milvus 开始聚类压缩的时间间隔。
只有当autoEnable
设置为true
时,此参数才有效。- minInterval
以毫秒为单位指定最小间隔。
该参数仅在autoEnable
设置为true
时有效。
将其设置为大于 triggerInterval 的整数有助于避免在短时间内重复压缩。- maxInterval
以毫秒为单位指定最大间隔。
该参数仅在autoEnable
设置为true
时有效。
一旦 Milvus 检测到某个集合的聚类压缩持续时间超过此值,就会强制进行聚类压缩。- newDataSizeThreshold
指定触发聚类压缩的上阈值。
该参数仅在autoEnable
设置为true
时有效。
一旦 Milvus 检测到数据集中的数据量超过此值,就会启动聚类压缩进程。- timeout
指定聚类压缩的超时持续时间。
如果执行时间超过此值,则聚类压缩失败。- queryNode
配置项 配置项 默认值 enableSegmentPrune
指定 Milvus 是否在收到搜索/查询请求时参考 PartitionStats 来剪切数据。
将此项设置为true
可使 Milvus 在搜索/查询请求期间从分段中剪除无关数据。false
dataNode.clusteringCompaction
配置项 默认值 默认值 memoryBufferRatio
指定集群压缩任务的内存缓冲区比率。
当数据大小超过使用此比率计算的分配缓冲区大小时,Milvus 会刷新数据。- workPoolSize
指定聚类压缩任务的工作池大小。 - common
配置项 配置项 默认值 usePartitionKeyAsClusteringKey
指定是否将集合中的Partition Key用作聚类密钥。
将其设置为true
表示将Partition Key用作聚类密钥。
您可以在集合中通过显式设置聚类密钥来覆盖此设置。false
要将上述更改应用到Milvus群集,请按照 "使用 Helm 配置 Milvus "和"使用 Milvus Operators 配置 Milvus "中的步骤操作。
集群配置
要在特定集合中进行聚类压缩,应从集合中选择一个标量字段作为聚类密钥。
default_fields = [
FieldSchema(name="id", dtype=DataType.INT64, is_primary=True),
FieldSchema(name="key", dtype=DataType.INT64, is_clustering_key=True),
FieldSchema(name="var", dtype=DataType.VARCHAR, max_length=1000, is_primary=False),
FieldSchema(name="embeddings", dtype=DataType.FLOAT_VECTOR, dim=dim)
]
default_schema = CollectionSchema(
fields=default_fields,
description="test clustering-key collection"
)
coll1 = Collection(name="clustering_test", schema=default_schema)
可以使用以下数据类型的标量字段作为聚类键:Int8
,Int16
,Int32
,Int64
,Float
,Double
, 和VarChar
。
触发聚类压缩
如果启用了自动聚类压实,Milvus 会在指定的时间间隔自动触发压实。或者,您也可以按如下方式手动触发压缩:
coll1.compact(is_clustering=True)
coll1.get_compaction_state(is_clustering=True)
coll1.wait_for_compaction_completed(is_clustering=True)
基准测试
数据量和查询模式共同决定了聚类压缩所能带来的性能提升。一项内部基准测试表明,聚类压缩最多可将每秒查询次数(QPS)提高 25 倍。
基准测试的对象是一个集合,其中包含来自 2000 万个 768 维 LAION 数据集的实体,关键字段被指定为聚类关键字。在集合中触发聚类压缩后,会发送并发搜索,直到 CPU 使用率达到高水位。
搜索过滤器 | 剪切率 | 延迟(毫秒) | QPS (请求/秒) | ||||
---|---|---|---|---|---|---|---|
平均值 | 最小值 | 最大值 | 中位数 | TP99 | |||
无 | 0% | 1685 | 672 | 2294 | 1710 | 2291 | 17.75 |
键 > 200 和键 < 800 | 40.2% | 1045 | 47 | 1828 | 1085 | 1617 | 28.38 |
键 > 200 和键 < 600 | 59.8% | 829 | 45 | 1483 | 882 | 1303 | 35.78 |
键 > 200 和键 < 400 | 79.5% | 550 | 100 | 985 | 584 | 898 | 54.00 |
key == 1000 | 99% | 68 | 24 | 1273 | 70 | 246 | 431.41 |
随着搜索筛选器中搜索范围的缩小,剪切率也随之增加。这意味着在搜索过程中会跳过更多的实体。比较第一行和最后一行的统计数据,可以发现不进行聚类压缩的搜索需要扫描整个集合。另一方面,使用特定键进行聚类压缩的搜索可实现高达 25 倍的改进。
最佳实践
以下是一些有效使用聚类压缩的提示:
为数据量大的数据集启用此功能。 数据集中的数据量越大,搜索性能就越高。对于超过 100 万个实体的集合,启用此功能是一个不错的选择。
选择合适的聚类关键字:可以使用通常用作筛选条件的标量字段作为聚类关键字。对于包含来自多个租户的数据的集合,可以使用区分一个租户和另一个租户的字段作为聚类密钥。
使用分区键作为聚类键。如果想在 Milvus 实例的所有集合中启用此功能,或者在使用分区键的大型集合中仍然面临性能问题,可以将
common.usePartitionKeyAsClusteringKey
设置为 true。这样,在选择集合中的标量字段作为分区键时,就会有一个聚类键和一个分区键。请注意,此设置不会阻止您选择另一个标量字段作为聚类键。明确指定的聚类键始终优先。