有没有更聪明的方法来重新索引elasticsearch?

我问,因为我们的search处于不断变化的状态,但是每当我们对索引进行更改(更改标记器或filter,或者分片/副本的数量)时,我们不得不吹掉整个索引,将所有Rails模型重新索引到Elasticsearch中…这意味着我们必须考虑停机时间来重新索引所有logging。

有没有更聪明的方法来做到这一点,我不知道?

我认为@卡尔米是正确的。 不过,让我解释一下更简单一些。 我需要偶尔使用一些新的属性或分析设置升级生产模式。 我最近开始使用下面描述的场景来进行实时,恒定负载,零停机索引迁移。 你可以远程做到这一点。

这里是步骤:

假设:

  • 你有索引real1和别名real_writereal_read指向它,
  • 客户端只写入real_write ,只读real_read
  • 文档的_source属性可用。

1.新的索引

使用您select的新映射和设置创buildreal2索引。

2.编写器别名开关

使用以下批量查询开关写入别名。

 curl -XPOST 'http://esserver:9200/_aliases' -d ' { "actions" : [ { "remove" : { "index" : "real1", "alias" : "real_write" } }, { "add" : { "index" : "real2", "alias" : "real_write" } } ] }' 

这是primefaces操作。 从这个时候开始, real2在所有节点上都填充了新的客户端数据。 读者仍然通过real_read使用旧的real_read 。 这是最终的一致性。

3.旧数据迁移

数据必须从real1迁移到real2 ,但real2中的新文档不能被旧条目覆盖。 迁移脚本应使用bulk API与create操作(而不是indexupdate )。 我使用简单的Ruby脚本es-reindex ,它具有很好的ETA状态:

 $ ruby es-reindex.rb http://esserver:9200/real1 http://esserver:9200/real2 

更新2017年你可能会考虑新的Reindex API,而不是使用脚本。 它有很多有趣的function,如冲突报告等

4.读者别名开关

现在real2是最新的,客户正在写信给他,但他们仍然从real1读取。 让我们更新读者别名:

 curl -XPOST 'http://esserver:9200/_aliases' -d ' { "actions" : [ { "remove" : { "index" : "real1", "alias" : "real_read" } }, { "add" : { "index" : "real2", "alias" : "real_read" } } ] }' 

5.备份和删除旧索引

写入和读取到real2 。 您可以从ES群集备份和删除real1索引。

完成!

是的,如何在没有停机的情况下重新build立索引数据,有更明智的方法。

首先,永远不要使用“最终”索引名称作为真正的索引名称。 因此,如果您想要将索引命名为“文章”,请不要将该名称用作物理索引,而应创build一个索引,如“articles-2012-12-12”或“articles-A”,“articles -1“等

其次,创build一个指向该索引的别名“别名”。 您的应用程序将使用此别名,因此您将永远不需要手动更改索引名称,重新启动应用程序等。

第三,当你想要或者需要重新索引数据时,将它们重新索引到一个不同的索引中 ,比如说“articles-B”–Tire的索引工具中的所有工具都支持你。

完成后,将别名指向新的索引。 通过这种方式,不仅可以最大限度地减less停机时间(不存在任何问题),还可以获得安全的快照:如果以某种方式将索引搞乱了,可以切换回旧索引,直到解决问题。

写了一篇关于我如何处理reindexing而不是最近没有停机的博客文章。 花费一些时间来弄清所有需要到位的小事情。 希望这可以帮助!

https://summera.github.io/infrastructure/2016/07/04/reindexing-elasticsearch.html

总结:

步骤1:准备新的索引

用你的新映射创build你的新索引。 这可以在Elasticsearch的同一个实例上,也可以在一个全新的实例上。

第2步:保持索引最新

当你重新索引时,你希望保持你的新旧索引是最新的。 对于写入操作,这可以通过将写入操作发送到新老索引上的后台工作者来完成。

删除有点棘手,因为删除和重新索引logging到新索引之间存在争用条件。 因此,您需要跟踪在reindex期间需要删除的logging,并在完成后处理这些logging。 如果你没有执行很多删除操作,另一种方法是在你的reindex期间消除删除的可能性。

步骤3:进行重生

您需要使用滚动式search来读取数据和批量API以进行插入。 由于在步骤2之后,您将在后台将新的和更新的文档写入新的索引,您希望确保不会使用批量API请求更新新索引中的现有文档。

这意味着您要批量处理API请求的操作是创build,而不是索引。 从文档 :“如果已经存在具有相同索引和types的文档,则创build将失败,而索引将根据需要添加或replace文档”。 这里的要点是你不希望滚动的search快照中的旧数据覆盖新索引中的新数据。

github上有一个很棒的脚本来帮助你完成这个过程: es-reindex 。

第四步:切换

完成重新索引后,就可以将search切换到新索引。 您需要重新打开删除或处理新索引的入队删除作业。 您可能会注意到,search新索引起初有点慢。 这是因为Elasticsearch和JVM需要时间热身。

执行您需要的任何代码更改,以便您的应用程序开始search新的索引。 您可以继续写入旧索引,以防止遇到问题并需要回滚。 如果你觉得这是不必要的,你可以停止写信给它。

第5步:清理

此时你应该完全转换到新的索引。 如果一切进展顺利,请执行任何必要的清理,例如:

  • 删除旧的索引主机,如果它不同于新的
  • 删除与旧索引相关的序列化代码

也许创build另一个索引,并将所有数据重新索引到该索引,然后在重新索引时进行切换?