聚类压缩
聚类压缩旨在提高搜索性能,降低大型 Collections 的成本。本指南将帮助您了解聚类压缩以及该功能如何提高搜索性能。
概述
Milvus 将输入的实体存储在 Collections 中的分段中,并在分段已满时将其封存。如果出现这种情况,就会创建一个新的段来容纳更多的实体。因此,实体会任意地分布在不同的段中。这种分布要求 Milvus 搜索多个分段,以找到与给定查询向量最近的邻居。
无聚类压缩
如果 Milvus 可以根据特定字段中的值将实体分布在不同的段中,那么搜索范围就可以限制在一个段内,从而提高搜索性能。
聚类压缩(Clustering Compaction)是 Milvus 的一项功能,它能根据标量字段中的值在 Collections 中的段之间重新分配实体。要启用此功能,首先需要选择一个标量字段作为聚类键。这样,当实体的聚类键值在特定范围内时,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指定是否启用聚类压缩。
如果需要为每个具有聚类密钥的 Collections 启用此功能,请将其设置为true。falseautoEnable指定是否启用自动触发压缩。
将此项设置为true表示 Milvus 在指定的时间间隔内压缩具有聚类密钥的 Collections。falsetriggerInterval以毫秒为单位指定 Milvus 开始聚类压缩的时间间隔。
只有当autoEnable设置为true时,此参数才有效。- minInterval以秒为单位指定最小间隔。
此参数仅在autoEnable设置为true时有效。
将其设置为大于 triggerInterval 的整数,有助于避免在短时间内重复压缩。- maxInterval指定最大间隔(以秒为单位)。
该参数仅在autoEnable设置为true时有效。
一旦 Milvus 检测到某个 Collections 未进行聚类压缩的时间超过此值,它就会强制进行聚类压缩。- newDataSizeThreshold指定触发聚类压缩的上阈值。
该参数仅在autoEnable设置为true时有效。
一旦 Milvus 检测到 Collections 中的数据量超过此值,就会启动聚类压缩进程。- timeout指定聚类压缩的超时持续时间。
如果执行时间超过此值,则聚类压缩失败。- queryNode配置项 配置项 默认值 enableSegmentPrune指定 Milvus 是否在收到搜索/查询请求时参考 PartitionStats 来剪切数据。
将此项设置为true可使 Milvus 在搜索/查询请求期间从分段中剪除无关数据。falsedataNode.clusteringCompaction配置项 默认值 默认值 memoryBufferRatio指定集群压缩任务的内存缓冲区比率。
当数据大小超过使用此比率计算的分配缓冲区大小时,Milvus 会刷新数据。- workPoolSize指定聚类压缩任务的工作池大小。 - common配置项 配置项 默认值 usePartitionKeyAsClusteringKey指定是否将 Collections 中的分区密钥用作聚类密钥。
将其设置为true表示将分区密钥用作聚类密钥。
您可以在 Collections 中通过显式设置聚类密钥来覆盖此设置。false
要将上述更改应用到 Milvus 群集,请按照 "使用 Helm 配置 Milvus"和 "使用 Milvus Operator 配置 Milvus"中的步骤操作。
Collection 配置
要在特定 Collections 中进行聚类压缩,应从 Collections 中选择一个标量字段作为聚类密钥。
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 数据集的实体的 Collections 上进行的,关键字段被指定为聚类关键字。在 Collections 中触发聚类压缩后,会发送并发搜索,直到 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 |
随着搜索筛选器中搜索范围的缩小,剪切率也随之增加。这意味着在搜索过程中会跳过更多的实体。比较第一行和最后一行的统计数据,可以发现不进行聚类压缩的搜索需要扫描整个 Collections。另一方面,使用特定键进行聚类压缩的搜索可以实现高达 25 倍的改进。
最佳实践
以下是一些有效使用聚类压缩的提示:
为数据量较大的 Collections 启用此功能。 Collections 中的数据量越大,搜索性能就越高。对于超过 100 万个实体的集合,启用此功能是一个不错的选择。
选择合适的聚类关键字:可以使用通常用作筛选条件的标量字段作为聚类关键字。对于保存多个租户数据的 Collections,可以利用区分一个租户和另一个租户的字段作为聚类密钥。
使用分区密钥作为聚类密钥。如果想在 Milvus 实例中的所有 Collections 启用此功能,或者在使用分区密钥的大型 Collections 中仍面临性能问题,可以将
common.usePartitionKeyAsClusteringKey设置为 true。通过这样做,当你选择 Collections 中的标量字段作为分区键时,你将拥有一个聚类键和一个分区键。请注意,此设置不会阻止您选择另一个标量字段作为聚类键。明确指定的聚类键始终优先。