在Elasticsearch运维场景中,经常会遇到一种监控场景:fielddata内存使用率高,严重时导致整个集群不可用(fielddata越小越好,大量的集群运维案例显示,fielddata不需要占用明显的堆内存)。本文从问题场景、问题排查与分析等方面,介绍如何快速定位并解决fielddata内存使用率高的问题。

问题场景

fieldata缓存主要包含field dataglobal ordinals,占用fielddata的业务场景主要包含:
  • 查询中针对_id进行排序。
    说明 Elasticsearch官方文档禁止对_id进行聚合、排序和脚本操作,建议将_id数据复制到开启doc_values的字段进行对应操作。
  • text类型的字段,开启fielddata进行聚合、排序和脚本查询操作。
    说明 text字段默认关闭fielddata,开启后可进行聚合、排序和脚本查询操作。尤其加载高基数text字段,fielddata会占用大量的堆内存,并且堆内存占用是永久的,建议将字段类型改成keyword。
  • keyword和ip等类型的字段,进行terms aggregations和composite aggregations等查询。
  • join字段的parent和child文档aggregations。
注意 前两个场景占用fielddata缓存较多,且影响较大,请优先关注。

问题排查

您可以通过高级监控报警、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清理缓存,业务测可能会存下抖动,请结合业务环境评估后操作。
  • 强制重启集群。
    具体操作请参见重启实例或节点
    说明 因fielddata内存占用高,导致fielddata占用大量的堆内存且集群不可访问时,建议优先选择强制重启集群,恢复集群可访问状态。