【问题标题】:Elasticsearch Reindexing race conditionElasticsearch 重新索引竞争条件
【发布时间】:2018-11-22 16:10:38
【问题描述】:

您好 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 如何确保也考虑到此删除在新索引中?

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

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

提前致谢!

【问题讨论】:

    标签: elasticsearch kibana


    【解决方案1】:

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

    如果在重新索引过程中仍会传入文档 工作(这可能需要很多时间),如何 重新索引过程确保文档将在 旧索引(以便能够在重新索引过程中搜索它 工作)但仍会正确地重新索引到新索引?

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

    假设source_index 的状态从t 变为t+1

    如果您在tdest_index 运行了重新索引作业,它仍然会消耗source_indext 的快照数据。您需要再次运行重新索引作业以获得source_index 的最新数据,即dest_indext+1 的数据。

    source_index 的摄取和从source_indexdestination_index 的摄取都是独立的事务/进程。

    重新索引作业永远不会总是保证source_indexdest_index 之间的一致性。

    如果一个文档在旧索引中被修改,在它被修改之后 重新索引(映射到新索引),而重新索引过程是 工作,ElasticSearch 将如何确保此修改也是 是否被纳入新索引?

    在新索引中不会考虑它,因为重新索引将使用source_index 在时间t 的快照。

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

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

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

    (类似于2。)如果在旧索引中删除了一条记录,则在它具有 被重新索引(映射到新索引),而重新索引过程 正在工作,ElasticSearch 将如何确保此删除也是 是否被纳入新索引?

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

    版本类型:外部

    顺便说一句,在重新索引期间您可以做的一个有趣的事情是利用 version_type:external,这将确保仅重新索引来自 source_index 的更新/缺失文档在dest_index

    您可以参考此LINK 了解更多信息

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

    【讨论】:

    • 感谢详细的回复!非常好的外部版本类型提示,我不知道!不幸的是,重新索引大量数据需要很长时间(可能需要几天),所以我不确定调度程序是否是运行多个重新索引任务的好主意,因为它会在整个持续时间内减慢平台速度?我会等一两天让其他人也回答,但如果没有其他人回答,我会接受你的回答。
    • 当然。抱歉,如果我的解释不准确,那么您应该仅将调度程序用于增量更新,而不是用于完整索引。我们所做的是在不同时间安排多个作业以进行增量更新,但我们很少进行全索引(但我们仍有一项工作要做全索引)。我们有大约 30-40 个不同的来源,我们在各种索引中摄取,但我们确保以这样的方式安排作业,即一次运行的增量作业不超过两个或三个。
    • 我明白了,谢谢你的回复!您的解释很清楚,增量更新似乎是个好主意,因为完全重新索引会非常耗时。
    • 再添加一个注释,如果您使用调度程序,增量更新将以拉取方式发生,即调度程序将是提取/拉取更新的人。我们正在考虑采用基于事件的方法,但这取决于源内容和管理它的团队。如果您可以控制源数据(不幸的是我们没有),我建议您实现消息队列,以便将任何更新/事件实时传送到弹性搜索(源作为发布者,弹性搜索作为消费者),这将消除对调度程序的需求。
    猜你喜欢
    • 2015-06-27
    • 2022-01-23
    • 2018-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多