跳到主要内容
版本:v2.5.x

聚类压缩

聚类压缩旨在提高搜索性能,降低大型 Collection 的成本。本指南将帮助您了解聚类压缩以及该功能如何提高搜索性能。

概述

Milvus 将输入的实体存储在 Collection 中的分段中,并在分段已满时将其封存。如果出现这种情况,就会创建一个新的段来容纳更多的实体。因此,实体会任意地分布在不同的段中。这种分布要求 Milvus 搜索多个分段,以找到与给定查询向量最近的邻居。

Without Clustering Compaction无聚类压缩

如果 Milvus 可以根据特定字段中的值将实体分布在不同的段中,那么搜索范围就可以限制在一个段内,从而提高搜索性能。

聚类压缩(Clustering Compaction)是 Milvus 的一项功能,它能根据标量字段中的值在 Collection 中的段之间重新分配实体。要启用此功能,首先需要选择一个标量字段作为聚类键。这样,当实体的聚类键值在特定范围内时,Milvus 就能将实体重新分配到段中。当你触发聚类压缩时,Milvus 会生成/更新一个名为PartitionStats 的全局索引,它记录了段和聚类键值之间的映射关系。

Clustering Compaction聚类压缩

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

|

指定是否启用聚类压缩。如果需要为每个具有聚类密钥的 Collection 启用此功能,请将其设置为true

|

| |

autoEnable

|

指定是否启用自动触发压缩。将此设置为true 表示 Milvus 在指定的时间间隔对具有聚类键的 Collection 进行压缩。

|

| |

triggerInterval

|

以毫秒为单位指定 Milvus 开始聚类压缩的时间间隔。只有将autoEnable 设置为true 时才适用。

| | |

minInterval

|

以毫秒为单位指定最小间隔。仅当设置autoEnabletrue 时适用。

将其设置为大于triggerInterval 的整数有助于避免在短时间内重复压缩。

| | |

maxInterval

|

以毫秒为单位指定最大间隔。只有将autoEnable 设置为true 时才适用。

一旦 Milvus 检测到某个 Collection 的聚类压缩持续时间超过此值,就会强制进行聚类压缩。

| | |

newDataSizeThreshold

|

指定触发聚类压缩的上阈值。这仅适用于将autoEnable 设置为true 时。

一旦 Milvus 检测到 Collection 中的数据量超过此值,就会启动聚类压缩进程。

| | |

timeout

|

指定聚类压缩的超时持续时间。如果执行时间超过此值,则聚类压缩失败。

| | |

queryNode

| |

enableSegmentPrune

|

指定 Milvus 是否在收到搜索/查询请求时参考 PartitionStats 来剪切数据。将此值设为true ,这样 Milvus 就能在收到搜索/查询请求时通过引用 PartitionStats 来剪切数据。

| | |

dataNode.clusteringCompaction

| |

memoryBufferRatio

|

指定集群压缩任务的内存缓冲区比率。 当数据大小超过使用此比率计算出的分配缓冲区大小时,Milvus 会刷新数据。

| | |

workPoolSize

|

指定聚类压缩任务的工作池大小。

| | |

common

| |

usePartitionKeyAsClusteringKey

|

指定是否使用 Collection 中的 Partition Key 作为聚类密钥。将此设置为 "true",Milvus 就会将 Collection 中的 Partition Key 作为聚类密钥。

你可以在 Collection 中通过显式设置聚类密钥来覆盖此设置。

| |

要将上述更改应用到 Milvus 群集,请按照 "使用 Helm 配置 Milvus"和 "使用 Milvus Operator 配置 Milvus"中的步骤操作

Collection 配置

要在特定 Collection 中进行聚类压缩,应从该 Collection 中选择一个标量字段作为聚类密钥。

from pymilvus import MilvusClient, DataType

CLUSTER_ENDPOINT="http://localhost:19530"
TOKEN="root:Milvus"

client = MilvusClient(
uri=CLUSTER_ENDPOINT,
token=TOKEN
)

schema = MilvusClient.create_schema()
schema.add_field("id", DataType.INT64, is_primary=True, auto_id=False)
schema.add_field("key", DataType.INT64, is_clustering_key=True)
schema.add_field("var", DataType.VARCHAR, max_length=1000)
schema.add_field("vector", DataType.FLOAT_VECTOR, dim=5)

client.create_collection(
collection_name="clustering_test",
schema=schema
)
说明

您可以使用以下数据类型的标量字段作为聚类键:Int8,Int16,Int32,Int64,Float,DoubleVarChar

触发聚类压缩

如果启用了自动聚类压实,Milvus 会在指定的时间间隔自动触发压实。或者,您也可以按如下方式手动触发压缩:

# trigger a manual compaction
job_id = client.compact(
collection_name="clustering_test",
is_clustering=True
)

# get the compaction state
client.get_compaction_state(
job_id=job_id,
)

基准测试

数据量和查询模式共同决定了聚类压缩所能带来的性能提升。一项内部基准测试表明,聚类压缩最多可将每秒查询次数(QPS)提高 25 倍。

该基准测试是在一个包含来自 2000 万个 768 维 LAION 数据集的实体的 Collection 上进行的,该数据集的key 字段被指定为聚类密钥。在 Collection 中触发聚类压缩后,会发送并发搜索,直到 CPU 使用率达到高水位。

| 搜索过滤器

|

剪切率

|

延迟

|

请求/秒

| | --- | --- | --- | --- | |

平均值

|

最小值

|

最大值

|

中位数

|

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

| |

键==1000

|

99%

|

68

|

24

|

1273

|

70

|

246

|

431.41

|

随着搜索筛选器中搜索范围的缩小,剪切率也随之增加。这意味着在搜索过程中会跳过更多的实体。比较第一行和最后一行的统计数据,可以发现不进行聚类压缩的搜索需要扫描整个 Collection。另一方面,使用特定键进行聚类压缩的搜索可以实现高达 25 倍的改进。

最佳实践

以下是一些有效使用聚类压缩的提示:

  • 为数据量较大的 Collection 启用此功能。

    Collection 中的数据量越大,搜索性能就越高。对于超过 100 万个实体的 Collection,启用此功能是一个不错的选择。

  • 选择合适的聚类关键字。

    可以使用通常用作筛选条件的标量字段作为聚类关键字。对于保存多个租户数据的 Collection,可以利用区分一个租户和另一个租户的字段作为聚类密钥。

  • 使用 Partition Key 作为聚类密钥。

    如果你想为 Milvus 实例中的所有 Collection 启用此功能,或者在使用 Partition Key 的大型 Collection 中仍面临性能问题,可以将common.usePartitionKeyAsClusteringKey 设置为true 。通过这样做,当你选择 Collection 中的标量字段作为 Partition Key 时,你将拥有一个聚类键和一个 Partition Key。

    请注意,此设置不会阻止您选择另一个标量字段作为聚类键。明确指定的聚类键始终优先。