什么是zookeeper:
zookeeper是一种分布式协调服务,用于管理大型主机,在分布式环境中协调和管理服务是一个复杂的过程.zookeeper通过其简单的架构和API解决了这个问题.zookeeper允许开发人员专注于核心应用程序逻辑,而不必担心应用程序的分布式特性.
zookeeper的数据模型
zookeeper的数据模型是什么样子呢?它很像数据结构中的树,也很像文件系统的目录.
树是由节点所组成.zookeeper的数据存储也同样是基于节点,这种节点叫做Znode.
但是,不同于树的节点,Znode的引用方式是路径引用,类似于文件路径:
/动物/猫
/汽车/宝马
这样的层级结构,让每一个Znode节点拥有唯一的路径,就像命名空间一样对不同信息作出清晰的隔离.
Znode包含哪些元素
data:Znode存储的数据信息.
ACL:记录Znode的访问权限,即哪些人或哪些IP可以访问本节点.
stat:包含Znode的各种元数据,比如事务ID,版本号,时间戳,大小等等.
child:当前节点的子节点引用
这里需要注意一点,Zookeeper是为读多写少的场景所设计.Znode并不是用来存储大规模业务数据,而是用于存储少量的状态和配置信息,每个节点的数据最大不能超过1MB.
Zookeeper的基本操作
创建节点
create
删除节点
delete
判断节点是否存在
exists
获得一个节点数据
getData
设置一个节点
setData
获取节点下的所有子节点
getChildren
这其中,exists,getData,getChildren属于都操作.zookeeper客户端在请求读操作的时候,可以选择是否设置Watch
Zookeeper的事件通知
我们可以把Watch理解成是注册在特定Znode上的触发器.当这个Znode发生变化,也就是调用了create,delete,setData方法的时候,将会触发Znode上注册的对应事件,请求Watch的客户端会接收到异步通知.
具体交互过程如下:
1.客户端可调用getData方法,watch参数是true.服务端接到请求,返回节点数据,并且在对应的哈希表里插入被watch的Znode路径,以及Watcher列表.
2.当被 Watcher的Znode已删除,服务端会查找哈希表,找到该Znode对应的所有Watcher,异步通知客户端,并且删除哈希表中对应的key-value.
Zookeeper的一致性
Zookeeper身为分布式系统协调服务,如果自身挂了如何处理呢?为了防止单机挂掉的情况,zookeeper维护了一个集群.
Zookeeper Service集群是一主多从结构.
在更新时,首先更新到主节点(这里的节点指的是服务器,不是Znode),再同步到从节点.
在读取数据时,直接读取任意从节点.
为了保证主节点的数据一致性,Zookeeper采用了ZAB协议,这种协议非常类似于一致性算法Paxos和Raft.
什么是ZAB
Zookeeper Automic Broadcast,有效解决了Zookeeper集群崩溃恢复,以及主从同步数据的问题.
ZAB协议定义三个节点状态
1.Looking:选举状态
2.Following:Follower节点(从节点)所处的状态.
3.Leading:leader节点(主节点)所处状态.
最大ZXID
最大ZXID也就是节点本地的最新事务编号,包含epoch和技术两部分,epoch是纪元的意思,相当于Raft算法选主时候的term.
ZAB的崩溃恢复
假如Zookeeper当前的主节点挂掉了,集群会进行崩溃恢复,ZAB的崩溃恢复分成三个阶段:
Leader election
选举阶段,此时集群中节点处于looking状态,它们会各自向其他节点发起投票,投票当中包含自己的服务器ID和最新事务ID(ZXID).
接下来,节点会用自身的ZXID和从其他节点接收到的ZXID做比较,如果发现别人家的ZXID比自己新,那么就重新发起投票,投票给目前已知最大的ZXID所属节点.
每次投票后,服务器都会统计投票数量,判断是否某个节点得到半数以上的投票.如果存在这样的节点,该节点将会成为准leader,状态变为leading.其他节点的状态变为Following.
Discovery
发现阶段,用于在从节点中发现最新的ZXID和事务日志,或许有人会问:既然leader被选为主节点,已经是集群里放数量最新的了,为什么还要从节点中寻找最新的事务呢?
这是为了防止某些意外情况,比如因网络原因在上一阶段产生多个leader的情况.
所以这一阶段,leader集思广益,接收所有Follower发来各自的最新epoch,基于此值加1,生成新的epoch分发给各个Follower.
各个Follower收到全新的epoch后,返回ACK给leader,带上各自最大的ZXID和历史事务日志.leader选出最大的ZXID,并更新自身历史日志.
Synchronization
同步阶段,把leader刚才收集得到的最新的历史事务日志,同步给集群中所有的follower.只有当半数follower同步成功,这个准leader才能成为正式的leader.
自此,故障恢复正式完成.
ZAB数据写入
Broadcast
ZAB的数据写入涉及到Broadcast阶段,简单来说,就是Zookeeper常规情况下更新数据的时候,由leader广播到所有的Follower.其过程如下:
1.客户端发出写入数据请求给任意Follower.
2.Follower把写入数据请求转发给leader.
3.leader采用二阶段提交方式,先发送Propose广播给Follower.
4.Follower接到Propose消息,写入日志成功后,返回ACK消息给leader.
5.leader接到半数以上ACK消息,返回成功给客户端,并且广播Commit请求给Follower.
ZAB协议既不是强一致性,也不是弱一致性,而是处于两者之间的单调一致性(顺序一致性).它依靠事务ID和版本号,保证了数据的更新和读取是有序的.
Zookeeper的应用场景
分布式锁
这是雅虎研究员设计Zookeeper的初衷.利用Zookeeper的临时顺序节点,可以轻松实现分布式锁.
服务注册和发现
利用Znode和Watcher,可以实现分布式的注册和发现.最著名的应用就是阿里的分布式RPC框架Dubbo.
共享配置和状态信息
Redis的分布式解决方案Codis,就是利用了Zookeeper来存放数据路由表和codis-proxy节点的元信息.同时codis-config发起的命令都会通过Zookeeper同步到各个存活的codis-proxy.
此外,Kafka,HBase,Hadoop,也都依靠Zookeeper同步节点信息,实现高可用.
什么是临时顺序节点?
Zookeeper的数据存储结构就像一棵树,这棵树由节点组成,这种节点叫做Znode.
Znode分为四种类型:
持久性节点
默认的节点类型,创建节点的客户端与zookeeper断开连接后,该节点依旧存在.
持久节点顺序节点
所谓顺序节点 ,就是在创建 节点时,zookeeper根据创建的时间顺序给该节点名称进行编号.
临时节点
和持久节点相反,当创建节点的客户端与zookeeper断开连接后,临时节点会被删除.
临时顺序节点
顾名思义,临时顺序节点结合和临时节点和顺序节点的特点:在创建节点时,Zookeeper根据创建的时间顺序给该节点名称进行编号;当创建节点客户端与zookeeper断开连接后,临时节点会被删除.
Zookeeper分布式锁的原理
分布式锁三个核心功能:加锁,解锁,锁超时
三个问题
1.要保证原子性操作,加锁和锁超时的操作要一次性执行
2.防止误删锁
3.在误删锁的基础上,加多一个守护线程,为锁续命
zookeeper分布式锁呢?
临时顺序节点
Znode有四种状态:
持久节点
持久节点有序节点
临时节点状
临时节点有序节点