Elasticsearch生产环境性能调优指南
#作者:朱雷
文章目录
- 一、背景
- 二、优化项
- 2.1. 磁盘优化
- 2.2.配置文件优化
- 2.3. jvm 配置
- 2.4. 关闭或禁用 swap
- 2.5. 最大文件描述符
- 2.6. 段合并流量设置
- 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拒绝请求时候,你应该采取如下措施:
- 停止插入线程3-5秒
- 从bluk请求里提取被拒绝的操作,可能大部分请求都成功了。bulk的响应里会告诉你哪些操作成功了,哪些操作被拒绝了。
- 把拒绝的操作重新生成一个新的bulk请求。
- 如果再有拒绝请求发生,就重复上面的步骤。
有十几个线程池,大部分你可以忽视,但是有少部分需要你特别注意:
indexing 正常的索引文档的请求
bulk 批量请求,这有区别于非批量的请求
get 根据id获取文档的操作
search 索引的检索和查询请求
merging 专门管理lucene合并的线程池
三、总结
本文总结Elasticsearch在生产实践中遇到问题的解决方案及实施过程中的经验参考。通过磁盘阈值、角色分离、内存锁定、段合并限流等策略,可显著提升集群稳定性与响应速度14。需结合硬件特性(如SSD/HDD)调整参数,并通过GET /_nodes/stats监控资源瓶颈。在优化过程中,优先保证集群核心功能(如分片分配、内存锁定)的稳定性,再逐步细化调优参数。