【问题标题】:Efficient way to search and sort data with elasticsearch as a datastore使用 elasticsearch 作为数据存储来搜索和排序数据的有效方法
【发布时间】:2015-12-15 16:31:40
【问题描述】:

我们使用弹性搜索作为主要数据存储来保存数据,我们的索引策略是基于时间的(例如,我们每 6 小时创建一个索引 - 可配置)。进入我们应用程序的搜索排序查询包含时间范围;并根据输入时间范围计算需要用于搜索数据的索引。

现在,如果输入时间范围很大 - 比如说 6 个月,并且我们将搜索排序查询委托给 elasticsearch,那么 elasticsearch 会将所有文档加载到内存中,这可能会大大增加堆大小(我们有一个限制堆大小)。

处理上述问题的一种方法是在我们的应用程序中按索引获取数据索引并对数据进行排序;索引相应地打开/关闭;例如,始终只打开最近的 4 个索引,其余索引根据需要打开/关闭。我想知道是否有更好的方法来处理手头的问题。

【问题讨论】:

  • 您要存储的数据量是多少(磁盘空间和文档数量)?每 6 小时创建一次索引可能是多余的。我们每 24 小时创建一个索引,有些索引的大小达到约 120 GB,包含 1 亿个文档。您的保留期限是多少?看来至少要6个月。此外,仅仅为了获取一些数据而打开和关闭索引应该很少见,关闭索引就像归档它。重新打开已关闭索引的开销很大。我们有 2 年的服务器统计数据,并且从未关闭这些索引。
  • 我们的数据大小与您的几乎相同,并且保留期限是可配置的。我们只在需要时才需要打开/关闭旧索引(超过 1 天),否则,elasticsearch 会将所有文档加载到内存中;尤其是在对数据进行排序时。
  • 顺便说一句。您可能需要考虑 Elasticsearch 是否足够可靠,可以作为您的主要数据存储。如果您有时不介意丢失数据,那就不用担心。这篇博文详细解释了它的故障模式aphyr.com/posts/323-call-me-maybe-elasticsearch-1-5-0 和 Elasticsearch 维护一个页面,介绍他们正在解决这些问题的工作elastic.co/guide/en/elasticsearch/resiliency/current/index.html
  • 您可能需要排序多少个结果?
  • 举个例子:时间范围为6个月,需要搜索的索引总数为720,单个索引的文档数为100,000。

标签: elasticsearch


【解决方案1】:

更新
选项 1
您可以尝试限制字段数据缓存大小,而不是打开和关闭索引。

您可以将字段数据缓存限制为 JVM 堆大小的百分比或特定大小,例如 10Gb。一旦将字段数据加载到缓存中,除非您特别限制缓存大小,否则不会将其删除。设置限制将驱逐缓存中最旧的数据,从而避免 OutOfMemoryException。

您可能无法获得出色的性能,但它可能不会比打开和关闭索引差,并且会消除很多复杂性。

考虑到 Elasticsearch 在执行排序时会加载索引中的所有文档,这意味着您设置的任何限制都应该足够大以将该索引加载到内存中。

See limiting field data cache size

选项 2
文档值
这意味着在索引时将必要的元数据写入磁盘,这意味着排序所需的“字段数据”存在于磁盘上而不是内存中。它并不比在内存中使用 fielddata 慢很多,实际上可以缓解垃圾收集的问题,因为更少的数据加载到内存中。存在一些限制,例如需要对字符串字段进行 not_analyzed。

您可以使用混合方法并在旧索引上启用文档值,并在当前索引上使用更快、更灵活的字段数据(如果您可以以这种方式对索引进行分类)。这样您就不会惩罚对“活动”数据的查询。

See Doc Values documentation

【讨论】:

  • 感谢您的回答。你的假设是正确的;我们确实在相对较短的时间内摄取了大量数据。但是你的回答并没有真正回答我原来的问题——需要进行排序时的内存消耗问题。
  • 很公平。我会在这个问题上发布更多的 cmets,以便我们获得更多信息,我会改进我的回答。
  • 我已经完全更新了与排序相关的答案
  • 非常感谢。我会尝试你提到的两个选项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-06
  • 2017-04-18
  • 2016-07-15
  • 1970-01-01
  • 2015-05-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多