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

时间:2013-09-11 13:24:05

标签: performance indexing elasticsearch

我们使用弹性搜索几乎作为缓存,存储在时间窗口中找到的文档。我们不断插入大量不同大小的文档,然后我们使用结合日期过滤器的文本查询在ES中搜索,这样当前线程就不会获得它已经看到的文档。像这样:

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

我们使用TTL功能在弹性搜索中维护数据30分钟。今天,我们每台机器每分钟至少有3台机器在批量请求中插入新文件,并使用上述问题进行搜索。

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

我们认为问题在于同步查询,插入和TTL删除。我们不需要保持旧数据的弹性,我们只需要在给定时间以弹性索引的文档的小时间窗口。 我们应该怎样做才能改善我们的表现?

提前致谢

机器类型:

  • Amazon EC2中型实例(3.7 GB内存)

其他信息:

修改

对于给你们一些反馈的长时间延迟感到抱歉。我们公司的事情很繁忙,我选择等待更平静的时间来更详细地说明我们如何解决我们的问题。我们仍然需要做一些基准来衡量实际的改进,但重点是我们解决了这个问题:)

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

但是,我们也做了一些修改,正如这里的答案所示,我们认为这些修改也改善了性能:

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

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

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

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

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

3 个答案:

答案 0 :(得分:11)

基于时间序列的索引的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将是最大的胜利 - 加上你的索引只有有限的数据来过滤/查询,这应该是提供一个很好的速度提升。

弹性搜索设置(例如内存等)

以下是我通常针对运行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_interval修改为5s,但请考虑将其设置为{批量索引操作之前{1}},然后回到所需的时间间隔。或者,考虑在批量操作完成后执行手动-1 API命中,特别是如果您每分钟进行批量插入 - 在这种情况下,它是受控环境。

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

答案 1 :(得分:1)

提高Elasticsearch效果的其他一些方法:

  • 增加索引刷新间隔。从1秒到10秒或30秒可以在性能上产生很大的不同。
  • 如果它过于激进则节流合并。您还可以通过降低index.merge.policy.max_merge_at_onceindex.merge.policy.max_merge_at_once_explicit来减少并发合并的数量。降低index.merge.scheduler.max_thread_count也可以提供帮助

很高兴看到您正在使用SPM。它在您的编辑中的URL不是超链接 - 它位于http://sematext.com/spm。 “Indexing”图表将显示合并相关设置的更改如何影响效果。

答案 2 :(得分:0)

我会启动一个额外的ES实例,并使其与当前节点形成一个集群。然后我将分割两台机器之间的工作,使用一个用于索引,另一个用于查询。看看它如何为您服务。您可能需要针对特定​​的使用模式进一步扩展。

相关问题