3

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

“((字 1 与字 2)或(字 3 与字 4))与插入日期 > 1389000”

我们使用 TTL 功能将弹性搜索中的数据保持 30 分钟。今天,我们至少有 3 台机器每分钟为每台机器批量插入新文档,并连续不断地使用上述查询进行搜索。

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

我们认为问题在于同时查询、插入和 TTL 删除。我们不需要在弹性中保留旧数据,我们只需要在给定时间在弹性中索引的文档的小时间窗口。我们应该做些什么来提高我们的表现?

提前致谢

机器的种类:

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

附加信息:

编辑

很抱歉这么久才给你们一些反馈。我们公司的事情有点忙,我选择等待平静的时间来更详细地说明我们如何解决我们的问题。我们仍然需要做一些基准测试来衡量实际的改进,但关键是我们解决了这个问题:)

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

然而,我们也做了一些修改,正如这里的答案所建议的那样,我们相信这也提高了性能:

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

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

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

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

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

4

3 回答 3

12

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在批量索引操作之前,然后再回到您想要的间隔。或者,考虑在批量操作完成后只进行手动_refreshAPI 命中,特别是如果您每分钟进行批量插入 - 在这种情况下,这是一个受控环境。

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

于 2013-09-12T16:38:18.130 回答
1

其他一些提高Elasticsearch性能的方法:

  • 增加索引刷新间隔。从 1 秒到 10 或 30 秒可以对性能产生很大影响。
  • 如果过于激进,则油门合并。您还可以通过降低index.merge.policy.max_merge_at_once和来减少并发合并的数量index.merge.policy.max_merge_at_once_explicit。降低index.merge.scheduler.max_thread_count罐头也有帮助

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

于 2013-12-31T02:58:01.243 回答
0

我会启动一个额外的 ES 实例并让它与您当前的节点形成一个集群。然后我会在两台机器之间分担工作,一台用于索引,另一台用于查询。看看这对你有什么影响。您可能需要针对您的特定使用模式进行更多扩展。

于 2013-09-11T14:18:04.187 回答