Split Index

拆分索引API允许您将现有索引拆分为新索引,其中每个原始主分片在新索引中被拆分为两个或多个主分片。

可以拆分索引的次数(以及每个原始分片可以拆分成的分片数)由index.number_of_routing_shards设置确定。路由分片的数量指定内部使用的散列空间,以便在具有一致散列的分片中分发文档。例如,number_of_routing_shards设置为30(5 x 2 x 3)的5个分片索引可以按因子2或3分割。换句话说,它可以按如下方式拆分:

  • 5 → 10 → 30 (split by 2, then by 3)
  • 5 → 15 → 30 (split by 3, then by 2)
  • 5 → 30 (split by 6)

虽然您可以在索引创建时显式设置index.number_of_routing_shards设置,但默认值取决于原始索引中主分片的数量。默认设计允许您按因子2分割,最多1024个分片。

但是,必须考虑原始分片的原始数量。例如,使用5个主分片创建的索引可以分为10,20,40,80,160,320或最多640个分片(使用单个分割动作或多个分割动作)。

如果原始索引包含一个主分片(或多分片索引已缩小为单个主分片),则索引可以拆分为大于1的任意数量的分片。默认路由数的属性然后,分片将应用于新拆分的索引。

How does splitting work?

拆分的工作原理如下:

  • 首先,它创建一个新的目标索引,其定义与源索引相同,但主分片数量较多。
  • 然后,它将源索引中的段硬链接到目标索引。(如果文件系统不支持硬链接,则会将所有段复制到新索引中,这是一个更耗时的过程。)
  • 创建低级文件后,将再次对所有文档进行哈希处理,以删除属于不同分片的文档。
  • 最后,它恢复了目标索引,好像它是一个刚重新打开的封闭索引。

Why doesn’t Elasticsearch support incremental resharding ? 为什么Elasticsearch不支持增量重新分片

从N分片到N + 1分片,又名。增量重新分片,确实是许多键值存储支持的功能。添加新分片并将新数据推送到此新分片只不是一个选项:这可能是索引瓶颈,并且在给定其_id时确定文档属于哪个分片,这对于获取,删除和更新请求是必需的,会变得相当复杂。这意味着我们需要使用不同的散列方案重新平衡现有数据。

键值存储最有效地实现此目的的方法是使用一致的散列。当从N增加到N + 1的分片数量时,一致散列仅需要重新定位1 / N个密钥。然而,Elasticsearch的存储单元,分片是Lucene索引。由于它们采用面向搜索的数据结构,占据了Lucene索引的很大一部分,只有5%的文档,删除它们并在另一个分片上索引它们通常会比使用键值存储的成本高得多。通过乘法因子增加分片数量时,此成本保持合理,如上一节所述:这允许Elasticsearch在本地执行拆分,从而允许在索引级别执行拆分,而不是重新索引需要的文档移动,以及使用硬链接进行有效的文件复制。

在仅附加数据的情况下,可以通过创建新索引并向其推送新数据来获得更大的灵活性,同时添加覆盖读取操作的旧索引和新索引的别名。假设旧索引和新索引分别具有M和N分片,与搜索具有M + N个分片的索引相比,这没有开销。

Preparing an index for splitting 准备拆分索引

创建一个新索引:

  1. PUT my_source_index
  2. {
  3. "settings": {
  4. "index.number_of_shards" : 1
  5. }
  6. }

为了拆分索引,索引必须标记为只读,并且健康为绿色。

这可以通过以下请求来实现:

  1. PUT /my_source_index/_settings
  2. {
  3. "settings": {
  4. "index.blocks.write": true #@1
  5. }
  6. }

@1: 阻止对此索引的写入操作,同时仍允许更改元数据,如删除索引。

Splitting an index

要将my_source_index拆分为名为my_target_index的新索引,请发出以下请求:

  1. POST my_source_index/_split/my_target_index
  2. {
  3. "settings": {
  4. "index.number_of_shards": 2
  5. }
  6. }

将目标索引添加到群集状态后,上述请求会立即返回 - 它不会等待分割操作开始。

_split API类似于create index API,并接受目标索引的设置和别名参数:

  1. POST my_source_index/_split/my_target_index
  2. {
  3. "settings": {
  4. "index.number_of_shards": 5 #@1
  5. },
  6. "aliases": {
  7. "my_search_indices": {}
  8. }
  9. }

@1: 目标索引中的分片数。这必须是源索引中分片数量的一个因素。

Monitoring the split process

可以使用_cat恢复API监视拆分进程,或者可以使用集群运行状况API等待,直到通过将wait_for_status参数设置为黄色来分配所有主分片。

在分配任何分片之前,只要目标索引已添加到群集状态,_split API就会立即返回。此时,所有分片都处于未分配的状态。如果由于任何原因无法分配目标索引,则其主分片将保持未分配状态,直到可以在该节点上分配该分片。

一旦分配了主分片,它就会转到状态初始化,并开始分割过程。分割操作完成后,分片将变为活动状态。此时,Elasticsearch将尝试分配任何副本,并可能决定将主分片重定位到另一个节点。

Wait For Active Shards

由于拆分操作会创建一个新的索引以将分片拆分为,因此索引创建的等待活动分片设置也适用于拆分索引操作。