fielddata内存使用率高问题的排查与处理方法

如果您在针对_id主键或开启fielddata的text类型字段做排序、聚合查询、脚本查询等操作时,遇到搜索结果返回慢、页面加载延迟等体验问题,可以优先根据本文查看fielddata内存使用情况,如果fielddata内存使用率较高,可以参考本文定位并解决该问题。

背景信息

大量Elasticsearch(ES)集群运维案例显示,fielddata内存使用率越小越好,fielddata不需要占用明显的堆内存。但在Elasticsearch(ES)运维场景中,经常会遇到fielddata内存使用率高,严重时导致整个集群不可用的监控场景。

问题场景

fieldata缓存主要包含field dataglobal ordinals,占用fielddata的业务场景主要包含:

说明

前两个场景占用fielddata缓存较多,且影响较大,请优先关注。

  • 针对_id主键做排序、agg查询和脚本查询操作。

    解决方案:

    • Elasticsearch官方文档中指出禁止对_id进行聚合、排序和脚本操作,建议将_id数据复制到开启doc_values的字段进行对应操作。

    • Kibana Discover通过_id查询数据时,下拉提示功能会自动触发聚合。

      image..png

      建议在Kibana > StackManagement > 高级设置中关闭filterEditor:suggestValues,避免在Kibana中根据主键进行搜索时,执行大量_id字段的聚合分析。

      image..png

  • 对开启fielddata的text类型字段进行聚合、排序和脚本查询操作。

    解决方案:

    text字段默认关闭fielddata,开启后可进行聚合、排序和脚本查询操作。如果加载高基数text字段,fielddata会占用大量的堆内存,并且堆内存占用是永久的,建议将字段类型改成keyword。

  • keyword和ip等类型的字段,进行terms aggregations和composite aggregations等查询。

  • join字段的parent和child文档aggregations。

问题排查

您可以通过高级监控报警、fielddata API和热线程三种方式,查看fileddata内存使用率是否过高。

高级监控报警

说明

阿里云Elasticsearch高级监控报警服务在社区版监控的基础上扩展了更细粒度的监控,尤其对集群运维提供了非常大的帮助。

  1. 登录阿里云Elasticsearch控制台
  2. 在左侧导航栏,单击高级监控报警

  3. 高级监控报警页面,选择监控可视化 > 指标监控

  4. 默认基础指标页签中,查看fielddata内存使用指标。

    fielddata内存使用指标

fielddata API

  1. 登录目标阿里云Elasticsearch实例的Kibana控制台,根据页面提示进入Kibana主页。
    登录Kibana控制台的具体操作,请参见登录Kibana控制台
    说明 本文以阿里云Elasticsearch 7.10.0版本为例,其他版本操作可能略有差别,请以实际界面为准。
  2. 单击右上角的Dev tools
  3. Console页签中,执行以下命令,查看各个节点的fielddata内存占用情况(fielddata.memory_size)。

    GET _cat/nodes?v&h=ip,heap.percent,heap.current,heap.max,ram.current,ram.percent,fielddata.memory_size

    预期结果如下。api查看fielddata内存占用

热线程

通过线程分析当前集群正在处理哪类耗时任务,以便聚焦根因定位。

GET _nodes/hot_threads

通过以下结果可以看到,热线程正在处理fielddata.ordinals.GlobalOrdinalsBuilder,即在构建全局序数。热线程

问题分析

您可以通过fielddata API和日志两种方式,分析导致fielddata内存占用高问题的原因。

fielddata API

执行以下命令,获取占用fielddata内存占用高的字段,分析和业务的哪类查询相关。

GET _cat/fielddata?v&s=size:desc

预期结果如下。fielddata api分析问题

日志聚焦查询

通过在阿里云Elasticsearch控制台中分析实例慢日志,查看是否存在导致fielddata内存占用高问题的操作,详细信息请参见查询日志。例如以下日志中存在查询时按照_id排序的操作,导致fielddata内存占用高。日志聚焦查询

解决方案

您可以通过以下方案,临时解决fielddata内存占用高的问题:

  • 通过_cache/clear指定fielddata,清理fielddata缓存。如果不指定,将清理所有缓存。

     POST _cache/clear?fielddata=true
    重要
    • 通过API清理缓存是一种临时方案,请结合业务环境评估后操作。该操作会加长查询耗时,消耗额外的计算资源,可能会加重集群服务压力。

    • 建议您从业务具体查询角度进行优化,否则即使进行了清理操作,后续查询压力仍可能回升至较高水平。例如,_id的查询场景,建议您新建一个字段,把数据写入新字段,通过新字段做查询。

  • 强制重启集群。

    具体操作请参见重启实例或节点

    说明

    因fielddata内存占用高,导致fielddata占用大量的堆内存且集群不可访问时,建议优先选择强制重启集群,恢复集群可访问状态。