ElasticSearch CPU和内存占用高的优化记录出现GC

本文详细记录了一次ElasticSearch在数据报表汇总引擎中遇到的查询超时问题,通过逐步排查,发现CPU使用率高达300%,内存使用率达到90%。经过对线程、段(segment)、节点内存和CPU使用情况的深入分析,最终定位问题为JVM GC频繁导致,并通过调整JVM参数,如增加heap大小和更改GC策略,成功解决了性能瓶颈。

 

      公司最近使用ElasticSearch作为数据报表汇总引擎.上线三个月累计数据800万,但是今天突然大面积出现查询超时,上服务器查看服务运行情况,发现cpu使用率高达300% mem 使用率也到了90%,下面记录了整个排查问题的过程

     1.首先查看elastic cpu和mem占用情况

复制代码

//首先查看所有进程
# top
//找到对应的elasticserch运行的PID,查看占用内存比较高的线程,Ctrl+c 退出
#top -Hp 12345   
//为了下面方便调用API,将elasticsearch.yml
//   xpack.security.enabled: false
//关闭认证,重启elasticsearch

复制代码

    2.确定是由于某个线程引起的状况,查询所有segment的驻留内存的情况

//kibana 以下全部以kibanna为例
GET  _cat/segments?v&h=index,segment,size
//curl
#curl -XGET 'http://10.0.7.134:9200/ _cat/segments?v&h=index,segment,size'

    这里摘录一下,elasticsearch,

<think> 我们参考了多个引用,特别是引用[2]引用[4],它们提供了在资源受限环境下优化Elasticsearch内存配置的关键指导。 引用[2]指出:Elasticsearch内存分配主要分为两部分:Elasticsearch内存Lucene使用的内存。其中,Elasticsearch内存应设置为不超过32GB且不超过节点总内存的50%,即取min(32G, 节点内存/2)。 引用[4]则提供了一个轻量级部署方案,其中提到可以通过禁用某些非核心服务来减少资源占用,例如禁用Elasticsearch的某些功能(在特定场景下)或者调整部署模式。 因此,在资源受限环境下优化Elasticsearch内存配置的方法如下: ### 一、核心优化原则 1. **堆内存设置**(根据引用[2]) - **上限规则**:设置`-Xms``-Xmx`为相同值,避免动态调整开销。大小取`min(32GB, 机器内存/2)`。 - **避免交换**:设置`bootstrap.memory_lock: true`锁定内存[^2]。 2. **Lucene内存管理**(引用[2]) - 剩余内存(约50%)供Lucene使用,用于文件系统缓存,加速索引搜索。 3. **精简部署**(根据引用[4]) - 在非必要场景下,禁用非核心功能(如安全模块、级监控等)以减少内存占用。 ### 二、具体优化步骤 #### 1. 调整JVM堆大小 修改`jvm.options`文件(Docker环境可通过挂载卷修改): ```ini # 示例:4GB内存的机器设置堆大小为2GB -Xms2g -Xmx2g ``` #### 2. 关闭非必要功能 在`elasticsearch.yml`中禁用以下模块: ```yaml # 关闭安全模块(仅限内网环境) xpack.security.enabled: false # 关闭机器学习(若不需要) xpack.ml.enabled: false # 关闭Watcher(若不需要) xpack.watcher.enabled: false ``` #### 3. 优化线程池(资源受限环境) 减少线程池数量以降低内存开销: ```yaml # elasticsearch.yml thread_pool: index: size: 1 # 原默认值=处理器数,改为1 search: size: 1 ``` #### 4. 调整索引设置 - **减少副本数**:`PUT /my_index/_settings { "index.number_of_replicas": 0 }` - **合并段**:强制合并只读索引`POST /my_index/_forcemerge?max_num_segments=1` #### 5. 使用轻量级替代组件(引用[4]) 在资源极度受限时(如边缘计算),考虑替代方案: - 用**Redis**替代**RabbitMQ**(节省128MB内存)[^4] - 禁用Elasticsearch的BI分析功能(节省512MB+内存)[^4] ### 三、监控与验证 1. 检查堆内存使用率: ```bash GET /_cat/nodes?v&h=name,heap.percent ``` 目标:长期<75% 2. 查看文件系统缓存使用: ```bash GET /_nodes/stats/os?filter_path=**.file_system,**.memory ``` ### 四、极端优化场景 若内存<4GB,采用以下策略: 1. **混合部署模式**:将主节点、数据节点、协调节点合并部署(仅限极小集群) 2. **限制分片数量**:`cluster.routing.allocation.total_shards_per_node: 5`(默认无限制) > **注意**:以上优化可能影响性能,需根据业务场景权衡。 ### 优化效果示例 | 配置项 | 默认值 | 优化后值 | 内存节省 | |----------------------|---------------|-------------|---------| | 堆内存 | 16GB | 1GB | 15GB | | 安全模块 | 启用 | 禁用 | ~200MB | | 索引副本数 | 1 | 0 | 减少50%磁盘占用 | | 线程池大小 | 8(8核CPU) | 1 | 减少线程栈内存 | ### 公式推导(内存分配) 设节点总内存为$M$,则: - Elasticsearch内存:$H = \min(32\text{GB}, \frac{M}{2})$ - Lucene可用内存:$L = M - H \approx \frac{M}{2}$ 当$M < 4\text{GB}$时,$H$按比例缩减: $$ H = \begin{cases} 0.5\text{GB} & M \leq 2\text{GB} \\ 1\text{GB} & 2\text{GB} < M \leq 4\text{GB} \\ \min(32\text{GB}, M/2) & M > 4\text{GB} \end{cases} $$ 通过以上优化,可在资源受限环境下显著降低内存占用,同时保持基本功能可用[^2][^4]。 §§相关问题§§ 1. 如何监控Elasticsearch内存使用情况? 2. 在Kubernetes中如何动态调整Elasticsearch内存配置? 3. Elasticsearch内存溢出(OOM)的常见原因及解决方法? </think> ### 资源受限环境下优化Elasticsearch内存配置的方法 以下是针对资源受限环境(内存<8GB)的Elasticsearch内存优化方案,结合核心原则实践策略: #### 一、核心优化原则(基于引用[2][4]) 1. **堆内存黄金法则** - 设置堆内存不超过物理内存的50%:$Heap \leq \frac{1}{2} \times RAM_{total}$ - 绝对上限32GB:$Heap \leq \min(32GB, \frac{1}{2}RAM_{total})$[^2] - **示例**:4GB内存机器 → 堆内存上限2GB 2. **内存分配比例** ```mermaid pie title 内存分配模型 "Elasticsearch内存" : 50 "Lucene文件缓存" : 40 "OS保留内存" : 10 ``` #### 二、关键优化策略 1. **精简部署架构**(基于引用[4]) | 组件 | 默认资源 | 优化方案 | 节省效果 | |---|---|---|---| | 主节点 | 2GB+ | 与数据节点合并 | 减少512MB+ | | 协调节点 | 1GB+ | 禁用专用节点,由数据节点兼任 | 减少1GB | | 安全模块 | 300MB+ | 禁用xpack.security | 减少200MB+ | | 机器学习 | 500MB+ | 关闭xpack.ml | 减少400MB+ | 2. **JVM配置优化** ```yml # config/jvm.options -Xms1g # 初始堆=最大堆,避免动态调整 -Xmx1g -XX:UseG1GC # G1垃圾回收器(<4GB首选) -XX:MaxGCPauseMillis=200 ``` 3. **分片策略优化**(基于引用[1]) - 减少分片数量:`PUT /index/_settings { "index.number_of_shards": 1 }` - 关闭副本:`index.number_of_replicas: 0`(可恢复后再启用) - 合并只读索引:`POST /index/_forcemerge?max_num_segments=1` 4. **操作系统级优化** ```bash # 禁用swap sudo swapoff -a # 调整虚拟内存 sysctl -w vm.swappiness=1 # 增加文件描述符 ulimit -n 65536 ``` #### 三、极端资源场景方案(<4GB内存) 1. **混合节点部署** ```yml # elasticsearch.yml node.roles: [master, data, ingest] # 三合一节点 discovery.type: single-node # 单节点集群模式 ``` 2. **组件替代方案**(基于引用[4]) - 消息队列:用Redis替代RabbitMQ → 节省128MB[^4] - 存储引擎:SSD替代HDD → 减少内存缓存依赖 3. **内存限制公式** 设总内存为$M$ (GB),推荐配置: $$ \begin{cases} Heap = \lfloor 0.4M \rfloor & \text{if } M \leq 4 \\ Heap = \min(32, \lfloor 0.5M \rfloor) & \text{if } M > 4 \end{cases} $$ #### 四、监控与验证 1. **健康检查命令** ```bash # 内存使用率 GET /_cat/nodes?v&h=name,ram.percent,heap.percent # 分片分布 GET /_cat/allocation?v ``` 2. **关键监控阈值** | 指标 | 警告阈值 | 危险阈值 | |---|---|---| | JVM堆使用率 | >75% | >85% | | 文件缓存命中率 | <90% | <80% | | 分片未分配数 | >0 | >5 | #### 五、优化效果示例 4GB内存服务器优化前后对比: | 配置项 | 默认值 | 优化后 | 内存节省 | |---|---|---|---| | 堆内存 | 2GB | 1.6GB | 400MB | | 线程池 | 自动 | 减半 | 200MB+ | | 副本数 | 1 | 0 | 减少50%磁盘缓存 | | 安全模块 | 启用 | 禁用 | 300MB | | **总计** | - | - | **900MB+** | > 通过上述方案,可在4GB内存机器上稳定运行小型集群(3节点),查询延迟控制在200ms内[^2][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值