首页 > 解决方案 > Elasticsearch 重新索引竞争条件

问题描述

您好 elasticsearch 用户/专家,

我在理解 Elasticsearch 的 reindex api 的竞争条件问题时遇到了一些麻烦,我想知道是否有人找到了解决方案。

我搜索了很多地方,找不到任何明确的解决方案(大多数解决方案可以追溯到 reindex api 之前)。

您可能知道,(现在)重新索引文档的标准方法(例如,在更改映射之后)是使用别名。假设别名指向“old_index”。然后我们使用新映射创建一个名为“new_index”的新索引,我们调用 reindex api 将文档从“old_index”重新索引到“new_index”,然后将别名切换为指向 new_index(并删除指向 old_index 的别名指针)。这似乎是重新索引的标准方式,这也是我在我访问的几乎所有最近的网站上看到的。

对于使用此方法,我的问题如下,虽然我不希望停机(因此用户应该仍然能够搜索文档),并且我仍然希望能够在重新索引过程发生时将文档注入 ElasticSearch:

  1. 如果在重新索引过程正在进行时仍会传入文档(这可能会花费很多时间),重新索引过程将如何确保将文档摄取到旧索引中(以便能够在重新索引时搜索它进程正在运行)但仍会正确地重新索引到新索引?
  2. 如果文档在旧索引中被修改,在它被重新索引(映射到新索引)之后,当重新索引过程正在工作时,ElasticSearch 将如何确保新索引中也考虑到这种修改?
  3. (类似于 2。)如果在旧索引中删除了一条记录,在它被重新索引(映射到新索引)之后,在重新索引过程正在进行时,ElasticSearch 如何确保在新索引中也考虑到这种删除指数?

基本上在无法为文档犯任何索引错误的情况下,如何继续确保重新索引不会出现上述任何问题?

有人知道吗?如果没有任何停机时间就没有解决方案,那么在这种情况下,我们将如何以最少的停机时间进行?

提前致谢!

标签: elasticsearchkibana

解决方案


道歉,如果它太冗长,但我的两分钱:

如果在重新索引过程正在进行时仍会传入文档(这可能会花费很多时间),重新索引过程将如何确保将文档摄取到旧索引中(以便能够在重新索引时搜索它进程正在运行)但仍会正确地重新索引到新索引?

当从源到目标进行重新索引时,别名将(并且必须)仍然指向source_index. 此索引的所有修改/更改都以独立的方式发生,这些更新/删除应立即生效。

假设状态source_indext变为t+1

如果您在tto运行了重新索引作业dest_index,它仍然会消耗source_indexat的快照数据t。您需要再次运行重新索引作业才能source_indext+1.dest_index

摄取 atsource_index和摄取 from source_indextodestination_index都是独立的事务/过程。

重新索引作业永远不会保证source_index和之间的一致性dest_index

如果文档在旧索引中被修改,在它被重新索引(映射到新索引)之后,当重新索引过程正在工作时,ElasticSearch 将如何确保新索引中也考虑到这种修改?

新索引中不会考虑它,因为重新索引将使用source_indexat time的快照t

您需要再次执行重新索引。对于这种通用方法,将有一个调度程序,每隔几个小时运行一次重新索引过程。

您可以source_index每隔几分钟(如果您使用调度程序)或实时(如果您使用任何基于事件的方法)进行更新/删除。

但是,对于完整索引(从source_indexdest_index),将其安排为一天一次或两次,因为这是一个昂贵的过程。

(类似于 2。)如果在旧索引中删除了一条记录,在它被重新索引(映射到新索引)之后,在重新索引过程正在进行时,ElasticSearch 如何确保在新索引中也考虑到这种删除指数?

同样,您需要运行一个新的作业/重新索引过程。

版本类型:外部

顺便说一句,在重新索引期间您可以做的一个有趣的事情是利用version_type:external它确保只有更新/丢失的文档source_index会被重新索引dest_index

您可以参考此链接以获取有关此的更多信息

POST _reindex
{
  "source": {
    "index": "source_index"
  },
  "dest": {
    "index": "dest_index",
    "version_type": "external"
  }
}

推荐阅读