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 方法,请参阅 常见问题。

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 配置文件中或通过环境变量进行设置。
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.
参数 | 默认值 | 说明 |
|---|---|---|
| 512 | 默认 Segment 最大大小(MB)。当 |
| 100 | 用于选择算法的 Segment 数量阈值。当 Segment 数量超过此值时,Milvus 会使用更快的贪婪算法进行合并规划。
|
| 4.0 | 数据节点内存除以该系数,可计算出系统允许的最大 Segment 大小。
|
| 4.0 | 最小查询节点内存除以该系数。在自动大小计算 (
|
要将上述更改应用到 Milvus 集群,请按照 使用 Helm 配置 Milvus 和 使用 Milvus Operator 配置 Milvus 中的步骤操作。
触发 Force Merge Compaction
通过使用 target_size 参数调用 compact(),可以触发 Force Merge Compaction。有关参数详情,请参阅下面的 参数参考。
有三种 Force Merge Compaction 模式可供选择:
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)
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")
明确目标尺寸
# Merge segments to approximately 2 GB each
job_id = client.compact(
"target_collection",
target_size="2048" # The unit is MB
)
自动尺寸计算
# Let Milvus determine the optimal segment size
max_int64 = (1 << 63) - 1
job_id = client.compact(
"target_collection",
target_size=max_int64
)
参数参考
下表解释了参数。
参数 | 类型 | 说明 |
|---|---|---|
| str | 必填。要执行 Compaction 的 Collection 的名称。 |
| int | 可选。目标 Segment 大小(以 MB 为单位)。参数值有 3 个选项:
|
如果指定的 target_size 小于配置的 dataCoord.segment.maxSize,请求将被拒绝并显示错误。
检查 Compaction 进度
Force Merge Compaction 以异步方式运行。使用返回的作业 ID 检查进度:
# 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。