Zookeeper总结分享

1. Zookeeper基本概念

1.1. Zookeeper简介

ZooKeeper 是一个开源的分布式协调服务。它是一个为分布式应用提供一致性服务的软件,分布式应用程序可以基于 Zookeeper 实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。

ZooKeeper 的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。

 

Zookeeper总结分享_第1张图片

Zookeeper Service集群是一主多从结构。

1.1.1. ZNode

Zookeeper总结分享_第2张图片

 

存储数据时,zookeeper 使用树形结构,其中的每个节点称作 ZNode,访问一个 ZNode 时,需要提供从 root 开始的绝对路径。

  1. PERSISTENT-持久节点:除非手动删除,否则节点一直存在于 Zookeeper 上
  2. EPHEMERAL-临时节点:临时节点的生命周期与客户端会话绑定,一旦客户端会话失效(客户端与zookeeper 连接断开不一定会话失效),那么这个客户端创建的所有临时节点都会被移除。
  3. PERSISTENT_SEQUENTIAL-持久顺序节点:基本特性同持久节点,只是增加了顺序属性,节点名后边会追加一个由父节点维护的自增整型数字。
  4. EPHEMERAL_SEQUENTIAL-临时顺序节点:基本特性同临时节点,增加了顺序属性,节点名后边会追加一个由父节点维护的自增整型数字。

每个 ZNode 可以存储最多 1MB 的数据,用户可以:

  • 创建 ZNode
  • 删除 ZNode
  • 存储数据到指定 ZNode
  • 从 ZNode 中读取数据

1.1.2. zookeeper watches

用户可以对一个 ZNode 设置 watch,当这个 ZNode 发生了变化时,例如 创建、删除、数据变更、添加或移除子节点,watch API 就会发出通知,这是 zookeeper 非常重要的功能。

zookeeper 的 watch 有一个缺点,就是这个 watch 只能被触发一次,一旦发出了通知,如果还想对这个节点继续 watch,用户需要重新设置 watch。

1.1.3. 服务启动流程

初始化数据 -> leader选举 -> 发现阶段-> 数据同步

  • 初始化数据:ZK 服务器启动时,首先会进行数据初始化,将磁盘中数据,加载到内存中,恢复现场。采用SnapShot+事务日志。如果没有快照会怎么样?
  • leader选举:fastLeader选举,可以看FastLeaderElection.lookForLeader()方法
  • 发现阶段:在这个阶段,Followers 和上一轮选举出的准 Leader 进行通信,同步 Followers 最近接收的事务 Proposal 。这个阶段的主要目的是发现当前大多数节点接收的最新 Proposal,并且准 Leader 生成新的 epoch ,让 Followers 接收,更新它们的 acceptedEpoch。
  • 数据同步:leader将自己当前的数据同步给所有learner(follower和observer的统称),当过半learner完成同步后集群就可对外提供服务。

 

2. ZAB协议

ZAB协议所定义的三种节点状态:

  • Looking :选举状态(每个节点刚加入集群时的初始状态)。
  • Following :Follower节点(从节点)所处的状态。
  • Leading :Leader节点(主节点)所处状态。

2.1. 崩溃恢复模式(选举机制)

ZooKeeper对Zab协议的实现有自己的主备模型,即Leader和learner(Observer + Follower),有如下几种情况需要进行领导者的选举工作

  • 情形1: 集群在启动的过程中,需要选举Leader
  • 情形2: 集群正常启动后,leader因故障挂掉了,需要选举Leader
  • 情形3: 集群中的Follower数量不足以通过半数检验,Leader会挂掉自己,选举新leader

有几个概念我们需要知道:

epoch:投票纪元,每个节点都会保存自己的epoch,每进行一次选举,这个值便会加一。

zxid:事务id,它是一个 64 位的 数字,它高32位是epoch,低32位用于递增计数。

myid:搭建集群时,需要为每个zk服务器配置全局唯一的myid。

vote:虚拟概念,可以想成节点投出去的票,格式为(myid,zxid),这个myid指的是任意节点的myid。

选举规则:首先比较zxid,优先选择zxid大的,若zxid相同则比较myid,选择myid大的。当集群中有超过半数的票都投给了同一个节点,那么这个节点就会成为leader,然后进入数据同步阶段。为什么要超过半数同意,如果是半数同意就可以成为leader会怎么样?

选举流程:

假设当前集群中有5个机器分别为1(1,2),2(2,3),3(3,3),4(4,1),5(5,3)号机器。

①每一个节点在进入选举流程时会首先投票给自己,例如myid为1,zxid为2的节点(1号机器)在进入选举流程时会投出第一张票(1,2),同理myid为2,zxid为3的节点(2号机器)会投出(2,3),并且每个节点会将这张选票发给集群中所有的节点。

②每个节点都会接收到其他节点发来的选票,1号机器会收到(2,3),然后进行比较,自己当前的投票为(1,2),所以会将自己的投票改为(2,3),然后将(2,3)再发送给集群中的其他节点。2号机器同理。

我们按照机器加入顺序分别为:1,2,3,5,4 来分析整个选举的流程

  1. 1号机器投票给自己,当前投票为(1,2),并将该投票不断发送给其他节点
  1. 2号机器投票给自己,当前投票为(2,3),接收到来自1号机器的投票(1,2),2号机器选票的zxid大于1号机器的,所以2号机器的投票不变还是(2,3)。2号机器将自己的投票不断发送给其他节点。1号机器接收到2号机器发来的投票,进行比较发现2号机器的投票更好,将自己的投票改为(2,3),并将(2,3)发送给其他节点。
  1. 3号机器投票给自己,当前投票为(3,3),接收到来自1、2号机器的投票,比较后发现自己的选票最佳,不进行更改。将自己的选票(3,3)发送给集群中其他的节点。1号、2号机器接收到3号机器发来的投票后发现3号的最佳,都将投票改为(3,3),此时集群中已经有3票投给了3号机器,5/2=2,3>2,所以集群中的leader已经被选举出来了,3号机器成为leader,1、2号机器成为follower。进入发现阶段,然后进入数据同步阶段。
  1. 4、5号机器加入后发现leader已经选举出来了,所以将自己的投票分别从(4,1)、(5,3)改为(3,3),然后进入数据同步阶段。

数据同步阶段:从节点将主节点的数据同步过来,使各个节点的数据都与主节点的相同,当集群中超过半数的从节点都完成数据同步后集群就可以对外提供服务了。

2.2. 消息广播模式(同步机制)

Zookeeper集群是一主多从,即只有主节点(leader)可以执行写请求,从节点(follower)和observer(不能参与选举)只能执行读请求,当一个客户端发送写请求时,会进行如下流程:

 

Zookeeper总结分享_第3张图片

 

只有当leader接收到超过集群半数的ack时才会在本地commit,然后将commit广播给所有的follower。

 

3. Zookeeper应用

3.1. 分布式锁

这是雅虎研究员设计Zookeeper的初衷。利用Zookeeper的临时顺序节点,可以轻松实现分布式锁。

3.2.服务注册和发现

利用Znode和Watcher,可以实现分布式服务的注册和发现。最著名的应用就是阿里的分布式RPC框架Dubbo。

3.3.共享配置和状态信息

Redis的分布式解决方案Codis,就利用了Zookeeper来存放数据路由表和 codis-proxy 节点的元信息。同时 codis-config 发起的命令都会通过 ZooKeeper 同步到各个存活的 codis-proxy。

此外,Kafka、HBase、Hadoop,也都依靠Zookeeper同步节点信息,实现高可用。

 

4. 分布式常见问题--脑裂现象

Zookeeper总结分享_第4张图片

指在一个高可用(HA)系统中,当联系着的两个节点断开联系时,本来为一个整体的系统,分裂为两个独立节点,这时两个节点开始争抢共享资源,结果会导致系统混乱,数据损坏。

 

 

你可能感兴趣的:(Java学习,分布式学习,zookeeper,分布式)