如何重命名集群中的索引?


110

我需要重命名集群中的几个索引(它们的名称必须更改,我不能使用别名)。

我看到没有支持的方法来执行此操作,发现的最接近的方法是重命名索引的目录,我在集群中尝试过此操作。

该集群有3台计算机AB并且C分片在每台计算机上复制。我关闭了上elasticsearch A,改名/var/lib/elasticsearch/security/nodes/0/indices/oldindexname/var/lib/elasticsearch/security/nodes/0/indices/newindexname并重新启动A

群集的状态为黄色,elasticsearch在做一些魔术来恢复正确的状态。一段时间后,我最终

  • oldindexname正在使用和完全复制(由回收BC我猜的)
  • newindexname 可用(我可以搜索它),但是头插件显示其碎片处于“未分配”状态,并且它们呈灰色显示(未复制)

在恢复过程中security.log显示以下消息:

[2015-02-20 11:02:33,461][INFO ][gateway.local.state.meta ] [A.example.com] dangled index directory name is [newindexname], state name is [oldindexname], renaming to directory name

虽然newindexname是可搜索的,但它肯定不是处于正常状态。

我通过删除恢复到先前的状态newindexname。群集恢复为绿色,没有任何“未分配”条目。

鉴于此,如何在群集中重命名oldindexnamenewindexname

注:最终的解决方案我心目中是滚动复制oldindexnewindex并删除oldindex之后。这将需要时间,因此,如果有更直接的解决方案,那就太好了。

Answers:


17

从ElasticSearch 7.4开始,重命名索引的最佳方法是使用新引入的Clone Index API复制索引,然后使用Delete Index API删除原始索引。

与出于相同目的而使用Snapshot API或Reindex API相比,Clone Index API的主要优势是速度,因为Clone Index API可以将段从源索引硬链接到目标索引,而无需重新处理其任何内容(在显然,支持硬链接的文件系统;否则,将在文件系统级别复制文件,这比其他方法要有效得多。克隆索引还可以确保目标索引在每个点上都与源索引相同(也就是说,与Reindex方法相反,无需手动复制设置和映射),并且不需要配置本地快照目录。

旁注:尽管此过程比以前的解决方案要快得多,但仍意味着需要停机。在实际的用例中,有必要使用重命名索引(例如,作为拆分,收缩或备份工作流中的一个步骤),但重命名索引不应成为日常操作的一部分。如果您的工作流程需要频繁的索引重命名,那么您应该考虑使用索引别名

下面是完整的操作序列索引重命名的例子source_indextarget_index。可以使用一些特定于ElasticSearch的控制台来执行它,例如Kibana中集成的控制台。请参见要点,以获取本示例的替代版本,curl而不是使用Elastic Search控制台。

# Make sure the source index is actually open
POST /source_index/_open

# Put the source index in read-only mode
PUT /source_index/_settings
{
  "settings": {
    "index.blocks.write": "true"
  }
}

# Clone the source index to the target name, and set the target to read-write mode
POST /source_index/_clone/target_index
{
  "settings": {
    "index.blocks.write": null 
  }
}

# Wait until the target index is green;
# it should usually be fast (assuming your filesystem supports hard links).
GET /_cluster/health/target_index?wait_for_status=green&timeout=30s

# If it appears to be taking too much time for the cluster to get back to green,
# the following requests might help you identify eventual outstanding issues (if any)
GET /_cat/indices/target_index
GET /_cat/recovery/target_index
GET /_cluster/allocation/explain

# Delete the source index
DELETE /source_index

162

您可以使用REINDEX来做到这一点。

Reindex不会尝试设置目标索引。它不会复制源索引的设置。您应在运行_reindex操作之前设置目标索引,包括设置映射,分片计数,副本等。

  1. 首先将索引复制到新名称
POST /_reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter"
  }
}
  1. 现在删除索引
DELETE /twitter

尽管这需要为两个索引(临时)留出空间,但这是简单且完全在服务器上的-因此,这似乎是迄今为止最好的解决方案(即使文档警告“实验”状态)。谢谢。
WoJ

2
如果映射有,这行得通_source: {enabled: false}吗?
哈拉尔德

2
@Harald没有,_reindex使用_source与原文档数据。
Agop

6
这会不会复制的映射twitternew_twitter,据我知道的。
尼克

3
我同意_reindex的解决方案,但问题应该更改。重新索引不仅是重命名。它甚至可以更改数据索引的方式。
lucabelluccini

62

要重命名索引,可以使用Elasticsearch Snapshot模块。

首先,您必须对索引进行快照。还原时可以重命名索引。

    POST /_snapshot/my_backup/snapshot_1/_restore
    {
     "indices": "jal",
     "ignore_unavailable": "true",
     "include_global_state": false,
     "rename_pattern": "jal",
     "rename_replacement": "jal1"
     }

named_replacement:-要在其中备份数据的新索引名。


4
Holycrap,这真是难以置信。谢谢!
克里斯·科格登

1
比公认的解决方案好得多!这实际上是索引的二进制副本,因此没有丢失任何内容的风险,并且不需要_source在索引中启用。我已经用这种方法重命名了一些多TB索引,没有任何问题。
夹克

2
@Jacket-我很高兴知道我的回答确实可以帮助您。
克里希纳·库马尔,

1
我同意,更好的解决方案,没有任何数据丢失的问题,更快以及对于比重新大指标
罗曼Hautefeuille

1
它保留映射吗?
Amogh Mishra

5

因此,没有直接的方法可以在ES中复制或重命名索引(我在自己的项目中进行了广泛搜索)

但是,一个非常简单的选择是使用流行的迁移工具[Elastic-Exporter]。

http://www.retailmenot.com/corp/eng/posts/2014/12/02/elasticsearch-cluster-migration/

[PS:这不是我的博客,只是偶然发现,发现它很好]

因此,您可以复制索引/类型,然后删除旧的索引/类型。


该链接不再起作用。我们还有其他地方可以找到它或有此信息吗?
Elachell'7

5

如果您无法REINDEX,则解决方法是使用别名。从官方文档中:

当针对特定索引工作时,elasticsearch中的API会接受一个索引名,并且在适用时会接受多个索引。索引别名API允许对别名使用名称进行别名,所有API都会自动将别名转换为实际的索引名称。别名也可以映射到多个索引,并且在指定别名时,别名将自动扩展为别名索引。别名也可以与过滤器关联,该过滤器将在搜索和路由值时自动应用。别名不能与索引同名。

请注意,如果您使用“更多喜欢此功能”,此解决方案将不起作用。https://github.com/elastic/elasticsearch/issues/16560


1
I need to rename several indexes in a cluster (their name must be changed I cannot use aliases).通过@WoJ
Thales P

原因别名不起作用:使用alias 要求您提前计划并创建原始索引名称as an alias为真实索引。然后,您可以创建一个新的别名,然后将旧的别名重用于其他用途。 但是,如果您只有一个real_index,则将无法访问old_data,对其进行别名,然后删除旧的real_index。别名现在不指向任何内容。
杰西·奇斯霍尔姆

@JesseChrisholm我认为一个人不能拥有“一点都没有指向的别名”。尝试删除real_index,您将看到别名“别名”也将被删除。
mgaert

5

实现重命名或更改索引映射的另一种不同方法是使用logstash重新索引。这是logstash 2.1配置的示例:

input {
  elasticsearch {
   hosts => ["es01.example.com", "es02.example.com"]
   index => "old-index-name"
   size => 500
   scroll => "5m"
  }
}
filter {

 mutate {
  remove_field => [ "@version" ]
 }

 date {
   "match" => [ "custom_timestamp", "MM/dd/YYYY HH:mm:ss" ]
   target => "@timestamp"
 }

}
output {
 elasticsearch {
   hosts => ["es01.example.com", "es02.example.com" ]
   manage_template => false
   index => "new-index-name"
 }
}

4
因此,您是说重新索引Elasticsearch索引的最佳方法是安装Logstash,然后使用该索引重新索引?似乎有点矫kill过正,尤其是如果您实际上不想要/不使用Logstash ...
M. Justin

答案中唯一的问题是“最好的”部分。我会说“另一种方式”。除此之外,这是一个很好的答案
罗伯特(Robert Robert)


-5

万一有人仍然需要它,以防万一。成功但非官方的重命名索引的方法是:

  1. 关闭需要重命名的索引
  2. 重命名主节点和数据节点的所有数据目录中的索引文件夹。
  3. 重新打开旧的封闭索引(我使用kofp插件)。旧索引将重新打开,但保持未分配状态。新索引将显示为关闭状态
  4. 重新打开新索引
  5. 删除旧索引

如果您碰巧遇到此错误“索引目录名称为悬挂”,请删除所有主节点(而非数据节点)中的索引文件夹,然后重新启动其中一个数据节点。


2
强烈建议不要使用Elastic。如果需要,请确保进行备份。
lucabelluccini

我不明白索引名称在数据目录中出现的位置。当我查看/ var / lib / elasticsearch / nodes / 0 / indices /时,目录名称是随机生成的,例如“ 1aS4RusHSYWLdt-Wx7NnBw”(Elasticsearch版本5.6.3)
JohanBoulé17年

1
@JohanBoulé,此方法自Elasticsearch版本5起不再有效。
Anh Le

@lucabelluccini,同意。最好只保留它们并使用别名。
Anh Le
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.