这里借助kibana进行修改相应的配置
elasticsearch集群的部署,详情请看上一篇文章:
Elasticsearch最新版快速入门看这个就可以了-CSDN博客
基础ES集群运维篇可以查看
Elasticsearch 生产应用(实用版),知晓这些,你就可以进行简单的ES集群运维了-CSDN博客
1、生产环境常用配置与上线清单
Development vs. production mode
从ES 5版本开始,支持 development 和 production 两钟运行模式
开发模式
生产模式
Bootstrap checks检测
一个集群在 production mode 时 。启动时必须通过所有bootstrap 检测,否则会启动失败
Bootstrap checks 可以分为两类:JVM & Linux checks 。
Linux checks 只针对Linux系统
JVM
从ES 6版本开始,只支持64位的JVM
配置 config/jvm.options
避免修改默认配置
将内存Xms 和Xmx 设置成一样,避免 heap resize 时引发停顿
Xmx 设置不要超过物理内存的50%(留有足够的内存用于全文检索) ;单个节点上,最大内存建议不要超过32G内存(JVM内存小于32时,会使用JVM对象指针压缩的技术,大于32时,可能会引起性能下降)
详情看 A Heap of Trouble: Managing Elasticsearch's Managed Heap | Elastic Blog
生产环境,JVM必须使用server模式
关闭JVM swapping
集群的API设定
静态设置和动态设定
静态配置文件尽量简洁:按照文档设置所有相关参数。Elasticsearch.yml配置文件中尽量只写必备参数
其他的设置项可以通过API动态进行设定,动态设定分 transient 和 persistent 两种,都会覆盖elasticsearch.yml中的设置
Transient 在集群重启后会丢失
Persistent在集群中重启后不会丢失
参照文档“setup elasticsearch > important system configuration”
Important System Configuration | Elasticsearch Guide [7.1] | Elastic
Disable swapping ,increase file descriptor ,虚拟内存 ,number 偶发thread
详细参考官方文档或者 ELK实验报告中的,优化资源限制配置
2、集群具体性能参考依据
(1)、网络
单个集群不要跨数据中心进行部署(不要使用WAN)网络延迟越小越好
节点中间的hops 越少越好
如果有多块网卡,最好将transport 和 http 绑定到不同的网卡,并设置不同的防火墙rules
按需为 coordinating node 或 ingest node 配置负载均衡
(2)、内存设定计算依据
内存大小要根据node需要存储的数据来进行估算
搜索类的比例建议:1:16
日志类的: 1:48 – 1:96 之间
总数据量1T ,设置一个副本 = 2T 总数据量
如果搜索类的项目,每个节点31*16 =496G ,加上预留空间,所以每个节点最多400G数据,至少需要5个节点
如果是日志类的项目,每个节点 31*50 = 1550GB ,2个数据节点即可
(3)存储
推荐使用SSD,使用本地存储(local disk),避免使用 SAN NFS / AWS /Azure filesystem
可以在本地指定多个 “path.data”,以支持使用多块磁盘
ES本身提供了很好的HA机制;无需使用RAID 1/5/10
可以在warm 节点上使用 spinning disk ,但是需要关闭 concurrent merges
Index.merge.scheduler.max_thread_count:1
Trim 你的SSD
(4)服务器硬件
建议使用中等配置的机器,不建议使用过于强劲的硬件配置
Medium machine over large machine
不建议在一台服务器上运行多个节点
(5)集群设置:throttles限流
为relocation 和recovery 设置限流,避免过多任务对集群产生性能影响
Recovery
Cluster.routing.allocation.node_concurrent_recoveries:2
Relocation
Cluster.routing.allocation.cluster_concurrent_rebalance:2
(6)集群设置:关闭dynamic indexes(动态索引创建的功能)
可以考虑关闭动态索引创建的功能,需要进行手动创建
PUT _cluster/settings
{
"persistent": {
"action.auto_create_index":false
}
}
或者通过模板设置白名单,仅允许的索引支持创建
测试,查看logstash消费情况,不符合条件的索引是无法直接创建的
(7)集群安全设定
为Elasticsearch 和kibana 配置安全功能
打开 authentication & authorization
实现索引和字段级的安全控制
节点间通信加密
Enable https
Audit logs
3、ES集群状态监控
(1)、ES stats 相关的 API
ES提供了多个监控相关的API
Node stats : _nodes/stats
Cluster stats: _cluster/stats
Index stats: index_name/_stats
(2)、The index & query slow log
支持将分片上,search 和 fetch 阶段的慢查询写入文件
支持为 query 和 fench 分别定义阈值
索引级的动态设置,可以按需设置,或者通过index template 统一设定
Slog log 文件通过 log4j2.properties
PUT tomcat-test-2024.10.11
{
"settings": {
"index.search.slowlog.threshold": {
"query.warn": "10s",
"query.info": "3s",
"query.debug": "2s",
"query.trace": "0s",
"fetch.warn": "1s",
"fetch.info": "600ms",
"fetch.debug": "400ms",
"fetch.trace": "0s"
}
}
}
index.search.slowlog.threshold.query.warn: 当查询时间超过10秒时,记录警告级别的日志。
index.search.slowlog.threshold.query.info: 当查询时间超过3秒时,记录信息级别的日志。
index.search.slowlog.threshold.query.debug: 当查询时间超过2秒时,记录调试级别的日志。
index.search.slowlog.threshold.query.trace: 不论查询多快都会记录跟踪级别的日志(由于设置为0秒,这实际上意味着禁用了基于时间的trace级别日志)。
index.search.slowlog.threshold.fetch.warn: 当获取阶段的时间超过1秒时,记录警告级别的日志。
index.search.slowlog.threshold.fetch.info: 当获取阶段的时间超过600毫秒时,记录信息级别的日志。
index.search.slowlog.threshold.fetch.debug: 当获取阶段的时间超过400毫秒时,记录调试级别的日志。
index.search.slowlog.threshold.fetch.trace: 不论获取多快都会记录跟踪级别的日志(同样地,设置为0秒意味着基于时间的trace级别日志被禁用)。
4、诊断集群的潜在问题
(1)、集群运维所面临的挑战
用户集群数量多,业务场景差异大
使用与配置不当,优化不够
如何让用户更加高效和正确的使用ES
如何让用户更全面的了解自己的集群的使用状况
发现问题滞后,需要防患于未然
需要“有迹可循”,做到“有则改之,无则加勉”
Elastic 有提供support diagnostics tool – GitHub - elastic/support-diagnostics: Support diagnostics utility for elasticsearch and logstash
(2)、为什么要诊断集群的潜在问题
防患于未然,避免集群崩溃
Master节点 / 数据节点宕机 – 负载过高,导致节点失联
副本丢失,导致数据可靠性受损
集群压力过大,数据写入失败
提升集群性能
数据节点负载不均衡(避免单节点瓶颈) / 优化分片,segment
规范操作方式(利用别名/避免 dynamic mapping 引发过多字段,对索引的合理性进行管理)
集群健康状态,是否有节点丢失
索引合理性
索引总数不能过大 / 副本分片尽量不要设置为0 /主分片尺寸检测 / 索引的字段总数(dynamic mapping 关闭) / 索引是否分配不均衡 /索引segment 大小诊断分析
资源使用合理性
CPU 内存和磁盘的使用状况分析 / 是否存在节点负载不平衡 / 是否需要最佳节点
业务操作合理性
集群的状态变更频率,是否在业务1高峰期有频繁操作
慢查询监控与分析
5、集群问题解决(yellow与red)
分片监控:
红:至少有一个主分片没有分配
黄:至少有一个副本没有分配
绿:主副分片全部正常分配
索引健康:最差的分片的状态
集群健康:最差的索引的状态
(1)、health 相关的 API
(2)、案例1:集群变红
分析:通过 allocation explain API发现,创建索引失败,因为无法找到标记了相应box type的节点
解决:删除索引,集群变绿,重新创建索引,并且指定正确的routing box type ,索引创建成功,集群保持绿色状态。
检测集群状态,查看是否有节点丢失,有多少分片无法分配
查看索引级别,找到不正常的索引
查看索引的分片
Explain 变红的原因
删除有问题的索引
重新查看集群状态,恢复正常
(3)、案例2:集群变黄
分析:通过 Allocation explain API 发现无法在相同的节点上创建副本
解决:将索引的副本数设置为0,或者通过增加节点解决
将索引的副本数设置为0
分片没有被分配的一些原因:
INDEX_CREATE:创建索引导致,在索引的全部分片分配完成之前,会有短暂的red,不一定代表有问题
CLUSTER_RECOVER:集群重启阶段,会有这个问题
INDEX_REOPEN:open一个之前close的索引
DANGLING_INDEX_IMPORTED:一个节点离开集群期间,有索引被删除,这个节点重新返回时,会导致dangling的问题(这个时候,对这个索引再执行一次删除的操作就行了)
(4)、常见问题与解决方法:
集群变红,需要检查是否有节点离线,如果有,通常通过重启离线的节点可以解决问题
由于配置导致的问题,需要修复相关的配置(例如错误的box_type,错误的副本数)
如果是测试的索引,可以直接删除
因为磁盘空间限制,分片规则(shard filtering)引发的,需要调整规则或者增加节点
对于节点返回集群,导致的dangling变红,可直接删除dangling索引
(5)、集群red & yellow 问题的总结
Red 和 yellow 是集群运维中常见的问题
除了集群故障,一些创建,增加副本登操作,都会导致集群短暂的red 和yellow,所以监控和报警时需要设置一定的延时
通过检查节点数,使用ES提供的相关API,找到真正的原因
可以指定move 或者reallocate分片
6、提升集群写能力
(1)、提高写入性能的方法
写性能优化的目标:增加集群的写吞吐量,越高越好
客户端:多线程,批量写
可以通过性能测试,确定最佳文档数量
多线程:需要观察是否有HTTP 429返回(有的话,就意味着ES集群无法处理当前的请求量了),实现retry以及线程数量的自动调节
服务器端:单个性能问题,往往是多个因素造成的,需要先分解问题,在单个节点上进行调整并且结合测试,尽可能压榨硬件资源,以达到最高吞吐量
使用更好的硬件,观察CPU / IO block
线程切换 / 堆栈状况
(2)、服务器端优化写入性能的手段
降低IO操作
使用ES自动生成的文档ID / 一些相关的ES配置,如refresh interval
降低CPU和存储开销
减少不必要分分词 / 避免不需要的doc_values /文档的诊断尽量保证相同的顺序,可以提高文档的压缩率
尽可能做到写入和分片的均衡负载,实现水平扩展
Shard filtering / write load balance
调整bulk 线程池和队列
ES的默认设置,已经综合考虑了数据可靠性,搜索的实时性质,写入速度,一般不要盲目修改
一切优化,都要基于高质量的数据建模
(3)、数据建模
关闭无关的功能
只需要聚合不需要搜索,index设置成false
不需要算分,norms设置成false
不要对字符串使用默认的 dynamic mapping ,字段数量过多,会对性能产生比较大的影响
Index_options控制在创建倒排索引时,那些内容会被添加到倒排索引中,优化这些设置,一定程度上可以节约CPU
关闭_source ,减少IO操作(适合指标型数据)
针对性能的取舍:
如果需要追求极致的写入速度,可以牺牲数据可靠性及搜索实时性以换取性能
牺牲可靠性:将副本分片设置为0,写入完毕再调整回去
牺牲搜索实时性:增加refresh interval 的时间
牺牲可靠性:修改translog 的配置
(4)、数据写入的过程
Refresh
将文档先保存在index buffer 中,以refresh_interval为间隔时间,定期清空buffer,生成segment,借助文件系统缓存的特性,先将segment放在文件系统缓存中,并开发查询,以提升搜索的实时性
Flush
删除旧的translog 文件
生成segment并写入磁盘 / 更新commit point 并写入磁盘,ES自动完成,可优化点不多
Refresh interval
降低refresh的频率
增加refresh_interval的数量,默认是1s,如果设置成-1,会禁止自动refresh
避免过于频繁的refresh,而生成过多的segment文件
但是会降低搜索的实时性
增大静态配置参数 indices.memory.index_buffer_size
默认是10%,会导致自动触发refresh
Translog
降低写磁盘的频率,但是会降低容灾的能力
Index.translog.durability:默认是request ,每个请求都落盘,设置成async,异步写入
Index.translog.sync_interval 设置为60s,每分钟执行一次
Index.translog.flush_threshod_size:默认512mb,可以适当调大,当translog超过该值,会触发flush
分片设定:
副本在写入时设为0,完成后再增加
合理设置主分片数,确保均匀分配在所有数据节点上
Index.routing.allocation.total_share_per_node:限定每个索引在每个节点上可分配的主分片数
5个节点的集群,索引有5个主分片,1个副本,应如何设置?
(5+5)/5 = 2
生产环境中要适当调大这个数字,避免节点下线时,分片无法正常迁移
Bulk ,线程池和队列的大小
客户端:
单个bulk请求体的数据量不要太大,官方就安逸大约5-15mb
写入端的bulk请求超时需要足够长,建议60s以上
写入端尽量将数据轮询打到不同的节点上
服务端:
索引创建属于计算密集型任务,应该使用固定大小的线程池来配置,来不及处理的放入队列,线程数应该配置成CPU核心数+1,避免过多上下文切换
队列大小可以适当增加,不要过大,否则占用的内存会成为GC的负担
一个索引设定的例子:
7、提升集群的读性能
(1)、尽量Denormalize数据
Elasticsearch != 关系型数据库
尽可能 denormalize 数据,从而获取最佳的性能
使用 nested 类型的数据,查询速度会慢几倍
使用 parent / child 关系,查询速度会慢几百倍
(2)、数据建模:
尽量将数据先行计算,然后保存到elasticsearch中尽量避免查询时的script计算
尽量使用filter context ,利用缓存机制,减少不必要的算分
结合profile,explain API 分析慢查询的问题,持续优化数据模型
严禁使用 * 开头通配符 terms 查询
避免查询时脚本:
可以在index文档时,使用ingest pipeline ,计算并写入某个字段
Keyword的值大于5,进行写入,提升查询速度
常见的查询性能问题 – 使用 query context
将左边的查询优化为右边的查询,通过filter进行一个过滤,会使用elasticsearch的cache缓存,提升读取速度
(3)、聚合文档消耗内存:
聚合查询会消耗内存,特别是针对很大的数据集进行聚合运算
如果可以控制聚合的数量,就能减少内存的开销
当需要使用不同的query scope ,可以使用filter bucket
(4)、通配符开始的正则表达
通配符开头的正则,性能非常糟糕,需避免使用
(5)、优化分片:
避免 over sharing
一个查询需要访问每一个分片,分片过多,会导致不必要的查询开销
结合应用场景,控制单个分片的尺寸
Search:20GB
Logging:40GB
Force-merge read-only 索引
使用基于时间序列的索引,将只读的索引进行force merge ,减少segment 数量
8、一些运维的相关建议
(1)、集群的生命周期管理
预上线
评估用户的需求及使用场景 / 数据建模 / 容量规划 / 选择合适的部署架构 / 性能测试
上线:
监控流量 / 定期检查潜在问题 (防患于未然,发现错误的使用方式,及时增加机器)
对索引进行优化(index lifecycle management),检测是否存在不均衡而导致有部分节点过热
定期数据备份 / 滚动升级
下架前监控流量,实现stage decommission
(2)、部署:
根据实际场景,选择合适的部署方式,选择合理的硬件配置
搜索类
日志 / 指标
部署要考虑,反亲和性(anti-affinity)
尽量将机器分散在不同的机架,例如,3台master节点必须分散在不同的机架上
善用shard filtering 进行配置
(3)、遵循的规范:
Mapping
生产环境中索引应考虑禁止 dynamic index mapping,避免过多字段导致cluster state 占用过多
禁止索引自动创建的功能,创建时必须提供mapping 或通过 index template 进行设定
设置slowlogs ,发现一些性能不好,甚至错误的使用pattern
例如:错误的将网址映射成keyword,然后利用通配符查询,应该使用text ,结合URL分词器
严禁一切 “*” 开头的通配符查询
(4)、对重要的数据进行备份
集群备份
(5)、定期更新到新版本:
ES在新版本中会持续对性能做出优化,提供更多的新功能
Circuie breaker 实现的改进
修复一些已知的bug 和安全隐患
(6)运维手动迁移分片:
从一个节点移动分片到另一个节点
使用场景:
当一个数据节点上有过多hot shards ;可以通过手动分配分片到特定的节点解决
(7)、从集群中移除一个节点:
使用场景:当你想移除一个节点,或者对一个机器进行维护,同时又不希望导致集群的颜色变黄或者变红
(8)、控制 allocation 和recovery 速率:
(9)ES节点重启
Synced flush 使用场景:需要重启一个节点
通过synced flush ,可以在索引上放置一个sync ID ,这样可以提供这些分片的recovery 的时间
POST _flush/synced
清空节点上的缓存:
使用场景:节点上出现了搞内存的占用,可以执行清楚缓存的操作,这个操作会影响集群的性能,但是会避免你的集群出现OOM的问题
POST _cache/clear
停掉非主分片的分配
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.enable": "primaries"
}
}
#内存数据强制落磁盘
POST _flush/synced
#关掉machine learning job一类的东西
POST _ml/set_upgrade_mode?enabled=true
#重启后 ,将配置改回来
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.enable": null
}
}
查看集群的分片状态
GET _cat/allocation?v
(10)、当搜索的响应时间过长
控制搜索的队列,看到有“reject”指标的增加,都可以适当增加该数值
(11)、避免OOM的发生
设置各类circuit breaker
(12)、索引非正常状态
查看分片分配情况
GET _cat/shards
看为啥红了 每个shard的主分片都看一下
GET _cluster/allocation/explain
{
"index": ".ds-ec-oms_info-2024.07.03-000010",
"shard": 0,
"primary": true
}
对节点id和节点 名称用
GET /_nodes/stats?pretty
根据节点名称看哪个节点有问题
GET /_cat/allocation?v&pretty
当索引的某一分片无法写入到对应节点上时,需要重新分配分片
POST _cluster/reroute
{
"commands": [
{
"move": {
"index": "your_index_name",
"shard": 0, // 分片编号
"from_node": "node_name_with_disk_issue", // 故障磁盘节点名称
"to_node": "target_node_name" // 目标节点名称
}
}
]
}
#node 填除了主分片所在节点外的 一个个试试,#谨慎执行!
最后都无法恢复再rollover