强制合并索引的段文件,减少段数量,提高查询性能并释放存储空间。
API #
POST /_forcemerge
POST /{index}/_forcemerge
API 的作用 #
该 API 用于强制合并索引的段文件(segments),主要作用包括:
- 减少段数量:将多个小段合并为较少的大段
- 提高查询性能:减少需要搜索的段数量
- 释放存储空间:清除已删除的文档
- 优化索引结构:减少磁盘 I/O
什么是段合并? #
Easysearch 使用段(segments)来存储索引数据。新文档会被添加到新段中,随着时间推移,段数量会增加。段合并操作将多个段合并为更大的段,提高查询效率。
使用场景 #
- 索引完成后优化查询性能
- 清理大量已删除文档
- 减少段数量以节省内存
- 定期维护只读索引
警告:Force Merge 是一个资源密集型操作,可能会影响集群性能。建议在低峰期执行。
API 的参数 #
路由参数 #
| 参数 | 类型 | 是否必填 | 描述 |
|---|---|---|---|
{index} | 字符串 | 否 | 要合并的索引名称。支持:单个索引、逗号分隔的多个索引、通配符表达式。不指定则操作所有索引 |
Query String 参数 #
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
max_num_segments | 整数 | 否 | -1 | 目标段数量。设置为 1 将合并为单个段 |
only_expunge_deletes | 布尔值 | 否 | false | 是否只清理已删除文档,不合并未删除的文档 |
flush | 布尔值 | 否 | true | 是否在合并后执行刷新操作 |
参数说明 #
max_num_segments #
- 强制将索引合并到指定的段数量或更少
- 设置为 1 会将整个索引合并为单个段(最大程度优化)
- 默认值 -1 表示使用默认合并策略
- 值越小,合并时间越长,消耗资源越多
only_expunge_deletes #
true:只合并含有大量删除的段false:执行完整的段合并(默认)- 与
max_num_segments同时使用时会产生警告
flush #
true:合并后执行刷新,使更改可见false:不刷新,稍后手动刷新
示例 #
合并所有索引为单个段 #
POST /_forcemerge?max_num_segments=1
响应示例:
{
"_shards": {
"total": 10,
"successful": 10,
"failed": 0
}
}
合并特定索引 #
POST /my_index/_forcemerge?max_num_segments=1
合并多个索引 #
POST /index1,index2/_forcemerge?max_num_segments=3
只清理已删除文档 #
POST /my_index/_forcemerge?only_expunge_deletes=true
合并后不刷新 #
POST /my_index/_forcemerge?max_num_segments=1&flush=false
使用通配符合并索引 #
POST /logs-2025-*/_forcemerge?max_num_segments=1
响应字段说明 #
| 字段 | 类型 | 描述 |
|---|---|---|
_shards.total | 整数 | 总分片数 |
_shards.successful | 整数 | 成功的分片数 |
_shards.failed | 整数 | 失败的分片数 |
使用场景 #
场景 1:优化只读索引 #
对于不再写入的索引,可以合并为单个段以获得最佳查询性能:
# 合并历史日志索引
POST /logs-2024-*/_forcemerge?max_num_segments=1
场景 2:清理已删除文档 #
大量删除文档后,清理空间:
POST /my_index/_forcemerge?only_expunge_deletes=true
场景 3:时间序列索引优化 #
# 每日优化昨天的索引
POST /logs-$(date -d 'yesterday' +%Y.%m.%d)/_forcemerge?max_num_segments=1
性能考虑 #
资源消耗 #
| 资源 | 影响 |
|---|---|
| CPU | 高 - 需要大量计算进行合并 |
| 磁盘 I/O | 高 - 需要读写大量数据 |
| 磁盘空间 | 需要额外空间 - 合并过程中需要临时空间 |
| 内存 | 中等 - 需要缓冲区进行合并 |
最佳实践 #
- 低峰期执行:在业务低峰期执行,避免影响正常服务
- 分批执行:对于大量索引,分批执行而非一次性合并所有索引
- 监控磁盘空间:确保有足够的磁盘空间用于合并过程
- 只读索引:只对不再写入的索引执行强制合并
- 避免频繁执行:频繁执行会增加不必要的开销
合并建议 #
| 索引类型 | max_num_segments 建议 |
|---|---|
| 活跃写入索引 | 不建议执行 |
| 偶尔写入索引 | 2-5 个段 |
| 只读索引 | 1 个段 |
注意事项 #
- 不可逆操作:合并后的段无法拆分
- 磁盘空间:合并过程中需要临时磁盘空间
- 时间索引:对于基于时间的索引(如日志),只对旧索引执行
- 复制索引:合并副本会自动同步到副本分片
- 写入影响:合并期间索引仍可读写,但性能会下降
Force Merge vs 自动合并 #
| 特性 | Force Merge | 自动合并 |
|---|---|---|
| 触发方式 | 手动 API | 自动后台进程 |
| 合并程度 | 可控(指定段数) | 基于策略 |
| 资源消耗 | 高 | 中等 |
| 执行时间 | 立即执行 | 后台渐进 |
| 使用场景 | 优化只读索引 | 日常维护 |





