目录

hadoop框架与核心组件刨析五ZOOKEEPER及选举深度刨析

hadoop框架与核心组件刨析(五)ZOOKEEPER及选举深度刨析


基本概念解释:

在介绍选举leader之前,先来介绍一下什么是zookeeper:

ZooKeeper是一个开源的分布式应用程序协调服务,来自于Google的Chubby一个开源的实现。是Hadoop和Hbase的重要组件。Zookeeper可以为分布式应用提供一致性的服务,功能包括:配置维护、名字服务、分布式系统、组服务等等。Zookeeper的目标是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。ZooKeeper包含一个简单的原语集,提供Java和C的接口。

https://i-blog.csdnimg.cn/direct/9e2143f6dd0e4b5686f14a7838672e08.png

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)。

角色对比

特性LeaderFollowerObserverClient
处理读请求发送读请求
处理写请求转发给Leader转发给Leader发送写请求
参与事务投票是(发起投票)是(ACK确认)
参与Leader选举是(被选举)是(投票)
数据同步是(广播数据)是(同步数据)是(同步数据)
数量1(集群中只有一个Leader)多个多个多个

ZOOKEEPER选举过程:

1. 快速Leader选举(Fast Leader Election)

快速Leader选举是ZooKeeper默认的选举算法,基于**Zab协议(ZooKeeper Atomic Broadcast)**实现。它的核心思想是通过投票机制快速选出一个Leader,确保集群的高效性和一致性。

选举过程:
  1. 初始状态

    • 每个ZooKeeper服务器启动时处于 LOOKING 状态,表示正在寻找Leader。
  2. 投票

    • 每个服务器会投票给自己,投票信息包括:

      • myid :服务器的唯一标识。
      • zxid :服务器上最新的事务ID(越大表示数据越新)。
      • epoch :选举轮次。
    • 服务器将投票信息广播给集群中的其他服务器。

  3. 比较投票

    • 每个服务器收到其他服务器的投票后,会比较投票信息:

      • 优先比较 zxid ,zxid越大,优先级越高。
      • 如果zxid相同,则比较 myid ,myid越大,优先级越高。
  4. 更新投票

    • 如果收到的投票比自己当前的投票更优,服务器会更新自己的投票,并重新广播。
  5. 确定Leader

    • 当某个服务器收到超过半数的相同投票(即Quorum),它会确定投票中的服务器为Leader,并将自己的状态改为 FOLLOWING
    • 被选中的服务器将自己的状态改为 LEADING ,成为Leader。
特点:
  • 快速 :通过优先比较zxid和myid,快速选出Leader。
  • 高效 :避免了复杂的协商过程,适合大规模集群。

2. 基于TCP的Leader选举

基于TCP的Leader选举是ZooKeeper早期版本中使用的一种选举方式,现在已经较少使用。它的核心思想是通过TCP连接和简单的投票机制选出Leader。

选举过程:
  1. 初始状态

    每个服务器启动时处于 LOOKING 状态。

  2. 建立连接

    每个服务器尝试与其他服务器建立TCP连接。

  3. 投票

    每个服务器投票给自己,并将投票信息发送给其他服务器。

  4. 比较投票

    服务器收到其他服务器的投票后,会比较投票信息(基于myid和zxid)。

  5. 确定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 ,用于比较数据的新旧程度。具体过程如下:

  1. 初始状态

    • 每个服务器启动时,会从本地磁盘加载最新的 zxid
    • 如果服务器是第一次启动,或者没有历史数据,则 zxid0
  2. 投票

    • 每个服务器投票给自己,并携带自己的 myidzxid
  3. 比较投票

    • 服务器收到其他服务器的投票后,会比较 zxid

      • zxid 越大的服务器,数据越新,优先级越高。
      • 如果 zxid 相同,则比较 myidmyid 越大的服务器优先级越高。
  4. 确定Leader

    • 当某个服务器收到超过半数的相同投票(即Quorum),它会确定投票中的服务器为Leader。

5. 为什么需要比较本地 zxid?

  • 确保数据一致性 :通过比较 zxid ,可以确保选举出的Leader拥有最新的数据,从而避免数据丢失或不一致。
  • 处理网络分区 :在网络分区的情况下,某些服务器可能无法与Leader通信,导致它们的 zxid 落后于其他服务器。通过比较 zxid ,可以确保选举出的Leader是最新的。

如此在回头看选举过程,就会明朗的多。如果文章帮到了你,请帮主播点个小关小猪哦~~