文章目录
- 概要
- 一、概念
- 二、节点角色
- 三、master节点脑裂
- 四、参考
概要
在工作中不可避免会用到ES,而用到ES就不得使用其集群模式了。
单节点的话不得不面临两个重大缺陷:单点故障(高可用)和海量数据存储搜索。
ES通过集群模式解决了这两个缺陷:
- 通过将一个索引数据备份到不同节点,实现高可用;
- 通过将一个索引数据拆分到多个节点(分片),实现海量数据存储与搜索。
ES的集群是去中心化的,在集群中没有固定的中心节点,所有节点都是平等的,可以互相通信和协作。我们从外部看,在逻辑上集群中所有节点是一个整体,无论与哪个节点进行通信,都等价于与ES集群通信。
那为何还有Master这种角色的节点呢?百科有如下解释:
在一个分布有众多节点的系统中,每个节点都具有高度自治的特征。节点之间彼此可以自由连接,形成新的连接单元。任何一个节点都可能成为阶段性的中心,但不具备强制性的中心控制功能。节点与节点之间的影响,会通过网络而形成非线性因果关系。这种开放式、扁平化、平等性的系统现象或结构,我们称之为去中心化。
去中心化,不是不要中心,而是由节点来自由选择中心、自由决定中心。简单地说,中心化的意思,是中心决定节点,节点必须依赖中心,节点离开了中心就无法生存。在去中心化系统中,任何节点都可以成为一个中心,任何中心都不是永久的,而是阶段性的,任何中心对节点都不具有强制性。
ES集群中的Master节点是动态选举的,任何符合条件的节点都可能成为Master节点,完全符合【任何节点都可以成为一个中心,任何中心都不是永久的】的描述。
一、概念
Cluster:
集群,一个ES集群是由多个节点(Node)组成的,每个集群都有一个cluster name 作为标识。在同一网段下的ES实例会通过cluster name 决定加入哪个集群下。
Node:
节点,一个ES实例就是一个node。
Index:
索引,即一系列doc的集合,类似于Mysql的表,MongoDB的集合。
Shard:
1:分片,ES是分布式搜索引擎,每个索引有一个或多个分片,索引的数据被分配到各个分片上;
2:分片有助于横向扩展,N个分片会被尽可能平均地(rebalance)分配在不同的节点上(例如你有2个节点,4个主分片(不考虑备份),那么每个节点会分到2个分片,后来你增加了2个节点,那么你这4个节点上都会有1个分片,这个过程叫relocation,ES感知后自动完成);
3:每个分片都是一个Lucene实例,所以一个分片只能存放 Integer.MAX_VALUE - 128 = 2,147,483,519个docs,见LUCENE-5843。所以每个分片是独立且功能完善的索引,这意味它可以被放置在集群中的任何节点上。
Replica:
1:复制,可以理解为副本分片,主要作用是高可用、提高查询性能。相应地有primary shard(主分片);
2:主分片和副本分片不会出现在同一个节点上(防止单点故障),如果只有一个节点,那么副本分片无法被分配,此时节点状态会变成Ywllow;
3:ES 7.0之前默认5个分片,一个副本分片,即5primary+5replica=10个分片。ES 7.0开始默认1个分片,此时主+副就是2个分片。
4:对于一个索引,除非reindex,否则不能调整主分片数,但可以随时调整副本分片数。
集群索引状态:
集群状态主要有三种:Green、Yellow、Red。
- Green:最健康得状态,说明所有的主分片和副本分片都可用,这种情况ES集群所有的主分片和副本分片都已分配,ES集群是 100% 可用的。
- Yellow:主分片可用,但副本分片不可用,即这种情况下集群所有的主分片已就绪,但至少一个主分片对应的副本分片不可用(挂了或没有副本分频)。此时不会有数据丢失,所以搜索结果依然是完整,不过,高可用性在某种程度上被弱化。
- Red:至少一个主分片不可用(此时对应的副本分片肯定挂完了,不然会从副本中选一个的成为主的),此时搜索结果是不完整的。
二、节点角色
Es的节点角色配置在7.9前后有一次大的改变。
7.9之前:
node.master:true
node.data: false
node.voting_only: false //仅投票
node.ingest: false
node.transform: false
...
node.ml: false
xpack.ml.enabled: true
cluster.remote.connect: false
7.9及其以后:
node.roles: [ master,voting_only,data ] //调成数组了,相比之前配置上方便多了
此时角色类型有以下几种:
名称 | 缩写 | 解释 |
---|---|---|
master | m | 候选主节点 |
voting_only | v | 仅投票节点 |
data | d | 数据节点 |
data_content | s | 内容数据节点 |
data_hot | h | 热数据节点 |
data_warm | w | 温数据节点 |
data_cold | c | 冷数据节点 |
data_frozen | f | 冷冻数据节点 |
ingest | i | 数据预处理节点 |
ml | l | 机器学习节点 |
remote_cluster_client | r | 远程节点 |
transform | t | 转换节点 |
一个节点没有配置node.roles
关键字,默认有cdfhilmrstw
几个角色。另外如果想配置成协调节点,直接配置node.roles: [ ]
即可。
由此可知一个节点可以兼任多种角色,但在实际项目中每个节点还是做好角色分配,按需分配资源更好:
常规来说有master节点、data节点、协调节点(coordinating node)、ingest节点就足够了。
- master节点:控制整个集群的元数据。维护集群元数据:只有master节点可以修改节点状态信息和元数据,比如索引的增删、Mapping 、Setting 、分词器、主副分片分配等等,另外还监控集群健康状态(如果一个节点出现故障或空间不足,主节点可以将分片移动到另一个节点),协调集群其它节点(比如加入新节点时主节点会自动将一些一些分片分给新节点)。
- data节点:负责数据存储和查询。
- coordinating节点:协调节点主要作用有请求分发和结果合并。请求分发是将接收的客户端请求转发到与查询条件相关的多个data节点的分片上(
主分片和副本分片都可能,所以说副本分片可以提高查询性能
),然后多个data节点的分片执行查询语句或者查询结果再返回给协调节点,此时协调节点就相当于一个负载均衡器。结果合并就是把各个data节点的返回结果进行整合、排序等一系列操作后再将最终结果返回给客户端。 - ingest节点:类似于logstash,通过预定义好的处理管道对数据进行处理和转换。ingest节点有20个内置处理器,例如grok,date,gsub,小写/大写,删除和重命名等。在写入数据时,经过ingest节点会拦截请求,对文档进行处理,比如将某个字段值由字符串转换为整数,解析字段中的日期等,然后再交由数据节点。
根据角色功能建议配置如下:
角色 | cpu | 内存 | 磁盘 |
---|---|---|---|
master | 低 | 低 | 低 |
data | 高 | 高 | 高 |
coordinating | 高 | 中 | 低 |
ingest | 高 | 中 | 低 |
方案如下
遵循高可用、职责单一、易于扩展、避免资源浪费等原则。
针对coordinating和ingest节点如果是单个,就不需要前面的LB了。如果由于业务压力过大,多个的话可以加一下,以实际业务需求为准。
有些博文说并不需要加LB,以coordinating节点为例,自身已经具有负载均衡能力,但个人以为其还要整合数据,这一点也是很吃资源的,所以业务量很大的时候,加一层LB不失为一个办法。
博文1
博文2
三、master节点脑裂
脑裂就是在Es集群中出现至少两个的活跃的master节点。在构建Es集群时为了高可用我们会部署多个master节点,其实都是候选主节点,原则来说某一刻只有其中一个会成为活跃的主节点,但是由于某些原因导致出现多个活跃的主节点。
出现的原因
- 网络波动
比如此时集群中有A、B、C、D、E五个master节点,此时E是活跃的。A、B、C在机房X,D、E在机房Y。如果X,Y两个机房突然网络中断了,但是其本身都是好好的。那么X机房中的三个主节点发现活跃的主节点失联了,就会重新选举,加入选出了A。对于其他机房的data节点来说就出现了两个活跃的主节点了。
- master节点负载过大,一般是节点职责不单一引起的,比如主节点即负责管理集群又要存储数据,又要协调客户端请求等等,当访问量激增时可能会导致
活跃主节点
不能及时响应候选主节点
向其发送的心跳,候选主节点
就会认为活跃主节点
挂了,从而重新选择新的活跃主节点
。
以上两个原因都是最终导致节点间心跳超时,进而引起候选主节点重新选举,从而出现脑裂现象。
所以说,如果所有候选主节点都在同一个机房(内网)下,出现脑裂大概率是master节点负载过大引起的。如果在不同机房,大概率是网络波动引起的。
不利影响
- 集群状态异常;
脑裂会导致集群分裂成多个独立部分,每个部分都有自己的主节点,有各自的运行状态,并且大概率互有冲突,这导致集群无法作为一个整体来协同工作,降低了集群的可用性和性能。
- 数据不一致;
元数据和索引数据都可能不一致,这一点是最大的影响。
1:多个主节点可能有不同的元数据,比如脑裂后,修改了某个索引的mapping,此时只有某一个活跃主节点收到了,此时查询时可能收到不一样的结果;
2:分片分配异常,比如脑裂后,新增了一个节点,多个主节点都收到了节点新增的信息,此时进行分片在平衡,就会导致分片分配出现混乱(比如同一个分片被分配到多个节点,或者某些分片无法被正确分配和访问)。
3:索引数据不一致,分片出现异常后,在有LB->多个coordinating节点的架构部署下,可能写入数据时落到A节点的分片1,读取时到B节点的分片1,数据肯定出现不一致问题。
如何避免
- 针对master节点负载过大这一原因,推荐节点职责单一做法,即master节点只承担master角色,不做其它任何角色;
- 优化网络环境,确保集群各节点间能够稳定、快速的通信,降低网络波动的概率;
- 定期备份数据,以便在发生脑裂后尽快恢复数据;
- 配置优化(相关配置在 EsV7.0前后进行了较大变更)
EsV7.0之前:
discovery.zen.ping.multicast.enabled: false
discovery.zen.ping.unicast.hosts: ["master1", "master2", "master3"]
discovery.zen.ping_timeout: 5
discovery.zen.minimum_master_nodes: 2
discoveryzen.ping.multicast.enabled: 将data节点的默认的master发现方式由multicast(多播)修改为unicast(单播),使新加入的节点快速确定master位置;
discovery.zen.ping.unicast.hosts:提供其他 Es节点的单播发现功能。配置集群中基于主机 TCP 端口的其他 Elasticsearch 服务列表;
discovery.zen.ping_timeout:节点通信等待响应的时间,默认3秒,增加这个值,会增加节点等待响应的时间,能一定程度上减少误判;
discovery.zen.minimum_master_nodes:当候选主节点的个数满足这个数字且都认为主节点挂了则会从新选举出新的活跃主节点。例如,Es集群有4个主节点,1个活跃主节点,3个候选主节点,此时3个候选节点都认为活跃主节点挂了则会重新进行选举,此时如果这个参数的值大于3则不会进行选举。我们可以适当把这个值改大,以减少出现脑裂的概率,官方给出的建议是(n/2)+1,n为有资格成为主节点的节点数。
EsV7.0及其以后:
废弃了discovery.zen.minimum_master_nodes配置,该机制由Es自身维护。
discovery.request_peers_timeout:5 #等价于之前的discovery.zen.ping_timeout
discovery.seed_hosts: #等价于之前的discovery.zen.ping.unicast.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
cluster.initial_master_nodes:候选主节点集合,第一次启动 Es 集群时, 引导集群进行第一次选举。
四、参考
1]:记一次生产环境 ES 脑裂
2]:官网V8
3]:官网initial_master_nodes配置
4]:Elasticsearch 8.X 节点角色划分深入详解
5]:ES7 选主去掉了minimum_master_nodes
6]:玩转 Elasticsearch 之企业级高可用分布式集群
8]:讲解Elasticsearch中master候选节点以及ES集群脑裂