ElasticSearch CPU 使用率高的排查思路

一、判断核心现象

流式任务(Blink/Flink)持续向 ES 批量写入,重启任务 = 清空内存堆积、重置连接 / 批次,所以 CPU 短暂回落;运行一段时间后负载复现,基本锁定这几类问题:

  1. 写入压力不平稳、批次 / 并发不合理
  2. ES 分片 / 刷新 / 段合并压力大
  3. 文档结构、查询 / 聚合后台任务拖 CPU
  4. Blink 侧写入参数、反压、重试逻辑异常
  5. ES JVM / 线程池配置不合理

二、现场快速排查

1. 先看 ES 节点的热点指标

1.1 节点维度

# 查看各节点CPU、负载、线程池
GET _cat/nodes?v&h=name,cpu,load_1m,heapPercent,ramPercent

# 查看ES 写入线程池、队列、拒绝(关键!写入瓶颈第一看这个)
GET _cat/thread_pool/write?v&h=node,name,active,queue,rejected
GET _cat/thread_pool/bulk?v&h=node,name,active,queue,rejected
  1. bulk/write 队列堆积、rejected > 0:写入过载
  2. active 长期打满:线程池不够或单请求太重

1.2 索引维度(写入目标索引)

# 索引写入TPS、段合并、刷新频率
GET _cat/indices?v&h=index,docs.count,docs.deleted,store,pri,rep,segments.count

# 实时索引统计(刷新、合并、bulk耗时)
GET _stats/indexing,merges,refresh

重点观察:

  • refresh 频率极高(默认 1s):小刷新频繁触发 CPU
  • merges 持续高:小分片 / 小文件太多,后台段合并吃满 CPU
  • bulk 耗时持续走高:单批次数据过大 / 文档字段过多

1.3 查看慢日志 & 热点操作

开启 / 查看 slowlog,确认是bulk写入慢还是查询/聚合慢

# 查看当前慢日志配置
GET _settings/index.slowlog

如果大量 bulk 慢日志 → 写入侧问题;大量search/agg → 业务查询拖 CPU。

2. Blink/Flink 任务侧排查

  • 是否存在反压:Flink UI 看 Task 反压、SubTask 堆积,反压会导致批次累积、批量写入暴涨。
  • 并发度:写入并发是否远大于 ES 承载能力。
  • 批量大小bulk.flush.max.actions / bulk.flush.max.size 配置是否不合理。
  • 重试机制:ES 返回 429 / 超时后,Blink 无限重试 → 风暴式写入,CPU 持续拉高。

三、分场景解决

场景1:流式写入 + 频繁 Refresh + 段合并爆炸

【现象特征】

重启任务后短时平稳,运行几小时 CPU 逐步上涨;ES segments.count 持续变多,merges 线程繁忙。

【优化操作】

  1. 调大索引 refresh 间隔
# 流式数据实时性要求不极致的直接改:
PUT 你的索引/_settings
{
  "index.refresh_interval": "30s"   // 从1s改成10~30s,根据业务容忍度调整
}

作用:减少内存刷盘、段生成,大幅降低 CPU

2. 关闭索引自动刷新

# 纯离线 / 准时间流:
{
  "index.refresh_interval": "-1"
}

可在凌晨低峰手动 POST 索引/_refresh

3. 限制段合并并发

# 防止合并打满 CPU:
PUT _cluster/settings
{
  "persistent": {
    "indices.store.throttle.max_bytes_per_sec": "100mb",
    "indices.merge.scheduler.max_thread_count": 2
  }
}

场景2:Blink/Flink 批量写入不合理,并发高,重试风暴

【现象特征】

bulk 队列经常堆积,有 rejected 拒绝;Flink 任务无反压,但写入 TPS 波动大。

Blink 侧参数优化(Flink ES Connector)

1、控制 Bulk 批次大小

    推荐组合(通用稳妥值):

    • bulkFlushMaxActions:1000~2000
    • bulkFlushMaxSizeInBytes:5~10MB
    • bulkFlushInterval:1000~3000 ms不要单批次过大(>20MB 极易 GC / 锁竞争拉高 CPU)

    2、降低写入并发

    Blink 写入 SubTask 并发 > ES 节点数 * 2 基本过载,逐步降并发观察 CPU。

    3、优化重试和超时

    关闭无限重试,增加退避策略:

    • 重试次数:3~5 次
    • 重试延迟:500ms~2s 指数退避
    • 连接超时 / Socket 超时 适当调高,避免频繁断开重连

    4、开启本地攒批,避免单条下发

    禁止逐条写入 ES,流式必须走 Bulk。


      场景3:索引分片不合理

      【现象特征】

      分片数过多,segments 暴增,段合并永不停歇。

      1. 单分片数据量建议:单分片 20~50GB 最优
      2. 分片数原则
        • 主分片数 不要超过 ES 数据节点数
        • 写入流索引:主分片 = 数据节点数,副本 1(高峰可临时关副本降负载)
      3. 临时降负载(紧急):
      PUT 索引/_settings
      {
        "index.number_of_replicas": 0
      }
      # 低峰再改回 1。

      场景4:文档本身问题(字段多、大字段、动态映射)

      1、禁用动态映射,提前建好 Mapping

      自动创建字段会频繁更新元数据、刷新索引,持续吃 CPU。

      2、剔除无用大字段(长文本、二进制、超大数组)

      写入、解析、索引都会拉高 CPU。

      3、关闭 _source 压缩 / 调整字段类型,减少解析开销。


      场景5:ES JVM & 系统层配置

      1、JVM 堆建议:不超过 31G,生产常用 16G/24G

        堆过大 → GC 卡顿、CPU 毛刺。

        2、系统层面:

          • 打开 ES 内存锁定 bootstrap.memory_lock: true
          • 调大文件句柄、线程数(流式写入必备)

            四、临时应急方案

            如果现在 CPU 已经很高,先做这几步快速止血:

            1. 对应索引 index.refresh_interval 改为 30s
            2. 临时把索引副本设为 0
            3. Blink 写入任务:降低 1/3 并发 + 调大 bulk 间隔
            4. 手动触发一次段合并整理(低峰操作):
            POST 索引/_forcemerge?max_num_segments=1

            五、长效运维建议

            1、按天 / 按小时拆分索引(时序流式数据首选)

            滚动索引/日期索引,旧索引只读,不再产生合并 / 刷新压力。

            2、做流量削峰:Blink 侧加缓冲,平滑写入 TPS,避免突刺。

            3、监控看板重点加:

            ES CPU、bulk 队列、段数量、refresh 次数、Flink 写入并发 / 批次。

            4、定时运维:凌晨低峰执行 forcemerge + refresh 整理碎片。

            补充一:快速定位

            • 队列堆积、rejected → 写入并发 / 批次太大,降并发、调 bulk
            • segments 多、merges 忙 → 分片多、刷新太勤,改 refresh、合分片
            • 重启就好、越跑越卡 → 内存 / 批次累积 + 后台合并持续运行

            补充二:信息收集命令(先收集后分析)

            1. 集群&节点基础信息

            # 所有节点概览:CPU、负载、堆内存、物理内存
            GET _cat/nodes?v&h=name,ip,cpu,load_1m,load_5m,heapPercent,ramPercent,diskUsedPercent,node.role
            
            # 集群整体健康、分片分配状态
            GET _cat/health?v
            
            # 查看节点JVM配置、堆大小、GC情况
            GET _nodes/jvm?pretty

            2. 写入核心线程池

            # bulk 线程池(流式写入最关键)
            GET _cat/thread_pool/bulk?v&h=node,name,active,queue,queue_size,rejected,completed
            
            # write 线程池
            GET _cat/thread_pool/write?v&h=node,name,active,queue,queue_size,rejected,completed
            
            # 全部线程池(兜底查看其他阻塞)
            GET _cat/thread_pool?v

            关注字段rejected > 0 代表写入过载拒绝;queue 持续上涨代表堆积。

            3. 目标业务索引信息

            # 索引基础:分片、文档数、存储、删除文档数
            GET _cat/indices?index=你的索引名*&v&h=index,pri,rep,docs.count,docs.deleted,store,segments.count
            
            # 索引全局统计:写入、刷新、段合并耗时/次数
            GET 你的索引名*/_stats/indexing,refresh,merges,search?pretty

            4. 段合并 & 刷新详情

            # 查看正在执行的段合并任务
            GET _cat/segments?index=你的索引名*&v
            
            # 查看后台合并调度、限流配置
            GET _cluster/settings?include_defaults=true&pretty
            
            # 查看索引当前 refresh 间隔、副本数等设置
            GET 你的索引名*/_settings?pretty

            5. 慢查询 / 慢写入日志

            # 查看当前慢日志阈值配置
            GET 你的索引名*/_settings/index.slowlog?pretty
            
            # 查看最近慢日志(ES7+/8+ 内置日志检索,也可直接看服务器日志文件)
            GET _search
            {
              "query": {
                "match_all": {}
              },
              "sort": [{"@timestamp": "desc"}],
              "size": 100
            }

            若服务器有日志文件,额外收集:elasticsearch/logs/ 下的 *.logsloglog 日志

            6. 分片&分片分配情况

            # 查看每个分片分布、大小、状态
            GET _cat/shards?index=你的索引名*&v&h=index,prirep,shard,pnode,store,docs
            
            # 查看未分配分片(如有异常分片也会拉高负载)
            GET _cat/shards?v&h=index,prirep,shard,state,node

            7. 批量请求 & 队列堆积补充

            # 查看当前活跃的批量请求
            GET _cat/pending_tasks?v
            
            # 集群pending任务(元数据、分片迁移、任务排队)
            GET _cat/tasks?v&actions=*bulk*,*index*
            原创不易,转载时请标明作者及出处。
            作者:打个小肥鸡
            转自:https://www.sretalk.com/?p=176
            暂无评论

            发送评论 编辑评论

            
            				
            |´・ω・)ノ
            ヾ(≧∇≦*)ゝ
            (☆ω☆)
            (╯‵□′)╯︵┴─┴
             ̄﹃ ̄
            (/ω\)
            ∠( ᐛ 」∠)_
            (๑•̀ㅁ•́ฅ)
            →_→
            ୧(๑•̀⌄•́๑)૭
            ٩(ˊᗜˋ*)و
            (ノ°ο°)ノ
            (´இ皿இ`)
            ⌇●﹏●⌇
            (ฅ´ω`ฅ)
            (╯°A°)╯︵○○○
            φ( ̄∇ ̄o)
            ヾ(´・ ・`。)ノ"
            ( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
            (ó﹏ò。)
            Σ(っ °Д °;)っ
            ( ,,´・ω・)ノ"(´っω・`。)
            ╮(╯▽╰)╭
            o(*////▽////*)q
            >﹏<
            ( ๑´•ω•) "(ㆆᴗㆆ)
            😂
            😀
            😅
            😊
            🙂
            🙃
            😌
            😍
            😘
            😜
            😝
            😏
            😒
            🙄
            😳
            😡
            😔
            😫
            😱
            😭
            💩
            👻
            🙌
            🖕
            👍
            👫
            👬
            👭
            🌚
            🌝
            🙈
            💊
            😶
            🙏
            🍦
            🍉
            😣
            Source: github.com/k4yt3x/flowerhd
            颜文字
            Emoji
            小恐龙
            花!
            上一篇