zookeeper学习笔记

zookeeper文件数据结构

zookeeper维护了一种类似文件系统的数据结构:
在这里插入图片描述
节点类型

  1. PERSISTENT:­持久化目录节点
    客户端与服务端断开连接后,该节点不会被清除,除非手动删除节点,不然会一直存在。

  2. PERSISTENT_SEQUENTIAL­:持久化顺序编号目录节点
    创建节点时,zookeeper会给该节点自己标上序号,其他的与PERSISTENT一样。

  3. EPHEMERAL:­临时目录节点
    客户端与服务端断开连接后,节点会被清除。

  4. EPHEMERAL_SEQUENTIAL­:临时顺序编号目录节点
    创建节点时,zookeeper会给该节点自己标上序号,其他的与EPHEMERAL一样。

  5. Container:容器节点
    如果该节点没有子节点,则会删除该节点。定时任务默认60s检查一次。

  6. TTL 节点
    创建该节点后,过了指定的时间后,zookeeper会自动清楚该节点。
    默认情况下是禁止的,需要配置 zookeeper.extendedTypesEnabled=true开启。

监听通知机制

在zookeeper,事件监听可分为三种:

  1. 监听目录
    会监听目录的变化,如目录的增、删,而不是节点的值的变化。
    命令:ls -w /path
  2. 监听节点
    会监听节点的变化,就是节点的值的变化,节点的路径变化不会监听。
    命令:get -w /path
  3. 监听目录的递归子节点
    对目录的所有子节点以及节点的值进行监听,如果子节点发生目录结构的变化(增、删)或者节点的值进行改变,都会监听到。这种情况下,对于每个子节点的目录变化都会响应一次。
    命令:ls -R -w /path

需要注意的是,对于节点或目录的监听都是一次性的,如果需要保持持续监听,需要在响应后再执行一次监听命令。

zookeeper使用场景

分布式锁

在这里插入图片描述
这种方式在并发高的情况下,性能会很低,因为当监听的节点被删除时,zookeeper会通知所有的客户端,收到通知的客户端会同时去竞争,但是只会有一个客户端获取到锁,这就是羊群效应。

想要避免的话,就要采取下面这种办法:
在这里插入图片描述

获取锁的过程:

  1. 客户端尝试在/lock下创建一个临时顺序节点
  2. 判断在/lock下创建的节点是否是最小的节点;
    如果是,则成功获取到锁;
    如果不是,则监听前面的节点。当前面的节点被删除时,会收到通知,再重复2步骤。
  3. 删除创建的临时节点,后面的客户端收到通知。

类似的用法还可以实现读写锁:
在这里插入图片描述
读写加锁时,要判断前面的节点是否有写锁,如果有写锁,则监听最近的写锁节点;
写锁加锁时,要判断前面的节点是否有加锁,如果有加锁,则监听最近的加锁节点。

注册中心

在这里插入图片描述

ZAB协议

ZAB 协议全称:Zookeeper Atomic Broadcast(Zookeeper 原子广播协议)。
整个Zookeeper 就是一个分布式一致性算法的实现,底层协议用的是ZAB协议。
ZAB协议是为分布式协调服务 zookeeper 专门设计的,支持 崩溃恢复原子广播协议。
基于该协议,zookeeper实现了一种 主备模式 的系统架构来保持集群间数据的一致性。

下面开始介绍 消息广播崩溃恢复

消息广播

整个 消息广播过程如下:
在这里插入图片描述

  1. 客户端往集群leader发送一条写命令;
  2. leader收到命令后:
    2.1 将写命令封装成一个事务proposal,放入一个队列里,发送给所有follower;
    2.2 leader写本地事务文件;
    2.3 leader给自己发送一个ack信号;
  3. follower收到leader发过来的proposal后,会以事务日志的方式存入本地磁盘,然后给leader发送一个ack信号;
  4. leader收到半数以上的follower的ack信号后,认为消息发送成功,然后发送commit信号给所有的follower,同时完成自己的事务提交;
  5. follower收到commit信号,完成事务提交。
有一些需要注意的地方:
  1. Leader收到客户端的请求后,会将请求封装成一个proposal事务,并给proposal事务分配一个全局唯一的递增ID,称为事务ID(ZXID),zookeeper要保证事务必须按照顺序依次执行,所以把它放入一个先进先出的队列中;
  2. 为了保证数据的一致性,只有Leader能处理客户端的写请求,Follower只能处理读请求,就算Follower收到了写请求,也会转发给Leader;
  3. ZAB协议规定了一个事务在一台机器中commit了,也就认为这个事务在所有的机器都能成功,即使这台机器崩溃了。
崩溃恢复

按照上诉的过程,不得不思考两个问题:
1.如果leader把proposal发给所有leader后,如果leader挂了怎么办?
2.如果follow在收到ack后提交了自己的事务,发送给commit时leader挂了怎么办?

针对这两个问题,ZAB会有两种行动原则:
1.ZAB协议会丢弃那些只在leader提出,但还没commit的事务;
2.ZAB协议会保证那些在leader中commit的事务在所有的机器中都commit。

所以,在进行leader的崩溃恢复时,ZAB协议会确保选出来的leader具有以下两个条件:
1.不能包含未提交的proposal;
2.含有集群中最大的事务ID(ZXID),这样的目的是保证新选出来的leader含有所以已提交的proposal。

数据同步

崩溃恢复完成后,leader会确保事务被过半数的follower提交了,即完成了数据同步。当follower同步完所有的数据后,就会加入到可用服务列表当中。

ZXID

ZXID被设计成了一个64位的数字。
低32位是一个简单的递增计数器,每当完成一个客户端的事务proposal请求,该值就会+1;
高32位代表了从本地事务日志取出的最大事务的ZXID,并从该值解析出epoch,epoch代表了该机器的选举周期,每进行一轮选举,epoch+1。
当完成一轮选举后,除了epoch会加1,低32位的事务id会清零,然后从0开始计数。
在这里插入图片描述
通过这种巧妙的设计,高32位代表了每一代leader的唯一性,低32位代表了每一代leader中事务的唯一性。简化了数据恢复流程。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值