【调优】Elasticsearch配置优化建议

89 阅读9分钟

目录

  1. 配置原则
  2. 主要配置文件
  3. JVM 内存配置
  4. 线程池配置
  5. 防止集群脑裂配置
  6. 集群数据恢复配置
  7. 集群和节点名称配置
  8. 路径管理配置
  9. 单播发现配置
  10. 操作系统优化
  11. 配置检查清单
  12. 常见问题
  13. 参考资源
  14. 总结

1,配置原则

  • Elasticsearch 已提供良好的默认配置
  • 性能相关配置不建议随意修改
  • 仅在明确需要时进行优化调整
  • 修改前请充分测试

2,主要配置文件

elasticsearch.yml

  • 位置:$ES_HOME/config/elasticsearch.yml
  • 用途:Elasticsearch 主配置文件
  • 包含:集群设置、节点设置、网络设置、路径设置等

jvm.options

  • 位置:$ES_HOME/config/jvm.options
  • 用途:JVM 相关配置
  • 包含:堆内存、GC 参数、JVM 选项等

3,JVM 内存配置

硬件要求

  • 理想配置:64GB 内存主机
  • 最低要求:8GB 内存(低于此值不适合生产环境)

内存分配原则

总内存 = JVM 堆内存 + 堆外内存(Lucene)+ 操作系统内存

分配建议

  • JVM 堆内存:主机内存的 1/2
  • 堆外内存(Lucene):默认配置,接近并小于堆内存大小
  • 操作系统:剩余内存
  • 32GB 主机:JVM 配置 16GB,剩余 16GB 给 Lucene 和系统
  • 64GB 主机:JVM 配置 32GB,剩余 32GB 给 Lucene 和系统

配置方法

方法 1:修改 jvm.options(推荐)

-Xms 和 -Xmx 建议设置为相同值,防止程序运行时改变堆内存大小,消耗系统资源

# 编辑 jvm.options
vi $ES_HOME/config/jvm.options
# 修改以下参数(建议 Xmx 和 Xms 相同)
-Xms16g
-Xmx16g

方法 2:环境变量(简单直接)

# 设置环境变量(同时覆盖 Xmx 和 Xms)
export ES_HEAP_SIZE=16g
# 或写入配置文件
echo "export ES_HEAP_SIZE=16g" >> /etc/profile
source /etc/profile

优先级:

  • 环境变量 ES_HEAP_SIZE 优先级高于 jvm.options
  • 如果设置了环境变量,会覆盖 jvm.options 中的配置

4,线程池配置

配置原则

  • Elasticsearch 默认线程池配置已优化,不建议修改
  • 如需修改,不要超过 CPU 核数的 2 倍,超过 2 倍会导致 CPU 效率降低
  • 应为:(( 核心数 x 3 )/ 2 )+ 1,过多的线程切换会消耗资源

配置示例

# 8 核 CPU,最多配置 16 个线程
thread_pool.search.size: 16
thread_pool.write.size: 16

建议

  • 保持默认配置
  • 仅在性能测试确认需要时再调整

5,防止集群脑裂配置

discovery.zen.minimum_master_nodes:最小master节点数

配置规则

计算公式:minimum_master_nodes = (master节点个数 / 2) + 1

配置建议

  • 3 个 master 节点:minimum_master_nodes = 2
  • 5 个 master 节点:minimum_master_nodes = 3
  • 单节点部署:minimum_master_nodes = 1

实际应用场景

场景 1:正常情况(3 master,minimum_master_nodes=2)

  • 网络正常:3 个节点正常通信,选举出 1 个主节点
  • Master1 断开:Master2 和 Master3 仍能选举出新主节点
  • 集群继续运行

场景 2:配置错误(3 master,minimum_master_nodes=1)

  • 网络分区:3 个节点互相隔离
  • 每个节点都认为自己是主节点
  • 导致脑裂,数据完整性异常

场景 3:单节点部署

  • 单节点必须设置为 1
  • 否则无法选举主节点,无法提供服务

动态配置(推荐)

扩容 master 节点时,使用 API 动态配置:

# 动态设置 minimum_master_nodes
curl -X PUT "http://<ES_HOST>:9200/_cluster/settings" \
  -H 'Content-Type: application/json' \
  -d '{
    "persistent": {
      "discovery.zen.minimum_master_nodes": 2
    }
  }'

注意:

  • API 配置优先级高于配置文件
  • 扩容前先修改此配置,避免集群脑裂

配置文件方式

# elasticsearch.yml
discovery.zen.minimum_master_nodes: 2

6,集群数据恢复配置

恢复控制配置

以下配置用于控制集群数据恢复行为,可显著提高恢复速度。

# 至少有 N 个节点在线才进行数据恢复(deny 概念)
gateway.recover_after_nodes: 8    # 至少 8 个节点在线
# 期望的节点数(allow 概念)
gateway.expected_nodes: 10        # 期望 10 个节点
# 等待时间(allow 概念)
gateway.recover_after_time: 5m    # 等待 5 分钟

效果:

  • 批量重启时,只有达到 8 个节点在线且(达到 10 个节点或等待 5 分钟)才开始恢复
  • 可避免不必要的分片迁移

配置说明

gateway.recover_after_nodes

  • 含义:至少需要 N 个节点在线才开始恢复
  • 作用:避免批量重启时触发大量分片迁移
  • 示例:gateway.recover_after_nodes: 8 表示至少 8 个节点在线

gateway.expected_nodes

  • 含义:期望的节点总数
  • 作用:达到此数量时就会开始恢复

gateway.recover_after_time

  • 含义:等待时间
  • 作用:达到此时间后就会开始恢复
  • 格式:5m(5 分钟)、1h(1 小时)

恢复逻辑

恢复开始条件(满足任一 allow 条件即可):

  1. 在线节点数 ≥ gateway.expected_nodes
  2. 等待时间 ≥ gateway.recover_after_time

恢复阻止条件(deny 条件):

  • 在线节点数 < gateway.recover_after_nodes

恢复速度控制

indices.recovery.max_bytes_per_sec

  • 用途:按需配置每秒恢复的数据量
  • 注意:恢复过快可能导致 CPU 使用率过高
  • 建议:设置为实际恢复速率的 80%

动态配置

curl -X PUT "http://<ES_HOST>:9200/_cluster/settings" \
  -H 'Content-Type: application/json' \
  -d '{
    "persistent": {
      "indices.recovery.max_bytes_per_sec": "200mb"
    }
  }'

注意:

  • gateway.* 配置只能在 elasticsearch.yml 中设置,无法动态更新
  • indices.recovery.max_bytes_per_sec 支持动态更新

7,集群和节点名称配置

集群名称

默认集群名:elasticsearch

  • 默认配置下,集群外的节点可能误加入,建议修改

配置方法

# elasticsearch.yml
cluster.name: my_es_cluster

节点名称

使用有意义的名称,便于日志识别

配置方法

# elasticsearch.yml
node.name: es_node_01

8,路径管理配置

路径分离原则

  • 数据、日志、插件路径分开存储
  • 数据路径使用独立的挂载盘
  • 提高安全性和读写性能

数据路径配置

#单路径配置
path.data: /data/elasticsearch/data
#多路径配置(建议)
path.data: /data1/elasticsearch/data,/data2/elasticsearch/data

多路径配置优势

  • 提高数据安全性(冗余)
  • 提高数据读写能力(并行)
  • 更好的 I/O 性能

日志和插件路径

# 日志路径
path.logs: /var/log/elasticsearch
# 插件路径
path.plugins: /opt/elasticsearch/plugins

9,单播发现配置

单播 vs 组播

组播(不推荐)

  • 问题:节点可能误加入集群
  • 风险:网络配置变化导致节点无法发现
  • 状态:已废弃,仅作为插件提供

单播(推荐)

  • 可控、稳定、适合生产环境
  • Elasticsearch 默认使用单播

配置示例

# elasticsearch.yml
#配置格式
discovery.zen.ping.unicast.hosts: ["host1", "host2", "host3"]
#使用主机名方式
discovery.zen.ping.unicast.hosts: 
  - "es-master-01.example.com"
  - "es-master-02.example.com"
  - "es-master-03.example.com"
#使用IP地址
discovery.zen.ping.unicast.hosts: 
  - "192.168.1.10"
  - "192.168.1.11"
  - "192.168.1.12"
#指定端口
discovery.zen.ping.unicast.hosts: 
  - "es-master-01:9300"
  - "es-master-02:9300"
  - "es-master-03:9300"

配置说明

  • 不需要列出所有节点
  • 只需列出几个关键节点(建议 3 个 master 节点)
  • 新节点连接上其中一个即可获取集群信息

工作原理

  1. 新节点启动
  2. 连接 unicast.hosts 中的节点(如 host1)
  3. 获取集群完整节点列表
  4. 联系主节点
  5. 加入集群

10,操作系统优化

关闭 Swap(虚拟内存)

  • Swap 是 Elasticsearch 性能的瓶颈
  • 使用 Swap 会导致严重的性能下降
  • 建议永久关闭
# 临时关闭所有 swap
sudo swapoff -a
# 1. 编辑 /etc/fstab
sudo vi /etc/fstab
# 2. 注释掉所有包含 swap 的行
# 例如:
# /dev/mapper/centos-swap swap  swap  defaults  0 0
# 3. 或者使用 sed 命令
sudo sed -i '/swap/s/^/#/' /etc/fstab
# 4. 验证
sudo swapon --show  # 应该没有输出

系统套接字和文件描述符配置

  • Lucene 使用大量文件
  • Elasticsearch 节点间使用大量 socket 连接
  • 使用 NioFs(非阻塞文件系统)和 MMapFs(内存映射文件系统) 配置步骤
# 1. 配置文件描述符限制
echo "* soft nofile 200000" | sudo tee -a /etc/security/limits.conf
echo "* hard nofile 200000" | sudo tee -a /etc/security/limits.conf
# 2. 配置进程数限制
echo "* soft nproc 65536" | sudo tee -a /etc/security/limits.conf
echo "* hard nproc 65536" | sudo tee -a /etc/security/limits.conf
# 3. 配置虚拟内存映射限制
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
# 4. 应用 sysctl 配置
sudo sysctl -p
# 5. 重新登录或重启使 limits 生效

Docker 部署配置

docker-compose 方式

services:
  elasticsearch:
    image: elasticsearch:7.17.28
    ulimits:
      nproc: 65535
      nofile:
        soft: 200000
        hard: 200000
    sysctls:
      - vm.max_map_count=262144

docker run 方式

docker run -d \
  --name elasticsearch \
  --ulimit nofile=200000:200000 \
  --ulimit nproc=65535:65535 \
  -e "discovery.type=single-node" \
  elasticsearch:7.17.28

docker build 方式

docker build \
  --ulimit nofile=200000:200000 \
  --ulimit nproc=65535:65535 \
  -t my-es-image:tag .

11,配置检查清单

  • 关闭 Swap
  • 配置文件描述符和进程数限制
  • 配置虚拟内存映射
  • 设置集群名称(非默认值)
  • 设置节点名称(便于识别)
  • 配置单播发现
  • 设置 minimum_master_nodes
  • 配置 JVM 内存(主机内存的 1/2)
  • 配置数据路径(建议多路径)
  • 配置数据恢复参数

12,常见问题

Q1: 为什么 minimum_master_nodes 必须是 (N/2)+1?

A: 防止脑裂。确保即使部分节点断开,剩余节点仍能形成多数派,避免出现多个主节点。

Q2: 单播列表需要包含所有节点吗?

A: 不需要。只需列出几个关键节点(如 3 个 master 节点),新节点连接上其中一个即可获取集群信息。

Q3: JVM 内存为什么建议设置为主机内存的 1/2?

A: 除了 JVM 堆内存,Lucene 还需要大量堆外内存(接近堆内存大小),剩余内存给操作系统使用。

Q4: 为什么必须关闭 Swap?

A: Swap 会导致严重的性能下降。Elasticsearch 设计为在内存中运行,使用 Swap 会严重影响性能。

Q5: 数据恢复配置中的 allow 和 deny 是什么意思?

A: deny 是阻止条件(必须满足),allow 是允许条件(满足任一即可)。恢复需要满足 deny 条件且满足任一 allow 条件。

13,参考资源

Elasticsearch 官方文档:www.elastic.co/guide/cn/el…

Elasticsearch 配置参考:www.elastic.co/guide/en/el…

14,总结

  1. 本文档涵盖了 Elasticsearch 的主要配置优化项:
  2. 防止脑裂:正确配置 minimum_master_nodes
  3. 数据恢复:优化恢复速度和避免不必要的迁移
  4. 内存配置:合理分配 JVM 和系统内存
  5. 路径管理:分离数据、日志、插件路径
  6. 单播发现:使用单播替代组播
  7. 系统优化:关闭 Swap,配置系统限制

遵循这些配置建议,可以提升 Elasticsearch 集群的稳定性、性能和可维护性。