ES 高CPU会导致:
- 吞吐量下降
- 查询响应时间增加
- 慢查询数增加
谁占用了CPU
- us:user time,表示 CPU 执行用户进程的时间。(各种逻辑运算,函数,排序,复杂相关性计算,密集数据插入等等)
- sy:system time,表示 CPU 在内核运行的时间。
- wa:waiting time,表示 CPU 在等待 IO 操作完成所花费的时间。
- hi&si:hard IRQ time,表示系统处理硬中断所花费的时间,soft IRQ time,表示系统处理软中断所花费的时间。
- id:idle time,表示系统处于空闲期,等待进程运行。
sy,hi&si 是操作系统层面的cpu消耗,不是我们重点优化对象。id是空闲cpu,不需要关注。下面重点聊一下us和wa。
如何减少CPU消耗
减少等待
提升IO处理能力
- 加磁盘提升IO并发能力
- 升级SSD
- 合理分片提升并发能力,每个分片都是一个 Lucene 索引实例。集群总分片数建议控制在5w以内,单个索引的规模控制在 1TB 以内,单个分片大小控制在30 ~ 50GB。分片的数量通常建议小于或等于ES 的数据节点数量,最大不超过总节点数的2倍。确保对于节点上已配置的每个 GB的内存,将分片数量保持在 20 以下,如果某个节点拥有 30GB 的堆内存,那其最多可有 600 个分片。 参考:我在 Elasticsearch 集群内应该设置多少个分片? | Elastic Blog
减少IO量
- 只返回需要的字段:只返回需要的字段,减少IO量。
- 缓存:尽量使用filter代替must,filter满足一定条件会走Node Query Cache。Elasticsearch-内存结构_es查看当前运行内存-CSDN博客
- 升级内存:升级内存可以提升缓存的数据量。建议设置内存:节点要存储的数据比例,搜索类比例:1:16,日志类比例:1:48-1:96。
- 减少索引量:不需要查询的字段index设置成false,减少倒排索引大小。
- 设置routing key:避免全分区查询。
- 只存需要查询的字段:_source是压缩单字段存储,只存需要的字段以减少OS缓存量。
- 减少查询量:规避prefix,wildcard等查询,匹配词比较多。
- 减少单位时间写入量:大量密集写入改成渐进的写入策略。
减少计算
- doc_values:开启doc_values提升聚合和排序性能(走_source需要解压缩)。
- store:单字段查询场景可以设置字段store:true(走_source需要解压缩)。
- 减少GC:调整内存参数,减少young gc 和 full gc次数。
- 减少耗CPU查询:script_score,function_score, regexp等等查询。
分析高CPU
查看请求量
查看查询/写请求量,分析是否cpu高和查询量升高或者写入量升高导致的。
如图所示,查询请求量的波动与集群最大CPU使用率是基本吻合的。基本可以确定是增加的查询导致,发现了问题所在,进一步确认则需要开启集群的慢日志收集,可以参考官方文档:集群日志说明。从慢日志中,我们可以得到更多信息。比如引起慢查询的索引、查询参数以及内容。
查看hot_threads
Elasticsearch使用线程池管理CPU资源,用于并发操作。高CPU使用率通常意味着一个或多个线程池运行不足。如果某个节点的CPU使用率很高,可以使用该节点的热线程API(hot_threads)来检查节点上运行的资源密集型线程。
// 获取集群中各节点的cpu信息
GET _cat/nodes?v=true&s=cpu:desc
// 查看热线程
GET _nodes/my-node,my-other-node/hot_threads
// 查看正在运行中的任务,返回结果字段running_time_in_nanos表示sql运行时长单位纳秒
GET _tasks?actions=*search&detailed
// 取消任务
POST _tasks/my-task-id/_cancel
参考:High CPU usage | Elasticsearch Guide [8.14] | Elastic