强制合并 API

编辑

强制对一个或多个索引的分片执行合并操作。对于数据流,该 API 会强制对数据流的后备索引的分片执行合并操作。

resp = client.indices.forcemerge(
    index="my-index-000001",
)
print(resp)
response = client.indices.forcemerge(
  index: 'my-index-000001'
)
puts response
const response = await client.indices.forcemerge({
  index: "my-index-000001",
});
console.log(response);
POST /my-index-000001/_forcemerge

请求

编辑

POST /<目标>/_forcemerge

POST /_forcemerge

先决条件

编辑
  • 如果启用了 Elasticsearch 安全功能,您必须具有目标数据流、索引或别名的 maintenance(维护)或 manage(管理)索引权限

描述

编辑

使用强制合并 API 强制对一个或多个索引的分片进行合并。合并通过合并一些分段来减少每个分段中的分段数量,并释放已删除文档使用的空间。合并通常会自动发生,但有时手动触发合并会很有用。

我们建议仅对只读索引(意味着索引不再接收写入)进行强制合并。 当文档被更新或删除时,旧版本不会立即删除,而是被软删除并标记为“墓碑”。这些软删除的文档会在常规分段合并期间自动清理。但是,强制合并可能会导致生成非常大的(> 5GB)分段,这些分段不符合常规合并的条件。因此,软删除的文档数量会迅速增加,从而导致更高的磁盘使用率和更差的搜索性能。如果您定期强制合并正在接收写入的索引,这也可能使快照更昂贵,因为新文档无法增量备份。

强制合并期间的阻塞

编辑

对该 API 的调用会阻塞,直到合并完成(除非请求包含 wait_for_completion=false,默认为 true)。如果在完成之前客户端连接丢失,则强制合并过程将在后台继续。对同一索引强制合并的任何新请求也将阻塞,直到正在进行的强制合并完成。

异步运行强制合并

编辑

如果请求包含 wait_for_completion=false,Elasticsearch 将执行一些预检,启动请求,并返回一个 task(任务),您可以使用该任务来获取任务的状态。但是,您无法取消此任务,因为强制合并任务是不可取消的。Elasticsearch 会在 _tasks/<task_id> 处以文档的形式创建此任务的记录。完成任务后,您应该删除任务文档,以便 Elasticsearch 可以回收空间。

强制合并多个索引

编辑

您可以通过以下方式使用单个请求强制合并多个索引:

  • 包含多个后备索引的一个或多个数据流
  • 多个索引
  • 一个或多个别名
  • 集群中的所有数据流和索引

每个目标分片都使用 force_merge(强制合并)线程池单独进行强制合并。默认情况下,每个节点只有一个 force_merge 线程,这意味着该节点上的分片一次强制合并一个。如果您在节点上扩展 force_merge 线程池,则它将并行强制合并其分片。

强制合并会使正在合并的分片的存储空间暂时增加,因为它可能需要高达三倍大小的可用空间,如果 max_num_segments 参数设置为 1,则会将所有分段重写为一个新的分段。

路径参数

编辑
<目标>
(可选,字符串)用于限制请求的逗号分隔的数据流、索引和别名列表。支持通配符(*)。要定位所有数据流和索引,请省略此参数或使用 *_all

查询参数

编辑
allow_no_indices

(可选,布尔值)如果为 false,则当任何通配符表达式、索引别名_all 值仅定位到缺失或关闭的索引时,该请求将返回错误。即使请求定位到其他打开的索引,此行为也适用。例如,如果某个索引以 foo 开头,但没有索引以 bar 开头,则定位到 foo*,bar* 的请求将返回错误。

默认为 true

expand_wildcards

(可选,字符串)通配符模式可以匹配的索引类型。如果请求可以定位数据流,则此参数确定通配符表达式是否匹配隐藏的数据流。支持逗号分隔的值,例如 open,hidden。有效值为:

all
匹配任何数据流或索引,包括隐藏的数据流或索引。
open
匹配打开的、非隐藏的索引。也匹配任何非隐藏的数据流。
closed
匹配关闭的、非隐藏的索引。也匹配任何非隐藏的数据流。数据流无法关闭。
hidden
匹配隐藏的数据流和隐藏的索引。必须与 openclosed 或两者结合使用。
none
不接受通配符模式。

默认为 open

flush
(可选,布尔值)如果为 true,则 Elasticsearch 会在强制合并后对索引执行刷新操作。默认为 true
ignore_unavailable
(可选,布尔值)如果为 false,则当请求定位到缺失或关闭的索引时,该请求将返回错误。默认为 false
max_num_segments

(可选,整数)要合并到的分段数。要完全合并索引,请将其设置为 1

默认为检查是否需要执行合并。如果是,则执行合并。

您不能在同一请求中同时指定此参数和 only_expunge_deletes

only_expunge_deletes

(可选,布尔值)如果为 true,则会清除所有包含超过 index.merge.policy.expunge_deletes_allowed(默认为 10)百分比的已删除文档的分段。默认为 false

在 Lucene 中,文档不会从分段中删除,而只是标记为已删除。在合并期间,会创建一个不包含这些已删除文档的新分段。

您不能在同一请求中同时指定此参数和 max_num_segments

wait_for_completion

(可选,布尔值)如果为 true,则请求将阻塞,直到操作完成。默认为 true

示例

编辑

强制合并特定的数据流或索引

编辑
resp = client.indices.forcemerge(
    index="my-index-000001",
)
print(resp)
response = client.indices.forcemerge(
  index: 'my-index-000001'
)
puts response
const response = await client.indices.forcemerge({
  index: "my-index-000001",
});
console.log(response);
POST /my-index-000001/_forcemerge

强制合并多个数据流或索引

编辑
resp = client.indices.forcemerge(
    index="my-index-000001,my-index-000002",
)
print(resp)
response = client.indices.forcemerge(
  index: 'my-index-000001,my-index-000002'
)
puts response
const response = await client.indices.forcemerge({
  index: "my-index-000001,my-index-000002",
});
console.log(response);
POST /my-index-000001,my-index-000002/_forcemerge

强制合并所有索引

编辑
resp = client.indices.forcemerge()
print(resp)
response = client.indices.forcemerge
puts response
const response = await client.indices.forcemerge();
console.log(response);
POST /_forcemerge

数据流和基于时间的索引

编辑

强制合并对于管理数据流的较旧的后备索引和其他基于时间的索引非常有用,尤其是在滚动之后。在这些情况下,每个索引仅在特定时间段内接收索引流量。一旦索引不再接收写入,其分片就可以强制合并为单个分段。

resp = client.indices.forcemerge(
    index=".ds-my-data-stream-2099.03.07-000001",
    max_num_segments="1",
)
print(resp)
response = client.indices.forcemerge(
  index: '.ds-my-data-stream-2099.03.07-000001',
  max_num_segments: 1
)
puts response
const response = await client.indices.forcemerge({
  index: ".ds-my-data-stream-2099.03.07-000001",
  max_num_segments: 1,
});
console.log(response);
POST /.ds-my-data-stream-2099.03.07-000001/_forcemerge?max_num_segments=1

这是一个好主意,因为单分段分片有时可以使用更简单、更高效的数据结构来执行搜索。