Zookeeper系列一:基础概念

Zookeeper系列一:基础概念

对于每个接触过大数据开发的同学而言,Zookeeper一定是不陌生的。它是一个开源的分布式服务框架,主要的用处就是为其他分布式框架的稳定运行提供服务。它有很多应用场景,比如分布式配置管理、分布式锁等。
笔者将从架构设计、数据模型、选举机制、读写数据流程、Watch机制五个方面展开。

架构设计

通常来讲,Zookeeper中主要有三个角色:

  • 领导者(Leader)
    • 管理协调整个集群的核心角色
    • 写操作的唯一处理者,以便保证来自相同客户端的请求保持发送顺序执行
  • 跟随者(Follower)
    • 可处理读操作请求,如果遇到写操作请求,则需转发给Leader处理
    • 参与集群中的选举投票
  • 观察者(Observer)
    • 为了满足集群访问量过大的需求而设立,不参与选举投票
    • 可处理读操作请求,如果遇到写操作请求,则需转发给Leader处理

数据模型

Zookeeper中的数据模型很简单,和标准文件系统类似,采用树形结构,每个节点称之为Znode,根节点为/。
Znode可以存储数据,至多可以存储1M数据,也可以创建子节点。需要注意的是当通过路径引用节点时,必须采用绝对路径。
在Zookeeper中,存在四种类型的Znode节点:

  • 永久节点:创建后一直存在,除非人为删除
  • 临时节点:只存在于连接会话期间,会话结束就会被删除,临时节点不能有子节点
  • 永久节点、序列化:在永久节点的基础上,追加递增序号
  • 临时节点、序列化:在临时节点的基础上,追加递增序号
    每个Znode主要由三部分组成:
  • stat:状态信息,描述Znode的版本、权限等信息
  • data:存储的数据
  • children:子节点
# 查看所有命令选项
help

# 查看根路径下所有节点
ls /

# 创建普通节点
create /app1 "helloworld"

# 创建带序号的永久节点
create -s /app2 "app2"

# 创建临时节点
create -e /app3 "app3"

# 创建带序号的临时节点
create -e -s /app4 "app4"

# 查看节点数据
get /app1

# 修改节点数据
set /app1 "app1"

# 删除节点
delete /app1

# 递归删除节点
rmr /app1

# 查看节点状态
stat /app3

选举机制

前面提过Zookeeper中是有Leader、Follower、Observer三种角色的,可是我们在配置文件中并没有指定这些角色,那么它们是怎样产生的呢?这就不得不提Zookeeper中的选举机制了。
假设有三台服务器组成的Zookeeper集群,它们的id分别是从1-3,那么当它们第一次启动后,谁才会成为Leader呢?我们简单地分析一下这个流程:

  • 服务器1启动,发起一次选举。服务器1投自己一票,此时得票数为一票,不够半数以上,选举无法完成,服务器1状态保持为LOOKING;
  • 服务器2启动,发起一次选举。服务器1和2分别投自己一票并交换选票信息。此时服务器1发现服务器2的id比自己目前投票选举的id(服务器1)要大,更改选票为服务器2。此时服务器1票数为0,服务器2票数为2,达到半数以上,服务器2当选为Leader。服务器1更改状态为FOLLOWING,服务器2更改状态为LEADING;
  • 服务器3启动,发起一次选举。此时服务器1、2已经不是LOOKING状态,不会更改选票信息。交换选票信息结果:服务器2为2票,服务器3为1票。此时服务器3服从多数,更改选票信息为服务器2,并更改状态为FOLLOWING;
  • 至此选举过程结束。
    以上只是确定了Leader和Follower两类角色,那么Observer该如何确定呢?
    其实Observer是通过配置文件实现的:
  • 在所有将会配置为Observer的节点配置文件zoo.cfg中添加如下语句:
peerType=observer
  • 其次,在所有服务器节点的zoo.cfg配置文件中,observer对应的 server定义处末尾添加:observer:
server.1=bigdata01:2888:3888:observer

读写数据流程

写数据流程

我们知道znode节点可以存储数据,但是在一个分布式系统中,如何才能保证数据的一致性呢?

  • 客户端向Zookeeper集群node1发送一个写数据请求;
  • 如果node1不是Leader,则会将写请求转发给Leader。Leader会将这个写请求广播给各个节点,各个节点会将写请求加入待写队列,并向Leader发送成功信息;
  • 当Leader受到半数以上节点成功信息后,说明该写操作可以执行。Leader回向各个节点发送提交信息,各个节点收到信息后会落实队列中的写请求,此时写操作成功;
  • node1节点会通知客户端写操作成功,此时可以认为整个写操作成功。

读数据流程

相比写数据流程,读数据流程就简单得多;因为每台server中数据一致性都一样,所以随便访问哪台server读数据就行;没有写数据流程中请求转发、数据同步、成功通知这些步骤。

Watch机制

概念

一个典型的发布/订阅模型系统定义了一种一对多的订阅关系,能让多个订阅者同时监听某一个主题对象。当这个主题对象自身状态变化时,会通知所有订阅者,使它们都做出相应的处理。
而在Zookeeper中,就是引入了Watch机制来实现这种分布式的通知功能。
触发通知事件的种类很多,包括节点创建、节点删除、节点改变、子节点改变等。
总体来说,Watch可以分为以下三个过程:

  • 客户端向服务端注册Watch监听事件
  • 服务端事件发生触发Watch机制
  • 客户端回调Watch得到触发事件情况
# 创建普通节点
create /app1 "ap1"

# 监听节点值变化
get /app1 watch

# 监听子节点变化
ls /app1 watch

特点

总体而言,Zookeeper中的Watch机制有以下特点:

  • 一次性触发
    • 事件发生触发监听后,一个watch事件就会被发送到设置监听的客户端
    • 这是一次性的,后续再次发生同样的事件,不会再次触发
  • 事件封装
    • Zookeeper中使用WatchedEvent对象来封装服务端事件并传递
    • WatchedEvent包含了每一个事件的三个基本属性:通知状态、事件类型和节点路径
  • event异步发送
    • watcher的通知事件从服务端发送到客户端是异步的
  • 先注册再触发
    • Zookeeper中的watch机制,必须客户端先去服务端注册监听,这样事件发送才会触发监听,通知给客户端

实现原理

Zookeeper中的Watch机制实现原理如下:

  • 主进程main进程
  • 在主进程中创建Zookeeper客户端同时会启动两个线程,一个是负责网络通信,一个负责监听
  • 通过连接通信线程把注册的监听器事件发送给Zookeeper
  • 在Zookeeper的监听器列表中把注册的监听器加入
  • Zookeeper监听到节点数据变化或者路径变化,就会把此消息发送给监听线程
  • 监听线程在内部会调用process方法,执行相关操作
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值