Elasticsearch提高查询性能

4

我正在尝试提高查询性能。简单的查询甚至不涉及嵌套文档,平均需要约3秒钟,有时更长。

curl "http://searchbox:9200/global/user/_search?n=0&sort=influence:asc&q=user.name:Bill%20Smith"

即使没有排序,它也只需要几秒钟。以下是集群的详细信息:

1.4TB index size.
210m documents that aren't nested (About 10kb each)
500m documents in total. (nested documents are small: 2-5 fields).
About 128 segments per node.
3 nodes, m2.4xlarge (-Xmx set to 40g, machine memory is 60g)
3 shards.
Index is on amazon EBS volumes.
Replication 0 (have tried replication 2 with only little improvement)

我没有看到CPU、内存等方面的明显峰值。有什么改进的想法吗?

2个回答

5
盖瑞所提到的堆空间问题是真实存在的,但这里可能不是堆空间造成的问题。
根据你当前的配置,你只有不到60GB的页面缓存可用,而你的索引有1.5TB。由于你的页面缓存中索引不到4.2%,所以很可能需要大量地访问磁盘才能完成搜索。
你可能需要向群集中添加更多内存,并且还需要仔细考虑碎片数量。如果只是使用默认值,则可能导致分布不均。在本例中,如果有五个碎片,那么两台机器将各拥有40%的数据,第三台机器只有20%。无论哪种情况,当进行分布式搜索时,您总是需要等待最慢的机器或磁盘。此 文章 详细介绍了如何确定正确的内存量。
对于这个具体的搜索示例,您可能可以使用过滤器。因为您正在排序,所以忽略了查询计算出的得分。使用过滤器后,第一次运行后它将被缓存,随后的搜索将变得更快。

谢谢。我已经更改了一些源代码以使用过滤器,但它们仍然不够快。奇怪的是,我们有一个类似数量文档的集群(减去嵌套文档),但是字段要少得多,查询速度要快得多(毫秒级)。 - lukewm
这是在一半的硬件上运行的,索引仍然太大而无法放入RAM中。我目前正在使用index: no store: false重新索引数据中的许多字段。您认为这样做有帮助吗? - lukewm
字段数量并不是问题,关键是用于回答大多数搜索的必要索引页面是否在页面缓存中。虽然将索引大小缩小很好,但削减实际上并没有使用的数据不会显著改善事情。 - Alex Brasetvik
删除字段并不能解决问题。但是,如果你将所有字段设置为“stored=true”,那么它们将成为索引的一部分,驻留在RAM中。所有字段都作为文档的一部分存储在磁盘上,只需确保不必要的字段不被设置为索引的一部分即可。 - Garry Welding
默认情况下,Elasticsearch 将整个原始文档存储为“_source”,没有其他字段。添加更多字段显然会使在磁盘上获取返回的命中的“结果对象”变大,但这些事物不会持久驻留在 RAM 中。 - Alex Brasetvik
显示剩余4条评论

2

好的,这里有几个要注意的地方:

  1. 减小你的堆大小。你每个平台上的Elasticsearch实例都有超过32gb的堆大小。Java在32gb以上不会压缩指针。将节点降至32gb,并在需要时启动另一个实例。
  2. 如果启动另一个实例不是一个选项,并且3个节点上的32gb不足以运行ES,则必须将堆内存增加到48gb以上!
  3. 我可能会坚持使用分片和副本的默认设置。5个分片,1个副本。然而,您可以调整分片设置来适应情况。我会在几个不同的条件下在几个索引中重新索引数据。第一个索引只有1个分片,第二个索引有2个分片,一直做到10个分片。查询每个索引,看哪个执行效果最好。如果10个分片的索引是最佳性能的,请继续增加分片数量,直到性能变差为止,那么您已经达到了分片限制。

需要考虑的一件事是,分片可能会提高搜索性能,但也会对索引时间产生巨大影响。分片越多,索引文档所需时间就越长...

您还存储了相当多的数据,也许您应该考虑自定义路由


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接