一、Elasticsearch中Master的作用
Elasticsearch的Master最重要的作用就是维护集群状态
集群状态中包括以下信息:
- 集群层面的设置
- 集群内有哪些节点
- 各索引的设置,映射,分析器和别名
- 索引内各分片所在的节点位置
上述的集群状态信息,由Master节点进行维护,并且同步到集群中所有节点。也就是说集群中的任何节点都存储着集群状态信息,但只有Master能够改变信息
主节点负责创建索引、删除索引、mapping的修改,跟踪哪些节点是集群的一部分,并决定哪些分片分配给相关的节点、追踪集群中节点的状态等,并将这些修改同步到其它节点
举例说明下:
如果我们设置了dynamic=true,这个时候如果发现新字段,数据节点是需要跟Master通信,通知Master修改Mapping。这个时候的index写入是阻塞的。等Master修改了集群状态之后,再同步到所有节点,才可以继续写入
通过这种场景我们发现可以对ES进行调优:
- 对于已知的mapping,可以选择禁用动态修改,这样就不会导致写入过程中,由于mapping的改变而导致性能的下降。后果就是不符合mapping规则的写入,最终结果是写入失败。禁用:”dynamic”:”strict”
- 对于每天需要大批量新建索引的场景,比如日志。我们可以选择在业务峰值很低的时间点把index预建出来,这样就会降低高峰时期新建索引对性能的影响。这对于field过多的bulk请求尤其重要
Elasticsearch中的Master并不像mysql、hadoop集群的master那样,它既不是集群数据的唯一流入点,也不是所有元数据的存放点。所以,一般情况下Elasticsearch的Master负载是很低的
二、Elasticsearch的Master选举机制
Elasticsearch并不依赖zookeeper,Elasticsearch自带有一套选举机制
什么时候触发选主?
- 集群启动
- Master 失效
选举算法:Bully算法
比较常见的一种算法,它假定所有的节点都有一个唯一id,并对根据id进行排序。然后选举出最大的id,作为Master
这种方法的弊端是容易造成一种反复选举的情况。比如最大的id负载过大,导致假死,这个时候选举出第二大的最为Master。过一会第一大的id恢复了,又选最大的作为Master,然后又假死
Elasticsearch的解决方法是通过推迟选举直到当前Master失效之后,才会进行新的Master选举。但是这种做法也有个弊端,就是会产生脑裂,同时选举多个Master出来
Elasticsearch的选主是ZenDiscovery模块负责的,主要包含Ping(节点之间通过这个RPC来发现彼此)和Unicast(单播模块包含一个主机列表以控制哪些节点需要ping通)这两部分
默认情况下,有两种方法可用于配置种子节点列表,就是需要Ping的节点列表
单播
单播发现 配置静态主机列表, 指定为主机名的主机在每轮 ping 操作期间解析为 IP 地址。可以在 elasticsearch.yml 配置文件中使用discovery.zen.ping.unicast.hosts
静态设置设置主机列表
基于文件
通过外部文件提供主机列表。Elasticsearch在更改时会重新加载此文件,以便种子节点列表可以动态更改,而无需重新启动每个节点
投票其实就是发起加入集群的请求
选主流程:
- 首先节点会ping所有节点
- 过滤候选节点
- 判断候选节点是否达到法定人数(Eligible Node /2 +1)
- 选举算法就是把 node 列表根据 nodeid排序,取第一个
- 已经选出了一个 master, 但只是临时的,准备向其投票
- 等待非主节点的连接到足够数量(投票达到法定人数),以完成选举
- 投票:投票信息包含该节点的基本信息以及该节点认为的 master 节点
- 如果一个节点收到足够多的票数,并且该节点也为自己投票,那么它将扮演领导者的角色,开始发布集群状态。如果等待超时后投票数没有超过半数,则认为选举失败,重新开始
- 在这期间, 如果是其他节点选为Master
- 停止连接数的累加
- 向Master发送请求,申请加入集群。
- 获取集群状态clusterState,如果集群状态中与选择的Master不一致,则重新开始
新Master获取最新集群状态
新选举出的Master并不一定具备最新的集群状态,它是通过gateway 模块来实现集群状态的持久化和恢复
- 枚举集群中所有具备成为Master 资格的节点列表(相当于找到候选节点列表)
- 通过listGatewayMetaState获取这些节点上存储的集群状态
- 通过版本号确定最新的集群状态并使用
三、脑裂
一个集群分裂成两个集群,出现了两个Master
- 适当调大响应时间,减少误判
通过参数discovery.zen.ping_timeout设置节点状态的响应时间,默认为3s,可以适当调大,如果master在该响应时间的范围内没有做出响应应答,判断该节点已经挂掉了。 - 角色分离
候选主节点和数据节点进行角色分离,这样可以减轻主节点的负担,防止主节点的假死状态发生,减少对主节点“已死”的误判 - 控制法定投票人数
设置参数discovery.zen.munimum_master_nodes
discovery.zen.minimum_master_nodes=N/2+1
如果达不到N/2+1,就是超过半数,就会选举失败,重新选举
假设10台机器组成的集群产生网络分区,3台一组,7台一组,产生分区前, Master位于3台中的一个,此时7台1组的节点会重新并成功选取 Master, 这种情况如何处理?
当有节点从集群离开时, Master 节点会检查一下当前集群总节点数是否具备法定节点数(过半),如果不具备,他会重新加入集群,放弃 Master 资格,因此不会产生双主
3台一组的集群不能达到法定节点数,不能选举,7台一组则可以选举成功