hadoop框架与核心组件刨析五ZOOKEEPER及选举深度刨析
hadoop框架与核心组件刨析(五)ZOOKEEPER及选举深度刨析
基本概念解释:
在介绍选举leader之前,先来介绍一下什么是zookeeper:
ZooKeeper是一个开源的分布式应用程序协调服务,来自于Google的Chubby一个开源的实现。是Hadoop和Hbase的重要组件。Zookeeper可以为分布式应用提供一致性的服务,功能包括:配置维护、名字服务、分布式系统、组服务等等。Zookeeper的目标是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。ZooKeeper包含一个简单的原语集,提供Java和C的接口。
ZOOKEEPER的角色:
角色 | 描述 | 职责 |
---|---|---|
Leader | 集群中的主节点,负责处理写请求和事务协调。 | - 处理客户端的写请求。 - 广播事务(PROPOSAL)给Follower。 - 提交事务(COMMIT)。 - 维护集群的事务顺序(zxid)。 |
Follower | 集群中的从节点,负责处理读请求和同步Leader的数据。 | - 处理客户端的读请求。 - 参与事务投票(ACK)。 - 同步Leader的数据。 - 参与Leader选举。 |
Observer | 类似于Follower,但不参与事务投票,用于扩展读性能。 | - 处理客户端的读请求。 - 同步Leader的数据。 - 不参与事务投票和Leader选举。 |
Learner | 泛指Follower和Observer,表示从Leader学习数据的节点。 | - 从Leader同步数据。 - 根据角色(Follower/Observer)决定是否参与投票。 |
Client | 客户端,与ZooKeeper集群交互,发送读/写请求。 | - 发送读请求(任意节点)。 - 发送写请求(必须由Leader处理)。 |
1. Leader
作用 :Leader是集群的核心节点,负责处理所有写请求和事务协调。
职责 :
- 接收客户端的写请求,并将其转换为事务。
- 广播事务(PROPOSAL)给所有Follower。
- 收集Follower的确认(ACK),并在达到Quorum后提交事务(COMMIT)。
- 维护全局的事务顺序(通过zxid)。
特点 :
- 集群中只有一个Leader。
- 如果Leader崩溃,会触发新的Leader选举。
2. Follower
作用 :Follower是集群中的从节点,负责处理读请求和同步Leader的数据。
职责 :
- 处理客户端的读请求。
- 参与事务投票(ACK),确认是否接受Leader广播的事务。
- 同步Leader的数据,保持与Leader的一致性。
- 参与Leader选举,投票选出新的Leader。
特点 :
- 可以处理读请求,减轻Leader的负载。
- 参与事务投票和Leader选举,是集群的重要组成部分。
3. Observer
作用 :Observer类似于Follower,但不参与事务投票,用于扩展集群的读性能。
职责 :
- 处理客户端的读请求。
- 同步Leader的数据,保持与Leader的一致性。
- 不参与事务投票和Leader选举。
特点 :
- 不参与投票,因此不会影响写性能。
- 主要用于扩展读性能,适合读多写少的场景。
4. Learner
作用 :Learner是Follower和Observer的统称,表示从Leader学习数据的节点。
职责 :
- 从Leader同步数据。
- 根据角色(Follower/Observer)决定是否参与投票。
特点 :
- Learner是一个抽象概念,用于描述Follower和Observer的共同行为。
5. Client
作用 :客户端是与ZooKeeper集群交互的应用程序。
职责 :
- 发送读请求(可以直接发送给任意节点)。
- 发送写请求(必须发送给Leader,或由Follower转发给Leader)。
特点 :
- 客户端通过ZooKeeper提供的API与集群交互。
- 客户端可以连接到任意节点(Leader/Follower/Observer)。
角色对比
特性 | Leader | Follower | Observer | Client |
---|---|---|---|---|
处理读请求 | 是 | 是 | 是 | 发送读请求 |
处理写请求 | 是 | 转发给Leader | 转发给Leader | 发送写请求 |
参与事务投票 | 是(发起投票) | 是(ACK确认) | 否 | 否 |
参与Leader选举 | 是(被选举) | 是(投票) | 否 | 否 |
数据同步 | 是(广播数据) | 是(同步数据) | 是(同步数据) | 否 |
数量 | 1(集群中只有一个Leader) | 多个 | 多个 | 多个 |
ZOOKEEPER选举过程:
1. 快速Leader选举(Fast Leader Election)
快速Leader选举是ZooKeeper默认的选举算法,基于**Zab协议(ZooKeeper Atomic Broadcast)**实现。它的核心思想是通过投票机制快速选出一个Leader,确保集群的高效性和一致性。
选举过程:
初始状态 :
- 每个ZooKeeper服务器启动时处于 LOOKING 状态,表示正在寻找Leader。
投票 :
每个服务器会投票给自己,投票信息包括:
- myid :服务器的唯一标识。
- zxid :服务器上最新的事务ID(越大表示数据越新)。
- epoch :选举轮次。
服务器将投票信息广播给集群中的其他服务器。
比较投票 :
每个服务器收到其他服务器的投票后,会比较投票信息:
- 优先比较 zxid ,zxid越大,优先级越高。
- 如果zxid相同,则比较 myid ,myid越大,优先级越高。
更新投票 :
- 如果收到的投票比自己当前的投票更优,服务器会更新自己的投票,并重新广播。
确定Leader :
- 当某个服务器收到超过半数的相同投票(即Quorum),它会确定投票中的服务器为Leader,并将自己的状态改为 FOLLOWING 。
- 被选中的服务器将自己的状态改为 LEADING ,成为Leader。
特点:
- 快速 :通过优先比较zxid和myid,快速选出Leader。
- 高效 :避免了复杂的协商过程,适合大规模集群。
2. 基于TCP的Leader选举
基于TCP的Leader选举是ZooKeeper早期版本中使用的一种选举方式,现在已经较少使用。它的核心思想是通过TCP连接和简单的投票机制选出Leader。
选举过程:
初始状态 :
每个服务器启动时处于 LOOKING 状态。
建立连接 :
每个服务器尝试与其他服务器建立TCP连接。
投票 :
每个服务器投票给自己,并将投票信息发送给其他服务器。
比较投票 :
服务器收到其他服务器的投票后,会比较投票信息(基于myid和zxid)。
确定Leader :
当某个服务器收到超过半数的相同投票时,它会确定投票中的服务器为Leader。
特点:
- 简单 :实现较为简单,适合小规模集群。
- 效率较低 :依赖TCP连接的建立和维护,选举速度较慢。
zxid和myid
myid
myid是在zookeeper在初始化集群时写在配置文件中的,是每个服务器的唯一标识,是一个整数。
如在zoo.cfg中配置:
server.1=192.168.1.1:2888:3888
server.2=192.168.1.2:2888:3888
server.3=192.168.1.3:2888:3888
对应的myid分别是1 2 3
myid用于区分集群中不同的服务器,在选举过程中,如果两个服务器的zxid相同,则会比较myid,myid更大的服务器优先级更高。
zxid
zxid是zookeeper的事务id,用于标识事务的顺序。它由Leader产生,是集群中唯一的标识事务的量。
如何产生:zxid由两部分组成:epoch和counter
epoch:表示Leader的任期。每次选举新的Leader时,epoch会递增。
counter:表示事务的序号,每次新的事务发生时,counter会递增。
在每个服务器启动时,会从本地磁盘加载最新的zxid(既最后一次提交的事务)
如果服务器是第一次启动,或者没有历史数据,则zxid为0
这里就会说,欸,比较时每个服务器发送zxid,但是这个参数又是集群共有的,那如何比较呢?
这其实是一种误解,具体解释如下:
1. zxid 的集群共有性
- zxid 是集群共有的 :在ZooKeeper集群中,所有服务器最终会达成一致,拥有相同的 zxid 。这是因为ZooKeeper通过 Zab协议(ZooKeeper Atomic Broadcast) 保证所有服务器按相同的顺序执行事务。
- zxid 的一致性 :一旦一个事务被提交(即被大多数服务器确认),所有服务器都会看到相同的 zxid 。
2. 为什么每个服务器有自己的 zxid?
尽管 zxid 是集群共有的,但在选举过程中,每个服务器会携带自己本地的 zxid ,这是因为:
- 数据同步的延迟 :在分布式系统中,不同服务器之间的数据同步可能存在延迟。某些服务器可能已经收到了最新的事务,而其他服务器还没有。
- 本地 zxid 的作用 :每个服务器的本地 zxid 表示它当前已经提交的最新事务。在选举过程中,这个值用于 比较服务器的数据新旧程度 。
3. zxid 的生成和同步
- Leader 生成 zxid :只有Leader可以生成新的 zxid 。当Leader接收到一个新的事务请求时,它会递增 zxid 的低32位(counter),并将事务广播给所有Follower。
- Follower 同步 zxid :Follower接收到Leader广播的事务后,会按照 zxid 的顺序执行事务,并更新自己的本地 zxid 。
4. 选举过程中 zxid 的作用
在选举过程中,每个服务器会携带自己本地的 zxid ,用于比较数据的新旧程度。具体过程如下:
初始状态 :
- 每个服务器启动时,会从本地磁盘加载最新的 zxid 。
- 如果服务器是第一次启动,或者没有历史数据,则
zxid
为
0
。
投票 :
- 每个服务器投票给自己,并携带自己的 myid 和 zxid 。
比较投票 :
服务器收到其他服务器的投票后,会比较 zxid :
- zxid 越大的服务器,数据越新,优先级越高。
- 如果 zxid 相同,则比较 myid , myid 越大的服务器优先级越高。
确定Leader :
- 当某个服务器收到超过半数的相同投票(即Quorum),它会确定投票中的服务器为Leader。
5. 为什么需要比较本地 zxid?
- 确保数据一致性 :通过比较 zxid ,可以确保选举出的Leader拥有最新的数据,从而避免数据丢失或不一致。
- 处理网络分区 :在网络分区的情况下,某些服务器可能无法与Leader通信,导致它们的 zxid 落后于其他服务器。通过比较 zxid ,可以确保选举出的Leader是最新的。
如此在回头看选举过程,就会明朗的多。如果文章帮到了你,请帮主播点个小关小猪哦~~