Zookeeper的学习(含Redis分布式和一致性相关)

参考:Zookeeper入门
rpc使用zk的例子1
rpc使用zk的例子2
添加链接描述

添加链接描述
添加链接描述
添加链接描述
添加链接描述
添加链接描述
添加链接描述


三种实现分布式锁的方式–请点击


Zookeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。
Zookeeper 功能较多,能够配置维护、域名服务、分布式同步、组服务等,也有很多服务框架使用 Zookeeper 来做注册中心。


1.命名服务   2.配置管理   3.集群管理   4.分布式锁  5.队列管理 

zookeeper注册中心(zookeeper的通知机制)

Zookeeper 用来做服务注册中心,主要是因为它具有节点变更通知功能,只要客户端监听相关服务节点,服务节点的所有变更,都能及时的通知到监听客户端,这样作为调用方只要使用 Zookeeper 的客户端就能实现服务节点的订阅和变更通知功能了,非常方便。
另外,Zookeeper 可用性还算是可以的,因为只要半数以上的选举节点存活,整个集群就是可用的。

zookeeper注册中心的实现机制

在zookeeper中进行服务注册就是在zookeeper创建了一个节点,结点存储该服务的IP端口号,调用方式(协议,序列化)等,由服务提供者去创建,以供消费者去获取信息,服务端启动服务时,会将服务名称,IP地址等信息注册到注册中心服务消费者在第一次调用服务时,会通过注册中心找到相应的服务的IP地址列表,并缓存到本地,以供后续使用。
当消费者调用服务时,不会再去请求注册中心,而是直接通过负载均衡算法从IP列表中取一个服务提供者的服务器调用服务。当服务提供者的某台服务器宕机或下线时,相应的ip会从服务提供者IP列表中移除。同时,注册中心会将新的服务IP地址列表发送给服务消费者机器,缓存在消费者本机。

zookeeper提供心跳检测,会盯上想服务端发送一个请求(实际上建立的是一个 socket 长连接),如果长期没有响应,服务中心就认为该服务提供者已经“挂了”,并将其剔除)
服务消费者会去监听相应路径(/HelloWorldService/1.0.0),一旦路径上的数据有任务变化(增加或减少),zookeeper都会通知服务消费方服务提供者地址列表已经发生改变,从而进行更新。
zookeeper 与生俱来的容错容灾能力(比如leader选举),可以确保服务注册表的高可用性。

使用 zookeeper 作为注册中心时,客户端订阅服务时会向 zookeeper
注册自身;主要是方便对调用方进行统计、管理。但订阅时是否注册 client 不是必要行为,和不同的注册中心实现有关,例如使用 consul
时便没有注册。





Zookeeper工作原理 (zookeeper的核心:原子广播

Zookeeper的底层选举原理?如何保持zookeeper数据一致性?Zab原子广播协议

Zookeeper 的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议
Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)
当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和 leader的状态同步以后,恢复模式就结束了。
状态同步保证了leader和Server具有相同的系统状态。

为了保证事务的顺序一致性,zookeeper采用了递增的事务id号(zxid)来标识事务
所有的提议(proposal)都在被提出的时候加上了zxid。
实现中zxid是一个64位的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的统治时期。低32位用于递增计数。

在这里插入图片描述

zxid什么情况下会不一致?

在同步的时候一台突然宕机了

zab原子广播协议有两种模式

1、恢复模式:初次启动节点时,选举leader,从节点进入恢复模式同步主节点数据
2、广播模式:解决每个节点的数据同步问题

恢复模式

当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数server完成了和leader的状态同步以后,恢复模式就结束了
状态同步保证了leader和server具有相同的系统状态。

广播模式

一旦Leader已经和多数的Follower进行了状态同步后,他就可以开始广播消息了,即进入广播状态。
这时候当一个Server加入ZooKeeper服务中,它会在恢复模式下启动,发现Leader,并和Leader进行状态同步。待到同步结束,它也参与消息广播。
ZooKeeper服务一直维持在Broadcast状态,直到Leader崩溃了或者Leader失去了大部分的Followers支持

Broadcast模式极其类似于分布式事务中的2pc(two-phrase commit 两阶段提交):即Leader提起一个决议,由Followers进行投票,Leader对投票结果进行计算决定是否通过该决议,如果通过执行该决议(事务),否则什么也不做。
在这里插入图片描述
在这里插入图片描述
对于客户端发送的写请求,全部由 Leader 接收,Leader 将请求封装成一个事务 Proposal,将其发送给所有 Follwer ,然后,根据所有 Follwer 的反馈,如果超过半数成功响应,则执行 commit 操作(先提交自己,再发送 commit 给所有 Follwer)。

当超过半数成功回应,则执行 commit ,同时提交自己。同时每个事物都有一个zxid 还有一个消息队列 解决异步,同时,针对各个节点的数据不一致性问题还有选举过程。



zookeeper分布式锁(与Redis分布式锁)

在这里插入图片描述
在这里插入图片描述

zookeeper分布式锁

在这里插入图片描述

Zk实现分布式锁思想:节点保持唯一事件通知临时节点(生命周期和session会话关联)
因为Zookeeper节点路径保持唯一,不允许重复 且有临时节点特性,连接关闭后当前节点会自动消失,从而实现分布式锁。
在这里插入图片描述

zk实现分布式锁的落地方案:

  • 使用zk的临时节点和有序节点每个线程获取锁就是在zk创建一个临时有序的节点,比如在/lock/目录下。

  • 创建节点成功后,获取/lock目录下的所有临时节点,再判断当前线程创建的节点是否是所有的节点的序号最小的节点

  • 如果当前线程创建的节点是所有节点序号最小的节点,则认为获取锁成功

  • 如果当前线程创建的节点不是所有节点序号最小的节点,则对节点序号的前一个节点添加一个事件监听

    • 比如当前线程获取到的节点序号为/lock/003,然后所有的节点列表为[/lock/001,/lock/002,/lock/003],则对/lock/002这个节点添加一个事件监听器。

    • 如果锁释放了,会唤醒下一个序号的节点,然后重新执行第3步,判断是否自己的节点序号是最小。
      -在这里插入图片描述

Redis分布式锁

使用Redis做分布式锁的思路大概是这样的:在redis中设置一个值表示加了锁,然后释放锁的时候就把这个key删除
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
除了要考虑客户端要怎么实现分布式锁之外,还需要考虑redis的部署问题。

redis有3种部署方式

  • 单机模式

  • master-slave + sentinel选举模式

  • redis cluster模式

使用redis做分布式锁的缺点在于:如果采用单机部署模式,会存在单点问题,只要redis故障了。加锁就不行了。

采用master-slave模式,加锁的时候只对一个节点加锁,即便通过sentinel做了高可用,但是如果master节点故障了,发生主从切换,此时就会有可能出现锁丢失的问题。

在这里插入图片描述

Redisson

实现Redis的分布式锁,除了自己基于redis client原生api来实现之外,还可以使用开源框架:Redission

Redisson是一个企业级的开源Redis Client,也提供了分布式锁的支持。我也非常推荐大家使用,为什么呢?

回想一下上面说的,如果自己写代码来通过redis设置一个值,是通过下面这个命令设置的。

SET anyLock unique_value NX PX 30000

这里设置的超时时间是30s,假如我超过30s都还没有完成业务逻辑的情况下,key会过期,其他线程有可能会获取到锁。

这样一来的话,第一个线程还没执行完业务逻辑,第二个线程进来了也会出现线程安全问题。所以我们还需要额外的去维护这个过期时间,太麻烦了~

我们来看看redisson是怎么实现的?先感受一下使用redission的爽:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Zookeeper与Redis实现分布式锁的区别?

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述





CAP理论

CAP理论:对一个分布式系统中,当涉及读写操作时,只能保证一致性、可用性、分区容错性,三者中的两个,另外一个必须被牺牲。

  • C(一致性)实际上保证的是对于一个客户端而言,每一次的读操作,返回的一定是最新的写操作的结果
  • A(可用性)是指非故障的节点在合理的时间内返回合理的响应,数据允许可以出错,允许脏读,数据同步的时候服务可用,数据最终会一致,注重服务可用。
  • P(分区容错性)是指当出现网络分区后,系统能够继续“履行职责”,允许出现网络故障,不会因为网络故障判断一个节点宕机了

现在的对于CAP的应用主要分为了AP、CP两种,因为对于分布式而言P(分区容错性)是必选的,如果我们选择CA(一致性、可用性)发生分区现象时,由于网络的不可靠性,为了保证一致性我们一定会在在分区时禁止写入,就与可用性有了冲突。

CP,即网络分区时为了保证一致性,在客户端访问到数据未同步到最新的节点时会返回error。也就是暂时放弃了可用性的要求。
AP,即网络分区出现时,在客户端访问到数据未同步到最新的节点时会返回旧的数据给他,暂时放弃了一致性的要求。在数据一致之后再用后续的方案进行数据筛选。

BASE是CAP理论中AP方案的延伸,指基本可用、软状态、最终一致性,核心思想是即使无法做到强一致性,但应用可以采用适合的方式达到最终一致性。
Paxos算法是基于消息传递且具有高度容错特性的一致性算法。目的是为了解决分布式环境下一致性的问题。

zookeeper采用CP

2PC两阶段提交协议解决分布式数据同步问题?(?

2PC两阶段提交协议应用于分布式事务场景,解决分布式多个系统间数据的一致性,如数据库XA机制。
多个服务器同时进行写操作,一台出错全部回滚。是全局的事务id
事务请求:只有在写操作的时候才会用到事务
Zk底层解决分布式事务问题,就是采用类似2pc两阶段提交协议的Zab协议;




集群管理

集群管理两点:1.是否有机器退出和加入 2.选举master

对于第一点,所有机器约定在父目录GroupMembers下创建临时目录节点,然后监听父目录节点的子节点变化消息
一旦有机器挂掉,该机器与 zookeeper的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个兄弟目录被删除,于是,所有人都知道:它上船了。

新机器加入也是类似,所有机器收到通知:新兄弟目录加入,highcount又有了,对于第二点,我们稍微改变一下,所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为master就好。


为什么Zookeeper集群节点一定要是奇数?为什么集群数量要大于三台?

  1. 因为节点剩余数要满足过半机制,剩余节点>总节点/2,三台集群和四台集群都只能宕机一台,还不如三台
  2. 偶数台容易造成票数相同

集群数量要大于三台的原因:
两台做集群的话,故障一台就不满足过半机制了,还不如不集群

Zookeeper中有哪三种类型的节点?分别是什么作用?

1.Leader类型 领导类型 负责写的请求,和各个节点同步;
2.Follower类型 跟随者 负责读的请求和投票决议
3.ObServer类型 观察者 和Follower大部分特征都是一样的,唯一区别就是不能参与选举和投票

注意:zk集群在后期扩容的时候,建议不要使用follow节点类型,会导致选举时间变长。

为什么要使用ObServer类型?

主要不影响原来本身选举的时间的效率、目的是提高客户端查询效率;
写操作都是转发给leader写的,读操作follower或者observer自己读

节点类型分为四种

1、临时节点–会话关闭,就自动消失(zk.close())
2、持久节点–永久持久化到硬盘
3、临时有序节点,自增
4、持久有序节点
在这里插入图片描述
在这里插入图片描述

Zookeeper选主流程(basic paxos)

系统默认的选举算法为fast paxos
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值