跳到主要内容
版本:v3.0.x

Force Merge Compaction

Force Merge 的目的是将小而零散的 Segment 合并为较少而较大的 Segment,以提高查询性能和存储效率。本指南介绍了如何使用 Force Merge Compaction。

说明

此功能处于公开预览阶段。请勿在生产环境中使用。

概述

标准 Compaction 通过多对一合并将 Segment 大小保持在所配置的 maxSize 附近,但仍会留下无法在不超出限制的情况下进一步合并的中等大小的 Segment。例如,如下图所示,如果 Collection 有 5 个 2 MB 的 Segment,而 maxSize 为 3 MB,合并任何两个 Segment 都会超出限制,因此标准 Compaction 无法进一步减少 Segment 数量量,碎片布局依然存在。

Force Merge 增加了一个 target_size 参数,并支持在可能的情况下,在严格的容差范围内,按照所需的大小重组 Segment。如下图所示,如果指定的 target_size 为 4 MB,则可将 5 个 2 MB 的小 Segment 进一步合并为更少的大型 Segment。这样可以减少多余的 Segment 数量,支持比默认 maxSize 设置更大的目标,而且当目标非常大时,系统可以根据当前硬件和 QueryNode 拓扑选择实用的输出大小和 Segment 数量。

要了解使用哪种 Compaction 方法,请参阅 常见问题

R8eow3kaqhktokblcmocnvxmnee

Force Merge Compaction 在现有的 Compaction API 基础上新增 target_size 参数,并保持完全向后兼容:不含 target_size 的现有 Compaction 调用仍可照常工作。

Force Merge 是异步操作。虽然在执行过程中会消耗 I/O 和内存资源,但它不会阻塞搜索或查询操作。

使用 Force Merge Compaction

前提条件

  • Milvus 3.0 或更高版本

  • PyMilvus 3.0 或更高版本

全局配置

以下配置参数控制 Force Merge 行为。请在 Milvus 配置文件中或通过环境变量进行设置。

YAML
dataCoord:
segment:
maxSize: 512 # Default segment max size (MB).
# Used when target_size is 0 or omitted.
compaction:
maxFullSegmentThreshold: 100
# When segment count exceeds this threshold,
# a faster greedy algorithm is used instead
# of the standard merge algorithm.
forceMerge:
datanodeMemoryFactor: 4.0
# DataNode memory divided by this factor
# determines the the largest segment
# size the system can allow.
querynodeMemoryFactor: 4.0
# Minimum QueryNode memory divided by this
# factor. Used in automatic size calculation
# to ensure merged segments can be loaded.

参数

默认值

说明

dataCoord.segment.maxSize

512

默认 Segment 最大大小(MB)。当 target_size 为 0 或省略时用作目标值。也是显式 target_size 的最小允许值。

dataCoord.compaction.maxFullSegmentThreshold

100

用于选择算法的 Segment 数量阈值。当 Segment 数量超过此值时,Milvus 会使用更快的贪婪算法进行合并规划。

  • 标准算法 (Segment 数量 <=dataCoord.compaction.maxFullSegmentThreshold 时使用):产生更优化的合并结果,但计算时间更长。

  • 贪婪算法 (Segment 数量 >dataCoord.compaction.maxFullSegmentThreshold 时使用):代价是 Segment 分组结果略逊于最优方案,更快地完成规划。

dataCoord.compaction.forceMerge.datanodeMemoryFactor

4.0

数据节点内存除以该系数,可计算出系统允许的最大 Segment 大小。

  • 数值越大,分配给合并的内存就越少,但留给其他数据节点操作的内存就越多,从而提高节点的稳定性。

  • 较小的值允许较大的合并,但会增加内存压力。

  • 例如,默认系数为 4.0,数据节点内存为 16 GB,合并预算为 4 GB。这意味着单次操作中合并的 Segment 总大小不能超过 4 GB。

dataCoord.compaction.forceMerge.querynodeMemoryFactor

4.0

最小查询节点内存除以该系数。在自动大小计算 (target_size=max_int64) 过程中使用,以确保合并后的 Segment 可以被查询节点加载。

  • 数值越大,生成的 Segment 越小,查询节点越容易加载。

  • 较小的值允许较大的 Segment,但可能会导致内存受限的查询节点加载失败。

  • 例如,默认系数为 4.0,最小的查询节点有 16 GB 内存,自动计算的目标大小不会超过 4 GB。这样可以防止 Force Merge 产生的 Segment 过大,以至于查询节点无法加载。

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

触发 Force Merge Compaction

通过使用 target_size 参数调用 compact(),可以触发 Force Merge Compaction。有关参数详情,请参阅下面的 参数参考

有三种 Force Merge Compaction 模式可供选择:

Text
compact("my_collection", target_size=?)

├─ Mode 1: target_size = 0 (or omitted)
│ Uses config maxSize (default 512 MB)
│ Equivalent to standard compaction

├─ Mode 2: target_size = 2048
│ Merges segments to ~2 GB each
│ Must be >= config maxSize

└─ Mode 3: target_size = max_int64
Auto-calculates optimal size based on
segment distribution and node memory

下面举例说明如何使用每种 Force Merge Compaction 模式。

默认(标准 Compaction)

Python
from pymilvus import MilvusClient

client = MilvusClient(
uri="http://localhost:19530",
token="root:Milvus"
)

# Standard compaction — uses config maxSize (default 512 MB)
job_id = client.compact("target_collection")

明确目标尺寸

Python
# Merge segments to approximately 2 GB each
job_id = client.compact(
"target_collection",
target_size="2048" # The unit is MB
)

自动尺寸计算

Python
# Let Milvus determine the optimal segment size
max_int64 = (1 << 63) - 1
job_id = client.compact(
"target_collection",
target_size=max_int64
)

参数参考

下表解释了参数。

参数

类型

说明

collection_name

str

必填。要执行 Compaction 的 Collection 的名称。

target_size

int

可选。目标 Segment 大小(以 MB 为单位)。参数值有 3 个选项:

  • 0 或省略:使用配置的 dataCoord.segment.maxSize (默认:512 MB)。相当于标准 Compaction。

  • 显式值:以 MB 为单位将 Segment 合并为指定大小(例如 2048)。必须大于或等于配置的 dataCoord.segment.maxSize

  • max_int64 ((1 << 63) - 1): 根据当前 Segment 分布和可用节点资源自动计算最佳大小。

说明

如果指定的 target_size 小于配置的 dataCoord.segment.maxSize,请求将被拒绝并显示错误。

检查 Compaction 进度

Force Merge Compaction 以异步方式运行。使用返回的作业 ID 检查进度:

Python
# Check compaction state
state = client.get_compaction_state(job_id)
print(f"State: {state}")

最佳实践

  • 不要在生产环境中使用 Force Merge Compaction

  • 大多数情况下使用自动大小计算模式。将 target_size 设置为 max_int64,让 Milvus 分析你的 Segment 分布和节点资源,以确定最佳大小。除非您有特定的大小要求,否则建议使用这种方法。

  • 考虑性能权衡。Force Merge Compaction 是一种资源密集型操作。它会读取、合并和重写 Segment 数量据。将其安排在低流量时段,以尽量减少对查询延迟的影响。

  • 监控之前和之后的 Segment 数量。使用 get_compaction_state()list_persistent_segments 验证 Compaction 是否如预期产生了更少、更大的 Segment。

常见问题

Force Merge 与标准 Compaction 有何不同?

这两种类型的 Compaction 操作有不同的目的。

  • 标准 Compaction(targetSize=0 或省略)是一种尽力而为的增量清理路径。

  • Force Merge(targetSize>0)是一种 Collection 级的重新打包路径,可以产生更少、更大、接近目标的 Segment。

关键区别在于合并形状:标准 Compaction 每个任务的合并形状为 m → 1,而 Force Merge 每个分组输入的合并形状为 m → n。这就是为什么 Force Merge 可以解决标准 Compaction 无法解决的 Segment 布局问题。下表比较了这 2 种运算符。

尺寸

标准 Compaction(默认)

Force Merge

API 触发器

targetSize=0 (或未设置),无 Major/L0 标志

targetSize>0 (MB)

主要目标

增量清理明显的碎片;日常维护

为搜索和平衡进行全 Collection 合并

Segment 大小来源

固定的 dataCoord.Segment.maxSize(服务器配置)

用户 targetSize,然后通过 maxSafeSize 进行安全限制

参数有效性

不调整用户大小

用户 targetSize 必须 >= dataCoord.Segment.maxSize;否则会被拒绝

安全上限

仅配置上限

maxSafeSize = min(QueryNode mem, DataNode mem) / memory_factor(独立非池化:进一步减半)

合并形状

m → 每个任务 1,输出 <= configMaxSize

m → n,输出接近目标大小

中段行为

可能会永久卡住(例如,两个 60% 的 Segment 不能合法地变成一个 120% 的 Segment)

重新打包 + 分割有效;没有 "卡在 60% 处 "的模式

Collection 扁平化能力

有限;重复运行仍可能留下许多中段

强大;旨在减少 Segment 数量,提高饱和度

拓扑意识

None

有;使用 QueryNode/复制/分散布局

读取路径并行性调整

None

有效时使用查询节点数/(副本×分片)调整输出数

典型用例

写入/删除后的高消耗日常清理

基准准备、搜索优化、负载并行性调整

预期范围

不期望重新打包整个 Collection

旨在实现 Collection 级别的重新打包结果

选择指导

  • 选择标准 Compaction 进行低风险增量清理。

  • 当您明确希望将 Collection 重塑为与搜索和加载行为一致的更少、更大的 Segment 时,请选择 Force Merge。

Force Merge 与 Clustering Compaction 有何不同?

Clustering Compaction(is_clustering=True) 基于聚类键在段内重组数据,以改进搜索剪枝。Force Merge (target_size=N) 在不改变数据分布的情况下优化 Segment 大小。它们的作用不同,但可以一起使用--先运行 Clustering Compaction 来组织数据,然后再运行 Force Merge 来合并生成的 Segment。

能否在正在查询的 Collection 上运行 Force Merge?

可以。Force Merge 以异步方式运行,不会阻塞查询。不过,它会消耗数据节点和磁盘 I/O 资源,因此在 Compaction 期间查询延迟可能会增加。请将 Force Merge 安排在流量较低的时段,以获得最佳效果。

如果我设置的 target_size 小于 maxSize 会发生什么情况?

请求将被拒绝,并显示错误。目标大小必须大于或等于配置的 dataCoord.segment.maxSize