先给出葵花宝典心法口诀:
节点发现很重要,避免脑裂保平安;出现问题快踢掉,否则查询好不了
自动恢复要慎重,过于仓促反不好,分片移动成本高,能够避免是最好
副本开销也挺高,流量大时可去掉,等到夜里静悄悄,定时任务来生成
拆分索引很靠谱,保留天数按需要,数据采集设拆分,定时删除有脚本
多节点,是个宝,物理资源利用高,扩容缩容需规范,不能直接(节点)上下线
写入参数可以调,注意观察看疗效,段合并调整是猛药,慎重避免副作用
一、陷阱的产生
1.ES的节点类型如下图:
默认的配置有问题:
a.ES默认安装后默认的节点类型:Maser-Eligible & Data & Ingest,三合一
b.默认设置里“minimum_master_nodes: 1”,只要看见一个节点,即可成立集群,异常情况下容易发生脑
c.原则:minimum_master_nodes应设置为 (master_eligible_nodes / 2) + 1
2.Master节点存储信息多
为管理ES集群,需要有一些元数据标明集群状态、索引/分片位置、in-sync shards …,这些信息被称为集群的Meta Data。
集群的Meta data的变更都由Master节点完成,并通知到集群中的其它节点。所以Master稳定对集群很重要。
默认Master同时作为Data节点,当负载较重时,容易导致稳定性问题
3.高成本的写过程
a. 客户端向Node1 发送写请求
b.Node1 算出文档属于分片0,于是将写请求转给分片0主分片P0所在的Node3
c. Node3写成功后,继续将写请求并行转发到Node1和Node2的副本分片上,一旦副本分片报告成功(根据配置不同可选择1个报告成功,多数报告成功,或所有报告成功),
Node3向协调节点Node1报告成功
d.Node1向客户端报告成功
一些解释说明:
a. 写请求到达分片后,先写Lucene文索引,再写Translog
b.写Lucene索引时,新记录首先被写入缓存,通过定时刷新生成段文件,定时刷新的频率由“refresh_interval”参数控制,默认1s
c.ES自己控制何时将生成的段文件持久化到磁盘
d.Translog也是首先写到内存里,并在满足一定条件时flush到磁盘持久化。
flush到磁盘的时机由两个参数定义:“flush_threshold_size”: “1024mb”;"sync_interval": "60s"
关于段合并:Segments/段太多会给ES带来很大负担,严重影响搜索性能并带来大量文件句柄的消耗,所以ES会自动进行段合并以优化性能。
但是段合并过程消耗大量I/O和CPU资源,并且ES会对段合并做节流控制,这个过程甚至会引发其它问题
4.高成本的搜索
过程描述:
a. 默认搜索分为两个阶段,查询阶段与取回阶段
b. 在查询阶段,客户端将Search请求发送给Node3,Node3将作为本次查询的协调节点。Node3将查询请求转发到每个主分片或副本分片中,如图中的P1和R0,每个主分片或副本分片搜索自身包含的符合查询条件的记录。
c. 各分片返回自己符合条件,并已排好序的结果给协调节点Node3,由Node3合并各节点返回的结果并过滤出全局符合条件的结果。接下来进入取回阶段。
d. 在取回阶段,协调节点Node3已在第三步知道全局结果里各记录分别属于哪个分片,并向相应的分片发送取回请求。
e. 相应分片响应取回请求,并将结果返回给Node3
f. Node3将合并后的结果返回给客户端,搜索完成
搜索的开销:
为保证搜索性能,ES需要将大量段数据保存在内存中,带来相当大的内存开销;同时,排序、聚合等操作也会消耗大量CPU资源。纵观整个搜索过程,可以发现它需要付出高CPU、高I/O的代价。
查询膨胀问题:
在查询阶段,会带来搜索膨胀的问题。即协调节点要知道全局结果,必须汇总每个分片的查询结果。
Example:某索引有30个分片,要查询符合某个条件的第10000笔记录,其过程是什么?
查询请求发到ES集群中某个节点,该节点充当协调节点并将查询转发到30个分片上
每个分片返回自己符合结果的前10000笔记录给协调节点,协调节点对总共30w笔记录排序,并确定全局排序结果里第10000笔记录在分片N上
向该分片N发送get请求,取回该笔记录
将记录返回给客户端
二、如何被陷入
两大陷阱 -- 稳定性 & 性能
稳定性
a.稳定性陷阱 Example #1:分片丢失,集群变红
问题现象:有分片丢失,集群进入Yellow/Red状态
普遍程度:非常普遍,我估计你们所有项目均遇见过
原因 & 解决办法:几乎都是由于节点失联导致分片丢失。节点失联的原因常见是gc,较少见的原因包括“系统问题”和“网络不通”。
如是gc导致问题,常见应对手段如关闭索引和部署多节点避免gc;如是其它环境因素,通常排除相关 因素后可解决问题
有用的命令:
查看未分片的原因:curl -XGET ‘http://
查看gc的命令: jstat -gc
b.稳定性陷阱 Example #2:脑裂无法恢复
问题现象:某个节点被踢出集群,并再也无法加入进来,集群随后进入分片恢复,当该丢失节点被手动加回集群后,
普遍程度:较为普遍
解决办法:合理设置参数,避免集群脑裂
假设有3个Master Eligible节点:node.master: true
至少看见2个Master Eligible才可组建集群:discovery.zen.minimum_master_nodes:2
c.稳定性陷阱 Example #3:再平衡对性能的恶化
问题现象:发现集群长时间处于黄色状态,大量分片处于分配中或待分配状态,往往伴随着一些节点处于高负载状态的现象。
普遍程度:普遍
原因分析:
当节点由于各种原因失联一段事件后,主节点会:
1)将失联节点上的每个主分片的一个副本提升为新的主分片;
2)重新在其它节点上分配副本;
3)进行分片恢复动作;
4)如此时失联节点重新加入,主节点将对集群做平衡,将一些分片移动到失联节点上,情况进一步变差
以上恢复/再平衡过程是CPU、network-io、disk-io都很重的操作!
如何缓解:合理设置分片恢复延迟,给系统更高的容错度
“index.unassigned.node_left.delayed_timeout”: “5m“ (默认1分钟)
d.稳定性陷阱 Example #4:查询响应慢
问题现象:从ES里加载数据失败
普遍程度:较为普遍
原因分析:
ES集群有数据节点处于异常状态 (如长时间GC),该节点未能被及时踢出集群,导致集群认为该节点仍存活,转发到该节点的查询长时间不能返回,导致页面的查询超时失败。
在这种情况下,写入数据也会受到影响,如观察采集器状态和日志,很大几率会发现有数据写失败的情况。
不少项目的ES集群会优化节点的心跳检测参数设置,以降低集群变红的概率和触发自平衡带来的影响,但这种优化在节点异常时,将加重查询响应慢的问题
如何应对:
合理规划部署并优化配置,降低节点异常的概率
非不得已应避免将心跳检测参数设置的过于激进,默认参数在大多数情况下适用,需要调整的情况下也不建议超过下面的值:
“discovery.zen.ping_interval”: “10s“
“discovery.zen.ping_timeout”: “5s”
“discovery.zen.ping_retries”: 3
稳定性陷阱的日志表现
稳定性陷阱的总结:
表现:ES节点掉出集群,或一段时间没有响应
诱因
jvm gc 【常见原因】
系统问题 【少见】
网络原因 【极少见】
危害
分片丢失,集群变红/黄
脑裂
再平衡导致集群性能恶化
查询响应时间很长/超时
2.性能陷阱:短板效应很明显
a.性能陷阱 Example #1:I/O慢导致集群性能差
问题现象:集群表现不稳定,采集器大量丢日志;查看ES日志经常出现长时间gc (> 30秒);在监控页面中观察会发现多数节点CPU、load经常飙红,CPU使用率超过硬件能力的70%
普遍程度:较少见
原因分析:ES为提高性能,做了很多优化,包括通过轮询操作替代睡眠、等待通知等阻塞操作(特别是段合并的节流控制处理逻辑)。
当磁盘写速度跟不上时,段合并逻辑会不断重试合并,直到可以写入,表现为检测到磁盘I/O写入不高,但CPU,load非常高。
如何解决:
有条件采用RAID5 (非常有效,推荐)
使用高性能磁盘 (有效)
没有RAID5的情况下,部署多节点,给不同节点分片的data目录分配不同的磁盘以隔离I/O (一般)
补充:评判硬盘性能是否满足数据量要求的条件不等式 (仅用于评估IO能否满足)
(eps × 每条日志大小 × (1 + 副本数) × 2[1] × 1.5[2]) ÷ data节点数 < 磁盘写速度 × 0.4[3]
其中[1]为ES写段和写Translog的影响因子;[2]为段合并的影响因子;
3]为考虑两重影响因素的调整因子:
1)ES data节点由于段合并有大量读操作,影响写入性能;
2)ES的段落磁盘时不是顺序写文件 (均为经验参数,可根据实际情况调整)
Example: 1w eps,日志平均1.5KB/条,1份副本,2个data节点,机器配置速度为180MB的硬盘,能否满足性能要求?
答:不等式左边:10000 * 1.5K * 2 * 2 * 1.5 ÷ 2 ≈ 45MB;不等式右边:180 * 0.4 =72MB。可以满足
b.性能陷阱 Example #2:节点慢导致集群性能差
问题现象:采集器丢日志,但通过监控页面观察,ES节点大多数时间正常,消耗资源较低,但长时间观察,能看到CPU,load飙红的情况,持续一段时间后消失,过段时间再出现,… …
普遍程度:较少见
原因分析:当ES集群中存在配置较低,或速度较慢的节点时,该节点将拉慢其它正常节点的写速度,并触发段合并的节流机制,导致CPU、load飙升;
事实上,查询也会受到影响,会表现出有时查询慢的现象。
如何解决:找出存在瓶颈的节点,并予以解决。
问题排查的有效命令:
curl –XGET “http://es-ip:9200/_cat/thread_pool?v&h=ip,bulk*”
性能陷阱的总结:
表现:ES集群性能差 -- 丢数据;CPU & load持续高位;采集器报错并陷入异常
诱因
磁盘I/O速度慢 【常见原因】
gc导致节点速度慢 【常见原因】
低配节点速度慢 【较少见】
危害
丢日志
机器性能用不满、上不去
CPU & load短时间飙升,集群稳定性变差
三、如何避坑
避坑的技术:调整部署 & 优化配置
1.部署优化之增强稳定性
节点的设置建议(4个以上数据节点,> 1.5w eps):
a. 主节点必须由master-only节点承担,Master-only节点配置8G内存
b. 条件允许则部署单独的coordinate节点负责查询,coordinate节点内存16GB。Coordinate节点配置后,模块里连接ES的配置改为coordinate节点。
c. 同物理机部署多Data节点,Data节点内存最大31G
切记给每个节点分配不同的data路径以避免异常情况(如因数据未能加载而造成的分片丢失),特别是在未使用RAID的情况下,让不同的节点的data path在不同硬盘上可以隔离I/O、提升性能
d. 数据量< 1.5w eps时,物理机<4台,通常不需特殊配置,确保节点发现参数正确。原则:保证超半数master eligible节点被看见才可建立集群。
原则:保证超半数master eligible节点被看见才可建立集群。
例如3个Master Eligible节点:node.master:true
至少看见2个Master Eligible才允许组成集群: discovery.zen.minimum_master_nodes:2
在节点发现配置里配上所有的Master-Eligible节点:discovery.zen.ping.unicast.hosts: ["x.x.x.x", "x.x.x.y", "x.x.x.z"]
2.部署优化之增加data节点
Data节点的配置为:
conf/elasticsearch.yml:
node.master: false
node.data: true
设置好节点发现,将Master-Eligible节点放入配置
conf/elasticsearch.yml:
cluster.name: hansihgt-enterprise
node.name: node_N
discovery.zen.ping.unicast.hosts: ["x.x.x.x", "x.x.x.y", "x.x.x.z"]
等待集群自动平衡
3.部署优化之减少data节点
将分片迁移到其它节点:
PUT _cluster/settings{ "transient" : { "cluster.routing.allocation.exclude._ip" : “x.x.x.x" }}
待数据迁移完成,将节点下线
4.部署优化之增加&减少Master节点
增加Master节点:
首先将‘minimum_master_nodes’参考变更到当前的“quorum/过半数“值,如,之前为3个Master-Eligible,现在要增加到4个,则quorum要由2提升到3:
curl -XPUT localhost:9200/_cluster/settings -d '{ "persistent" : { "discovery.zen.minimum_master_nodes" : 3 }}'
再部署新的Master节点,并在配置文件里设置正确的发现参数
5.部署优化充分利用硬件资源
一般采用单台物理机上部署多节点的方式以充分利用内存,以及分散磁盘I/O
数据节点的内存磁盘比
给所有ES数据节点启动参数配置的内存之和记为M(注意不是机器的物理内存),每天的索引所占存储记为S,索引打开天数记为N,它们之间的关系应满足:
M * δ > S * N
δ为经验参数,取值在96 ~ 128之间 (根据现场经验,该值可以适当激进一些)
Example:某集群7个数据节点,每个节点配置31GB内存,每天数据量约2.5TB(含副本), δ取100,则最大可打开的索引天数为:
N < 31 * 7 * 100 ÷ (2.5 * 1024) ≈ 8天
6.部署优化之合理选择硬件
磁盘使用:I/O性能对ES性能有很大影响,建议
有条件应尽量上RAID5
不能上RAID5尽可能选择高性能硬盘
网卡选择:数据量大时应使用万兆网卡,
网络存储:最好都不用!
迫不得已,唯一的选择:SAN
由于写入延迟大,不要用NAS
关于虚拟机:最好不用虚拟机 ,迫不得已,应尽量保证硬件资源不被其它虚拟机竞争
7.优化配置之使用方法优化
流量高峰时不写副本,设置定时任务生成
拆分索引,便于不同业务数据源的数据保存不同的时间周期。
8.优化配置之ES参数优化
a. 提升稳定性:
正确设置节点发现参数,避免脑裂
延迟迁移分片:“index.unassigned.node_left.delayed_timeout”: “5m“
b.优化写性能 :
降低段刷新频率:"index.refresh_interval": "60s“
c.降低IO阻塞:
"index.merge.scheduler.max_thread_count": "1“
action.wait_for_active_shards: 1 (ES 5.x以后)
action.write_consistency: one (ES 2.x)
d.段合并参数配置,减少段合并(慎重,有副作用!)
"index.merge.scheduler.max_merge_count": 16
"index.merge.policy.floor_segment": "128mb"
"index.merge.policy.segments_per_tier": 128
"index.merge.policy.max_merge_at_once”: 32
哈哈:方法千万条,稳定第一条,规划不完善,上线满头汗!