Elasticsearch生产环境性能调优指南

#作者:朱雷

文章目录

  • 一、背景
  • 二、优化项
    • [2.1. 磁盘优化](#2.1. 磁盘优化)
    • 2.2.配置文件优化
    • [2.3. jvm 配置](#2.3. jvm 配置)
    • [2.4. 关闭或禁用 swap](#2.4. 关闭或禁用 swap)
    • [2.5. 最大文件描述符](#2.5. 最大文件描述符)
    • [2.6. 段合并流量设置](#2.6. 段合并流量设置)
    • [2.7. thread_pool相关](#2.7. thread_pool相关)
  • 三、总结

一、背景

Elasticsearch是基于Lucene的开源分布式搜索与分析引擎,支持近实时全文检索、结构化查询及复杂数据分析,广泛应用于日志处理、企业搜索和大数据监控。其核心特性包括水平扩展、RESTful API接口和倒排索引技术,可高效处理PB级数据。作为Elastic Stack的核心组件,常与Kibana、Logstash集成,提供端到端数据解决方案。

二、优化项

2.1. 磁盘优化

2.1.1. 磁盘使用

复制代码
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.disk.watermark.low": "90%",
"cluster.routing.allocation.disk.watermark.high": "95%",
"cluster.routing.allocation.disk.watermark.flood_stage": "95%", 
"cluster.info.update.interval": "1m"
}
}

persistent
表示为永久修改,重启以后也会保存设置

cluster.routing.allocation.disk.watermark.low
cluster.routing.allocation.disk.watermark.high
这两个配置是磁盘使用率限制,当磁盘使用率大于low的限制时,如果没有别的node可以存储数据,状态就会变为red。

cluster.routing.allocation.disk.watermark.flood_stage 
这个配置值要大于等于cluster.routing.allocation.disk.watermark.high,否则设置不成功,这时候只能搜索。

cluster.info.update.interval
#时间间隔 现在是1分钟,默认是30s

也可以指定具体的大小值来限制,如下:
"cluster.routing.allocation.disk.watermark.low": "100gb",
"cluster.routing.allocation.disk.watermark.high": "50gb",
"cluster.routing.allocation.disk.watermark.flood_stage": "10gb",


transient表示临时修改,重启以后不会保存设置
PUT _cluster/settings
{
"transient": {
"cluster.routing.allocation.disk.watermark.low": "90%",
"cluster.routing.allocation.disk.watermark.high": "95%",
"cluster.routing.allocation.disk.watermark.flood_stage": "95%", 
"cluster.info.update.interval": "1m"
}
}
临时修改需要在配置文件elasticsearch.yml中添加以上配置:
cluster.routing.allocation.disk.threshold_enabled: true
cluster.routing.allocation.disk.watermark.low: 90%
cluster.routing.allocation.disk.watermark.high: 95%
cluster.routing.allocation.disk.watermark.flood_stage: 98%
cluster.info.update.interval: 1m

2.2.配置文件优化

复制代码
cat elasticsearch.yml
# 集群名
cluster.name: es_prod

# 根据每个节点用途命名
node.name: es_data_01 或 es_master_01 或 es_client_01

# 网络地址
network.host: 192.168.1.10

# 副本、分片配置、索引刷新间隔
# index.refresh_interval: 30s
# index.number_of_replicas: 0
# index.number_of_shards: 1



# 数据、日志、插件目录,path/to 自定义, 数据可以添加多个路径
path.data: /path/to/data1,/path/to/data2 

# Path to log files:
path.logs: /path/to/logs

# Path to where plugins are installed:
path.plugins: /path/to/plugins

# 磁盘配额配置
cluster.routing.allocation.disk.threshold_enabled: true
cluster.routing.allocation.disk.watermark.low: 90%
cluster.routing.allocation.disk.watermark.high: 95%
cluster.routing.allocation.disk.watermark.flood_stage: 98%
cluster.info.update.interval: 1m

# 段合并流量设置
indices.store.throttle.max_bytes_per_sec: 100mb

# 锁定内存,禁止操作系统交换到swap
bootstrap.mlockall: true

# 最小主节点数,算法:(master 候选节点个数 / 2) + 1, 这个可以使用api 动态更新,当添加和删除 master 节点的时候,你需要更改这个配置。
discovery.zen.minimum_master_nodes: 2

# 当你集群重启时,这三个设置可以在集群重启的时候避免过多的分片交换。这可能会让数据恢复从数个小时缩短为几秒钟,该配置不能动态更新且只在整个集群重启的时候有作用
gateway.recover_after_nodes: 3
gateway.expected_nodes: 3
gateway.recover_after_time: 5m

# 单播发现配置,不需要包含你的集群中的所有节点, 它只是需要足够的节点,当一个新节点联系上其中一个并且说上话就可以了,一般写上三个master就可以
discovery.zen.ping.unicast.hosts: ["host1", "host2:port"]
discovery.seed_hosts:
   - 192.168.1.10:9300
   - 192.168.1.11
   - seeds.mydomain.com
   - [0:0:0:0:0:ffff:c0a8:10c]:9301
cluster.initial_master_nodes: 
   - master-node-a
   - master-node-b
   - master-node-c

2.3. jvm 配置

在jvm 配置里配置,建议内存大小为所在机器一半的内存大小配置。

2.4. 关闭或禁用 swap

swapoff -a

可以在 sysctl 中这样配置,设置为 1 比设置为 0 要好,因为在一些内核版本 swappiness 设置为 0 会触发系统 OOM:

vm.swappiness = 1

2.5. 最大文件描述符

复制代码
GET /_nodes/process

{
   "cluster_name": "elasticsearch__zach",
   "nodes": {
      "TGn9iO2_QQKb0kavcLbnDw": {
         "name": "Zach",
         "transport_address": "inet[/192.168.1.131:9300]",
         "host": "zacharys-air",
         "ip": "192.168.1.131",
         "version": "2.0.0-SNAPSHOT",
         "build": "612f461",
         "http_address": "inet[/192.168.1.131:9200]",
         "process": {
            "refresh_interval_in_millis": 1000,
            "id": 19808,
            "max_file_descriptors": 64000, 
            "mlockall": true
         }
      }
   }
}

根据需要修改系统配置:

sysctl -w vm.max_map_count=1000000

2.6. 段合并流量设置

默认值是 20 MB/s,对机械磁盘应该是个不错的设置。如果你用的是 SSD,可以考虑提高到 100--200 MB/s。测试验证对你的系统哪个值合适。

复制代码
PUT /_cluster/settings
{
    "persistent" : {
        "indices.store.throttle.max_bytes_per_sec" : "100mb"
    }
}
关闭合并限流:
PUT /_cluster/settings
{
    "transient" : {
        "indices.store.throttle.type" : "none" 
    }
}

2.7. thread_pool相关

一般不需要调整和优化线程池,但线程池的状态,有利于你掌握集群行为。

若队列满了,超出了限制,开始拒绝新的事务,表示集群正处在资源瓶颈,表示你的集群或者节点正在以最大的速度处理事务,但赶不上新事务增加的速度。

bulk批量索引的请求线程队列是最有可能出现拒绝请求的事情,队列的拒绝是对压力的一个有效措施,表示集群正处于最大的容量,比把数据全部塞到内存队列里要好。增大队列大小不会提升性能,它只会隐藏问题。

解决队列满了的问题是清理队列。当你遇到bulk拒绝请求时候,你应该采取如下措施:

  1. 停止插入线程3-5秒
  2. 从bluk请求里提取被拒绝的操作,可能大部分请求都成功了。bulk的响应里会告诉你哪些操作成功了,哪些操作被拒绝了。
  3. 把拒绝的操作重新生成一个新的bulk请求。
  4. 如果再有拒绝请求发生,就重复上面的步骤。

有十几个线程池,大部分你可以忽视,但是有少部分需要你特别注意:

indexing 正常的索引文档的请求

bulk 批量请求,这有区别于非批量的请求

get 根据id获取文档的操作

search 索引的检索和查询请求

merging 专门管理lucene合并的线程池

三、总结

本文总结Elasticsearch在生产实践中遇到问题的解决方案及实施过程中的经验参考。通过磁盘阈值、角色分离、内存锁定、段合并限流等策略,可显著提升集群稳定性与响应速度14。需结合硬件特性(如SSD/HDD)调整参数,并通过GET /_nodes/stats监控资源瓶颈。在优化过程中,优先保证集群核心功能(如分片分配、内存锁定)的稳定性,再逐步细化调优参数。

相关推荐
maray2 小时前
对 Lambda 架构问题的深入理解
大数据·数据库·架构
夜影风2 小时前
关于数据仓库、数据湖、数据平台、数据中台和湖仓一体的概念和区别
大数据·数据仓库·spark
Blossom.1182 小时前
量子计算在金融科技中的应用前景
大数据·人工智能·安全·机器学习·计算机视觉·金融·量子计算
递归尽头是星辰3 小时前
ClickHouse核心优势分析与场景实战
大数据·数据仓库·clickhouse·实时分析·实时查询
胡尔摩斯.4 小时前
ElasticSearch操作
大数据·elasticsearch·jenkins
£菜鸟也有梦6 小时前
Spark入门秘籍
大数据·分布式·spark
Leo.yuan7 小时前
ETL 代表什么?ETL 开发主要做什么?
大数据·数据库·数据仓库·数据分析·etl
多多洛码代码7 小时前
Flink概述
大数据·flink
lilye667 小时前
精益数据分析(70/126):MVP迭代中的数据驱动决策与功能取舍
大数据·人工智能·数据分析