【问题标题】:How to deal with Elasticsearch index delay如何处理 Elasticsearch 索引延迟
【发布时间】:2015-10-08 13:50:40
【问题描述】:

这是我的场景:

我有一个包含用户列表的页面。我通过 Web 界面创建了一个新用户并将其保存到服务器。服务器对elasticsearch中的文档进行索引并成功返回。然后我被重定向到不包含新用户的列表页面,因为在 elasticsearch 中搜索文档可能需要长达 1 秒的时间

Near real-time search in elasticsearch.

弹性搜索指南说您可以手动刷新索引,但说不要在生产中这样做。

...不要在生产中每次索引文档时都进行手动刷新;它会损害你的表现。相反,您的应用程序需要了解 Elasticsearch 的近实时特性并考虑到这一点。

我想知道其他人是如何解决这个问题的?我希望有一个事件或我可以听的东西会告诉我文档何时可供搜索,但似乎没有类似的东西。简单地等待 1 秒是合理的,但这似乎是个坏主意,因为它可能花费的时间可能比这要少得多。

谢谢!

【问题讨论】:

  • 我认为问题在于您正在尝试使用搜索数据库来查找事务性内容。我可能会使用具有真实事务的数据库,然后使用 ElasticSearch 进行搜索和高级过滤,而不是列表页面。

标签: elasticsearch


【解决方案1】:

即使您可以强制 ES 自我刷新,您也正确地注意到它可能会损害性能。围绕这一点以及人们经常做的事情(包括我自己)的一个解决方案是提供实时错觉。最后,这只是一个用户体验挑战,而不是真正的技术限制。

在重定向到用户列表时,您可以人为地将刚刚创建的新记录包含到用户列表中,就好像该记录已由 ES 本身返回一样。没有什么能阻止你这样做。当你决定刷新页面时,新的用户记录将被 ES 正确返回,没有人关心该记录来自哪里,用户此时关心的只是他想看到新的记录他刚刚被创造出来,只是因为我们习惯于按顺序思考。

实现此目的的另一种方法是重新加载一个空的用户列表骨架,然后通过 Ajax 或其他异步方式检索用户列表并显示它。

另一种方法是在 UI 上提供视觉提示/线索,表明后台正在发生某些事情,并且很快就会有更新。

归根结底,这一切都归结为不是让用户感到惊讶,而是为他们提供足够的线索,让他们知道发生了什么、正在发生什么以及他们仍然应该期待发生什么。

更新

为了完整起见,这个答案早于 ES5,它引入了一种方法来确保索引调用不会返回,直到文档在搜索索引时可见或返回错误代码。通过在索引数据时使用?refresh=wait_for,您可以确定当 ES 响应时,新数据将被索引。

【讨论】:

  • 当实际写入失败时会发生什么?你让人们相信它是创造出来的,而它不是真的
  • @user310291 你能详细说明一下吗?
  • 如果前端显示写操作成功但实际上在后端写失败,那么这会让用户在下一次操作时惊讶于保存的内容不存在。前端可以只显示一个闪光告诉用户它失败了然后重置为事实。
  • NEST 库是否支持 ?refresh=wait_for?
  • @IvanDoroshenko 是的,它是:github.com/elastic/elasticsearch-net/blob/…
【解决方案2】:

Elasticsearch 5 有一个选项可以阻止索引请求,直到下一次刷新发生:

?refresh=wait_for

见:https://www.elastic.co/guide/en/elasticsearch/reference/5.0/docs-refresh.html#docs-refresh

【讨论】:

  • NEST 库是否支持 ?refresh=wait_for?
【解决方案3】:

这是我在 Angular 应用程序中为解决此问题所做的代码片段。在组件中:

async doNewEntrySave() {
    try {
      const resp = await this.client.createRequest(this.doc).toPromise();
      this.modeRefreshDelay = true;
      setTimeout(() => {
        this.modeRefreshDelay = false;
        this.refreshPage();
      }, 2500);
    } catch (err) {
      this.error.postError(err);
    }
  }

在模板中:

<div *ngIf="modeRefreshDelay">
  <h2>Waiting for update ...</h2>
</div>

我知道这是一个快速而肮脏的解决方案,但它说明了用户体验应该如何工作。显然,如果现实世界的延迟超过 2.5 秒,它就会中断。更高级的版本会循环,直到新记录出现在页面延迟中(当然有限制)。

除非您完全重新设计 ElasticSearch,否则您在成功 索引操作和该文档出现在搜索结果中的时间之间总会有一些延迟。

【讨论】:

    【解决方案4】:

    索引完成后数据应立即可用。几个一般性问题:

    1. 您是否检查过 CPU 和 RAM 以确定您是否对 ES 集群征税?如果是这样,您可能需要加强硬件配置以解决它。 ES 喜欢 RAM!

    2. 您使用的是 NAS(网络附加存储)还是 EBS 等虚拟化存储?由于延迟,Elastic 建议不要这样做。如果您可以使用 DAS(直连)和 SSD,您的状态会好很多。

    以 AWS 为例,从 m4.xlarge 实例迁移到 r3.xlarge 为我们带来了巨大的性能提升。

    【讨论】:

      猜你喜欢
      • 2018-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-19
      • 1970-01-01
      • 1970-01-01
      • 2010-12-08
      相关资源
      最近更新 更多