当前位置: 首页 > 面试题库 >

使用Elasticsearch作为时间窗口存储的性能问题

陈夜洛
2023-03-14
问题内容

我们几乎将elasticsearch用作缓存,存储在时间窗口中找到的文档。我们不断插入许多不同大小的文档,然后使用结合日期过滤器的文本查询在ES中进行搜索,因此当前线程不会获取已经看到的文档。像这样:

“(((word1 AND word 2)OR(word3 AND word4))AND insertDate> 1389000”

我们使用TTL功能在elasticsearch中将数据保留30分钟。如今,我们至少有3台机器每分钟每分钟插入大量新文件,并每隔一台机器不断地使用上述查询进行搜索。

我们在索引和检索这些文档方面遇到很多麻烦,我们没有获得由ES索引和返回的文档的大量吞吐量。每秒甚至无法索引200个文档。

我们认为问题在于同时进行查询,插入和TTL删除。我们不需要使旧数据保持弹性,我们只需要在给定时间以较小的时间窗对具有弹性索引的文档进行索引。我们应该怎么做才能提高绩效?

提前致谢

机型:

  • Amazon EC2中型实例(3.7 GB RAM)

附加信息:

  • 用于建立索引的代码是这样的:https : //gist.github.com/dggc/6523411

  • 我们的elasticsearch.json配置文件:https : //gist.github.com/dggc/6523421

编辑

很抱歉给您提供一些反馈的时间过长。在我们公司,事情有点忙碌,我选择等待更平静的时期,以更详细地说明我们如何解决问题。我们仍然需要做一些基准测试来衡量实际的改进,但是重点是我们解决了这个问题:)

首先,我认为索引性能问题是由部分使用错误引起的。如前所述,我们将Elasticsearch用作一种缓存,用于在30分钟的时间范围内查找文档。我们在elasticsearch中寻找内容与某个查询匹配且插入日期在一定范围内的文档。然后,Elastic会返回完整的文档json(除索引内容外,还有大量数据)。我们的配置错误地(除了content和insertDate字段之外)错误地为文档json字段建立了索引,我们认为这是造成索引性能问题的主要原因。

但是,正如此处答案所建议的,我们还进行了许多修改,我们认为这些修改也改善了性能:

  • 现在,我们不使用TTL功能,而是在通用别名下使用两个“滚动索引”。当索引变旧时,我们创建一个新索引,为其分配别名,然后删除旧索引。

  • 我们的应用程序每秒执行大量查询。我们认为这会严重影响弹性,并降低索引性能(因为我们仅使用一个节点进行elasticsearch)。我们为该节点使用了10个分片,这导致我们向弹性触发的每个查询都转换为10个查询,每个分片一个。由于我们可以随时丢弃弹性数据(因此,改变分片数量对我们来说不是问题),因此我们只需将分片数量更改为1,就可以大大减少弹性节点中的查询数量。

  • 我们的索引中有9个映射,每个查询都将触发到一个特定的映射。在这9个映射中,大约90%插入的文档进入了其中的两个映射。我们为每个映射创建了一个单独的滚动索引,并将其他7个映射保留在同一索引中。

  • 并不是真正的修改,但是我们从Sematext安装了SPM(可扩展性能监视),这使我们可以密切监视elasticsearch并学习重要指标,例如,触发的查询数-> sematext.com/spm/index.html

我们的使用数量相对较小。我们大约有100个文档/秒到达,需要索引,峰值为400个文档/秒。至于搜索,我们每分钟大约有1500次搜索(更改分片数之前为15000)。在进行这些修改之前,我们遇到了那些性能问题,但现在还没有。


问题答案:

TTL到基于时间序列的索引

您应该考虑使用基于时间序列的索引,而不是TTL功能。假设您只关心文档的最近30分钟窗口,请使用基于日期/时间的命名约定为每30分钟创建一个新索引:docs-201309120000,docs-201309120030,docs-201309120100,docs-201309120130等(请注意命名惯例中30分钟的增量。)

使用Elasticsearch的索引别名功能(http://www.elasticsearch.org/guide/reference/api/admin-
indices-aliases/
),您可以别名docs到最近创建的索引,以便在进行批量索引时始终使用别名docs,但是docs-201309120130例如,它们将被写入。

查询时,您将过滤日期时间字段以确保仅返回最近30分钟的文档,并且您需要查询2个最近创建的索引以确保获得完整的30分钟的文档-
您可以在此处创建另一个别名以指向两个索引,或者直接查询两个索引名称。

使用此模型,您无需承担TTL使用的开销,并且仅可以删除过去一个多小时内未使用的旧索引。

还有其他方法也可以提高批量索引和查询的速度,但是我认为删除TTL将是最大的赢家-
另外,您的索引仅具有数量有限的数据要过滤/查询,这应该提供一个不错的选择提速。

Elasticsearch设置(例如内存等)

这是我通常为运行ES的服务器调整的一些设置-http:
//pastebin.com/mNUGQCLY,请注意,它仅适用于1GB
VPS,因此需要进行调整。

节点角色

查看主数据库,数据数据库和“客户端” ES节点类型也可能对您有所帮助-http:
//www.elasticsearch.org/guide/reference/modules/node/

索引设置

进行批量插入时,请考虑同时修改两者的值index.refresh_interval
index.merge.policy.merge_factor-我看到您已将修改refresh_interval5s,但请考虑-1在批量索引操作之前将其设置为,然后再返回所需的时间间隔。或者,考虑_refresh在批量操作完成后手动执行一次API命中,特别是如果您每分钟
进行批量插入-在这种情况下,这是受控环境。

使用index.merge.policy.merge_factor,将其设置为较高的值可减少ES在后台执行的段合并数量,然后在批量操作恢复正常行为后恢复为默认值。30通常建议将插入设置为,默认值为10



 类似资料:
  • 我正在尝试flink的一些网络监控工作。我的目标是计算每个的不同。 我下面的代码工作,但性能真的很糟糕。似乎每个滑动窗口都重新计算所有事件,但这不应该是必要的。 例如,我们有时间秒1-600的事件。Flink可以得到每秒的累加器,所以我们每秒有600个累加器。当第一个滑动窗口过期时,flink只合并1-300的累加器,并销毁第二个1的累加器。此窗口还可以在最后一秒前预合并1-299。当第二个滑动窗

  • 我有一个拼花地板数据表,结构如下: null null 我已经调整了以下设置,希望降低总时间: spark.memory.storagefraction 0.02 spark.sql.windowexec.buffer.in.memory.threshold 100000 spark.sql.constraintpropagation.enabled false 第二种方法帮助防止了日志中出现的一

  • 我们在应用程序中使用ehcache。请看以下配置: 既然我们已经配置为eternal="true ",那么它会永远创建缓存吗?。磁盘空间有可能用完吗? 对磁盘存储的性能会有什么影响?。肯定比内存缓存慢,但是影响有多大。 如果磁盘中存储了更多缓存,是否会导致执行多个文件操作的IO问题? 请建议生产级应用的最佳实践。假设我们有一个3 GB的堆内存和25000个并发用户访问应用程序。但是,我们的应用程序

  • 在更改配置值和SVN提交之后,我将触发refresh POST调用,URL:http://localhost:8080/Actuator/refresh[8080是客户端端口]。SVN中更新的值没有被刷新。 众所周知,config-server在本地存储SVN数据。[在我的例子中,文件夹位置-/tmp/config-repo-5393789580706388886]这里奇怪的是,一旦触发了“ref

  • 简而言之,一个人如何以给定的Firebase用户/UID的身份从Node.js访问Firebase存储?

  • 我有一个关于Kafka流的时间窗的问题,有些概念真的让我困惑。 我们有一个主题每天获得1000万个事件,我们有6天的日志保留,所以总的主题包含6000万个事件。 现在,我创建了一个KTable,我正在执行load all操作并迭代事件。正如我之前提到的,实际上我们只是当前的事件,而不是6千万事件,所以我在KTable定义中窗口化了这些数据。 现在,当我用以下语句加载所有事件时,一切都运行良好。 问