Es 集群构成
Es 集群由多个节点(Node)构成,Node可以有不同的类型,通过以下配置可以产生四种不同类型的 Node:
1 | conf/elasticsearch.yml: |
四种不同类型的Node是一个node.master和node.data的true/false的两两组合。当然还有其他类型的Node,比如IngestNode(用于数据预处理等),不在本文讨论范围内。
当node.master 为 true 时,表示这个 node 是一个 master 的候选节点,可以参与选举,类似于 MasterCandidate。Es 正常工作时只能有一个 master(leader),多于 1 个时发生脑裂。
当 node.data 为 true 时,这个节点作为一个数据节点,会存储分配在该 node 上的 shard 数据,并负责这些 shard 的写入、查询等。
此外,集群内 node 都可以执行任何请求,负责将请求转发给对应的 node 进行处理。当 node.master 和 node.data 都是 false 时,这个节点可以作为一个类似 proxy 的节点,接受请求并进行转发、结果聚合等。
Es 选主
ZenDiscovery是ES自己实现的一套用于节点发现和选主等功能的模块,没有依赖Zookeeper等工具
在本节点到每个hosts中的节点建立一条边,当整个集群所有的node形成一个联通图时,所有节点都可以知道集群中有哪些节点,不会形成孤岛。
为了避免产生脑裂,ES采用了常见的分布式系统思路,保证选举出的master被多数派(quorum)的master-eligible node认可,以此来保证只有一个master。这个quorum通过以下配置进行配置:
1 | conf/elasticsearch.yml: |
这个配置对于整个集群非常重要。
脑裂
要预防脑裂问题,我们需要看的一个参数就是 discovery.zen.minimum_master_nodes。这个参数决定了在选主过程中需要有多少个节点通信。缺省配置是1.一个基本的原则是这里需要设置成 N/2+1, N是急群中节点的数量。 例如在一个三节点的集群中, minimum_master_nodes应该被设为 3/2 + 1 = 2(四舍五入)。
让我们想象下之前的情况下如果我们把 discovery.zen.minimum_master_nodes 设置成 2(2/2 + 1)。当两个节点的通信失败了,节点1会失去它的主状态,同时节点2也不会被选举为主。没有一个节点会接受索引或搜索的请求,让所有的客户端马上发现这个问题。而且没有一个分片会处于不一致的状态。
我们可以调的另一个参数是 discovery.zen.ping.timeout。它的默认值是3秒并且它用来决定一个节点在假设集群中的另一个节点响应失败的情况时等待多久。在一个慢速网络中将这个值调的大一点是个不错的主意。这个参数不止适用于高网络延迟,还能在一个节点超载响应很慢时起作用。