收缩索引 API

编辑

将现有索引收缩为具有更少主分片的新索引。

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

请求

编辑

POST /<索引>/_shrink/<目标索引>

PUT /<索引>/_shrink/<目标索引>

前提条件

编辑
  • 如果启用了 Elasticsearch 安全功能,则您必须具有索引的 manage 索引权限
  • 在您可以收缩索引之前

    • 索引必须是只读的。
    • 索引中每个分片的副本必须驻留在同一节点上。
    • 索引必须具有 green 健康状态

为了使分片分配更容易,我们建议您也删除索引的副本分片。您可以稍后在收缩操作中重新添加副本分片。

您可以使用以下 更新索引设置 API 请求来删除索引的副本分片,并将索引的其余分片重新定位到同一节点。

resp = client.indices.put_settings(
    index="my_source_index",
    settings={
        "settings": {
            "index.number_of_replicas": 0,
            "index.routing.allocation.require._name": "shrink_node_name"
        }
    },
)
print(resp)
response = client.indices.put_settings(
  index: 'my_source_index',
  body: {
    settings: {
      'index.number_of_replicas' => 0,
      'index.routing.allocation.require._name' => 'shrink_node_name'
    }
  }
)
puts response
const response = await client.indices.putSettings({
  index: "my_source_index",
  settings: {
    settings: {
      "index.number_of_replicas": 0,
      "index.routing.allocation.require._name": "shrink_node_name",
    },
  },
});
console.log(response);
PUT /my_source_index/_settings
{
  "settings": {
    "index.number_of_replicas": 0,                                
    "index.routing.allocation.require._name": "shrink_node_name"  
  }
}

删除索引的副本分片。

将索引的分片重新定位到 shrink_node_name 节点。 请参阅 索引级分片分配过滤

重新定位源索引可能需要一段时间。 可以使用 _cat recovery API跟踪进度,或者可以使用 cluster health API 并使用 wait_for_no_relocating_shards 参数来等待所有分片都重新定位。

然后,您可以使用 添加索引块 API 使用以下请求使索引只读

resp = client.indices.add_block(
    index="my_source_index",
    block="write",
)
print(resp)
response = client.indices.add_block(
  index: 'my_source_index',
  block: 'write'
)
puts response
const response = await client.indices.addBlock({
  index: "my_source_index",
  block: "write",
});
console.log(response);
PUT /my_source_index/_block/write

描述

编辑

收缩索引 API 允许您将现有索引收缩为具有更少主分片的新索引。 目标索引中请求的主分片数必须是源索引中分片数的因子。 例如,具有 8 个主分片的索引可以收缩为 421 个主分片,或者具有 15 个主分片的索引可以收缩为 531 个主分片。 如果索引中的分片数是质数,则只能将其收缩为单个主分片。 在收缩之前,索引中每个分片的(主分片或副本)副本必须存在于同一节点上。

数据流上的当前写入索引不能收缩。 为了收缩当前写入索引,必须首先 翻转数据流,以便创建新的写入索引,然后可以收缩先前的写入索引。

收缩如何工作

编辑

收缩操作

  1. 创建一个与源索引具有相同定义的新目标索引,但主分片数量较少。
  2. 将源索引中的段硬链接到目标索引中。(如果文件系统不支持硬链接,则所有段都将复制到新索引中,这是一个耗时得多的过程。 此外,如果使用多个数据路径,则如果它们不在同一磁盘上,则不同数据路径上的分片需要完整复制段文件,因为硬链接不能跨磁盘工作)
  3. 恢复目标索引,就像它是一个刚刚重新打开的已关闭索引一样。 将分片恢复到 索引设置 .routing.allocation.initial_recovery._id

收缩索引

编辑

要将 my_source_index 收缩为名为 my_target_index 的新索引,请发出以下请求

resp = client.indices.shrink(
    index="my_source_index",
    target="my_target_index",
    settings={
        "index.routing.allocation.require._name": None,
        "index.blocks.write": None
    },
)
print(resp)
response = client.indices.shrink(
  index: 'my_source_index',
  target: 'my_target_index',
  body: {
    settings: {
      'index.routing.allocation.require._name' => nil,
      'index.blocks.write' => nil
    }
  }
)
puts response
const response = await client.indices.shrink({
  index: "my_source_index",
  target: "my_target_index",
  settings: {
    "index.routing.allocation.require._name": null,
    "index.blocks.write": null,
  },
});
console.log(response);
POST /my_source_index/_shrink/my_target_index
{
  "settings": {
    "index.routing.allocation.require._name": null, 
    "index.blocks.write": null 
  }
}

清除从源索引复制的分配要求。

清除从源索引复制的索引写入块。

一旦将目标索引添加到集群状态,上述请求将立即返回——它不会等待收缩操作开始。

只有当索引满足以下要求时,才能收缩索引

  • 目标索引必须不存在。
  • 源索引的主分片必须多于目标索引。
  • 目标索引中的主分片数必须是源索引中的主分片数的因子。 源索引必须具有比目标索引更多的主分片。
  • 索引在其所有分片中总共不能包含超过 2,147,483,519 个文档,这些分片将被收缩到目标索引上的单个分片中,因为这是可以容纳在单个分片中的最大文档数。
  • 处理收缩过程的节点必须有足够的可用磁盘空间来容纳现有索引的第二个副本。

_shrink API 类似于 create index API,并接受目标索引的 settingsaliases 参数

resp = client.indices.shrink(
    index="my_source_index",
    target="my_target_index",
    settings={
        "index.number_of_replicas": 1,
        "index.number_of_shards": 1,
        "index.codec": "best_compression"
    },
    aliases={
        "my_search_indices": {}
    },
)
print(resp)
response = client.indices.shrink(
  index: 'my_source_index',
  target: 'my_target_index',
  body: {
    settings: {
      'index.number_of_replicas' => 1,
      'index.number_of_shards' => 1,
      'index.codec' => 'best_compression'
    },
    aliases: {
      my_search_indices: {}
    }
  }
)
puts response
const response = await client.indices.shrink({
  index: "my_source_index",
  target: "my_target_index",
  settings: {
    "index.number_of_replicas": 1,
    "index.number_of_shards": 1,
    "index.codec": "best_compression",
  },
  aliases: {
    my_search_indices: {},
  },
});
console.log(response);
POST /my_source_index/_shrink/my_target_index
{
  "settings": {
    "index.number_of_replicas": 1,
    "index.number_of_shards": 1, 
    "index.codec": "best_compression" 
  },
  "aliases": {
    "my_search_indices": {}
  }
}

目标索引中的分片数。 这必须是源索引中的分片数的因子。

最佳压缩仅在对索引进行新写入时生效,例如当 强制合并分片到单个段时。

映射不能在 _shrink 请求中指定。

监视收缩过程

编辑

可以使用 _cat recovery API监视收缩过程,或者可以使用 cluster health API,通过将 wait_for_status 参数设置为 yellow 来等待所有主分片都已分配。

_shrink API 在将目标索引添加到集群状态后立即返回,然后再分配任何分片。 此时,所有分片都处于 unassigned 状态。 如果由于任何原因无法在收缩节点上分配目标索引,则其主分片将保持 unassigned 状态,直到可以在该节点上分配为止。

一旦分配了主分片,它将移动到状态 initializing,收缩过程开始。 当收缩操作完成时,该分片将变为 active。 此时,Elasticsearch 将尝试分配任何副本,并且可能会决定将主分片重新定位到另一个节点。

等待活动分片

编辑

由于收缩操作会创建一个新索引来收缩分片,因此索引创建时的 等待活动分片 设置也适用于收缩索引操作。

路径参数

编辑
<索引>
(必需,字符串)要收缩的源索引的名称。
<目标索引>

(必需,字符串)要创建的目标索引的名称。

索引名称必须满足以下条件

  • 仅小写
  • 不能包含 \/*?"<>|、` ` (空格字符)、,#
  • 7.0 之前的索引可以包含冒号 (:),但这已被弃用,并且在 7.0+ 中将不受支持
  • 不能以 -_+ 开头
  • 不能是 ...
  • 长度不能超过 255 个字节(请注意它是字节,因此多字节字符将更快地计入 255 的限制)
  • . 开头的名称已弃用,但 隐藏索引 和插件管理的内部索引除外

查询参数

编辑
wait_for_active_shards

(可选,字符串)在继续操作之前必须处于活动状态的每个分片的副本数。 设置为 all 或任何非负整数,直到索引中每个分片的总副本数 (number_of_replicas+1)。 默认为 1,表示仅等待每个主分片变为活动状态。

请参阅 活动分片

master_timeout
(可选,时间单位)等待主节点的时间段。 如果主节点在超时到期之前不可用,则请求失败并返回错误。 默认为 30s。 也可以设置为 -1 以指示请求永远不应超时。
timeout
(可选,时间单位)在更新集群元数据后等待集群中所有相关节点响应的时间段。 如果在超时到期之前没有收到响应,则集群元数据更新仍然适用,但响应将表明它没有被完全确认。 默认为 30s。 也可以设置为 -1 以指示请求永远不应超时。

请求正文

编辑
aliases

(可选,对象对象)结果索引的别名。

aliases 对象的属性
<别名>

(必需,对象)键是别名名称。 索引别名名称支持 日期数学

对象正文包含别名的选项。 支持空对象。

<别名> 的属性
filter
(可选,查询 DSL 对象)用于限制别名可以访问的文档的查询。
index_routing
(可选,字符串)用于将索引操作路由到特定分片的值。 如果指定,这将覆盖索引操作的 routing 值。
is_hidden
(可选,布尔值)如果 true,则别名是 隐藏的。默认为 false。别名的所有索引都必须具有相同的 is_hidden 值。
is_write_index
(可选,布尔值)如果 true,则索引是别名的 写入索引。默认为 false
routing
(可选,字符串)用于将索引和搜索操作路由到特定分片的值。
search_routing
(可选,字符串) 用于将搜索操作路由到特定分片的值。如果指定,此值将覆盖搜索操作的 routing 值。
settings
(可选,索引设置对象) 目标索引的配置选项。请参阅索引设置
max_primary_shard_size
(可选,字节大小单位) 目标索引的最大主分片大小。用于查找目标索引的最佳分片数量。当设置此参数时,目标索引中每个分片的存储空间将不会大于此参数。目标索引的分片计数仍然是源索引分片计数的因数,但如果此参数小于源索引中单个分片的大小,则目标索引的分片计数将等于源索引的分片计数。例如,当此参数设置为 50gb 时,如果源索引有 60 个主分片,总计 100gb,则目标索引将有 2 个主分片,每个分片大小为 50gb;如果源索引有 60 个主分片,总计 1000gb,则目标索引将有 20 个主分片;如果源索引有 60 个主分片,总计 4000gb,则目标索引仍然有 60 个主分片。此参数与 settings 中的 number_of_shards 冲突,只能设置其中一个。