ES作为一个分布式系统,需要多个节点协同,来管理集群,处理用户请求。那么很自然有个问题,ES的集群是如何组建起来的?
所谓集群,就是多台计算机一起协同工作。 既然是协同工作,那么就必须步调一致,步调一致才能得解放。需要有领导这个角色来协调资源, 这个角色在ES中命名为Master。 Master这个角色,不是ES的独有的,基本上所有的分布式系统都有这个角色的存在,比如Zookeeper, Mongo等。
Master的产生机制也很有意思: 选举。既然是选举,那么必然会出现一个问题:怎么选举? 这就是所谓的“选举算法”。 “选举算法”中最有名的就是Paxos算法,也是最难理解的算法。好在ES用的不是这么复杂的算法,ES用的是Bully算法。ES需要解决的问题是节点的选举, 而Paxos算法除了选举,还解决了一致性的问题,杀鸡焉用牛刀。
基于Bully算法,ES实现ZenDiscovery。 顺便说一句,ES的节点发现由统一的模块处理,就是DiscoveryModule。有兴趣了解ES源码,可以作为一个入口。
ZenDiscovery的流程相当简洁, 就两步:
1. 每个节点和其他的节点通信,获取其他节点的nodeId, 从中选取nodeId最小的那个作为自己的投票。 2. 每个节点接收其他节点的投票,如果有一个节点得到足够多的选票,则接受自己成为Leader的事实,开始分发节点状态到整个集群的其他节点。下面通过具体的代码来理解这一个流程。既然是理解ES集群的组建过程,那么就从ES的进程启动开始,以elasticsearch-2.4.5为例。
我们知道,ES的启动命令是bin/elasticsearch,这个命令会调用org.elasticsearch.bootstrap.Elasticsearch.java的main方法。
启动elasticsearch后, 通过使用如下的命令可以确定:
接下来,会实例化一个Node对象,代表这个ES节点。然后start这个node.
Bootstrap.init(args); // Elasticsearch.java line 45 INSTANCE.start(); // Bootstrap.java line 288 node.start(); // Bootstrap.java line 222 discoService.joinClusterAndWaitForInitialState(); // Node.java 286如果在es的配置文件进行如下的配置,那么可以debug这个过程.
// 当前启动节点的IP地址 network.host: 192.168.43.239 // 集群的IP列表 discovery.zen.ping.unicast.hosts: ["192.168.43.239", "192.168.43.239:9800","192.168.43.239:9900"]我们忽略代码间的跳转,直接到核心业务逻辑代码ZenDiscovery.innerJoinCluster(),具体的业务逻辑如下:
s1: 确定master ZenDiscovery.findMaster()
s2: 判断master是否是当前节点,如果是则等待其他的节点加入;否则连接master, 然后发起状态更新的请求到master.
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。