我们使用elasticsearch作为主要数据存储来保存数据,我们的索引策略是基于时间的(例如,我们每6小时创建一个索引 - 可配置)。来到我们的应用程序的搜索排序查询包含时间范围;根据输入时间范围,我们计算出需要用于搜索数据的指数。
现在,如果输入时间范围很大 - 让我们说6个月,我们将搜索排序查询委托给elasticsearch,那么elasticsearch会将所有文档加载到内存中,这可能会大大增加堆大小(我们对堆大小有限制)。
解决上述问题的一种方法是通过索引获取数据索引并对应用程序中的数据进行排序;指数是开放/封闭的;例如,只有最新的4个指数一直开启,其余指数根据需要开启/关闭。我想知道是否有更好的方法可以解决手头的问题。
答案 0 :(得分:1)
UPDATE
选项1
您可以尝试限制字段数据缓存大小,而不是打开和关闭索引。
您可以将字段数据缓存限制为JVM堆大小或特定大小的百分比,例如10Gb。将字段数据加载到缓存后,除非您专门限制缓存大小,否则不会将其删除。设置限制将驱逐缓存中最旧的数据,因此避免OutOfMemoryException。
您可能无法获得出色的性能,但它可能不会比打开和关闭索引更糟糕,并且会消除很多复杂性。
考虑到Elasticsearch在执行排序时会加载索引中的所有文档,这意味着您放置的任何限制都应足以将该索引加载到内存中。
See limiting field data cache size
选项2
文件价值
这意味着在索引时将必要的元数据写入磁盘,这意味着排序所需的“fielddata”存在于磁盘而不是内存中。它不比在内存fielddata中使用慢很多,实际上可以减少垃圾收集的问题,因为较少的数据被加载到内存中。有一些限制,例如字符串字段需要not_analyzed。
您可以使用混合方法并在旧索引上启用doc值,并在当前索引上使用更快,更灵活的fielddata(如果您可以通过这种方式对索引进行分类)。这样您就不会对“活动”数据的查询进行处罚。