简介数据结构节点类型
持久(Persistent)
持久化目录节点持久化顺序编号目录节点 短暂(Ephemeral)
临时目录节点临时顺序编号目录节点 应用场景特点选举机制
理解几个概念选举状态什么时候会进行选举?第一次启动非第一次启动
Leader在集群中存在Leader不在集群中 监听器原理
监听器原理详解:常见的监听:注意 写数据原理
向Leader节点发送写数据的请求向Follower节点发送写数据的请求 分布式锁
分布式锁的由来什么是分布式锁?分布式锁的特点zookeeper分布式锁
原理:
简介数据结构ZooKeeper由雅虎研究院开发,是Google Chubby的开源实现,后来托管到Apache,于2010年11月正式成为Apache的顶级项目。
ZooKeeper是一个经典的分布式数据一致性解决方案,致力于为分布式应用提供一个高性能、高可用,且具有严格顺序访问控制能力的分布式协调服务。
分布式应用程序可以基于ZooKeeper实现数据发布与订阅、负载均衡、命名服务、分布式协调与通知、集群管理、Leader选举、分布式锁、分布式队列等功能。
zookeeper数据模型的结构与Unix文件系统很类似,整体上可以看做一颗树,每个节点称为ZNode。zookeeper为了保证高吞吐量和低延迟,把整个树状结构的目录都放在了内存中,由于内存大小的限制,每一个ZNode默认最多能够存储1MB的数据,每个ZNode都可以通过其路径唯一标识。
节点类型zookeeper的节点类型分为一下两种:
持久(Persistent)客户端和服务器断开连接后,该节点不删除,直到有删除操作来主动清除这个节点。
持久化目录节点客户端与zookeeper断开连接后,该节点依然存在
持久化顺序编号目录节点客户端与zookeeper断开连接后,该节点依然存在,zookeeper给该节点名称进行顺序编号
创建ZNode时设置顺序标识,ZNode名称后会附加一个值,顺序号是一个单调递增的计数器,用于记录每个节点创建的先后顺序,由父节点维护
短暂(Ephemeral)客户端和服务器断开连接后,该节点自己删除。临时znode在会话退出时会自动删除,所以不能在临时节点上创建子节点。另外临时节点属于某会话,但所有客户端都可以查看、引用它。
需要注意的是,当客户端会话失效后,所产生的临时节点并不是一下子就消失,而是要过段时间才会消失(大概10S左右)。
临时目录节点客户端和服务器断开连接后,该节点被删除
临时顺序编号目录节点客户端与zookeeper断开连接后,该节点被删除,zookeeper给该节点名称进行顺序编号
应用场景统一命名服务:在分布式的环境下,通常一个应用被部署在多台机器上,这些IP难以被记住,而zookeeper可以将这些IP进行统一命名一个域名。
统一配置管理:在分布式的环境下,配置文件的同步是非常常见的。一般来说,会要求一个集群下的所有节点的配置信息都是一致的,并且进行修改之后,希望能够快速地同步到各个节点上。统一集群管理:在分布式的环境下,实时掌握每个节点的状态是必要的,可以根据节点实时状态做出一些调整。可以将节点信息写入zookeeper上的一个ZNode上,然后监听这个ZNode获取它的实时状态变化。比如:dubbo的注册中心默认就是zookeeper
软负载均衡:在zookeeper中记录每台服务器的访问数,让访问数最少的服务器去处理最新的客户端请求 特点
zookeeper的集群由一个领导者(Leader),多个跟随者(Follower)组成集群中只要有半数以上节点存活,zookeeper集群就可以正常工作,所以zookeeper适合安装奇数台服务器全局数据一致性:每个server保存一份相同的数据副本,Client无论连到哪个server,拿到的数据都是一样的更新请求顺序执行,来自同一个Client的更新请求按其发送顺序依次执行数据更新原子性,要么全部更新成功,要么全部更新失败实时性,在一定时间范围内,Client能读到最新数据 选举机制 理解几个概念
myid:唯一标识自己的IDSID:服务器ID,用来唯一标识一台zookeeper集群中的机器,每台机器不能重名ZXID:事务ID,ZXID是一个事务ID,用来标识一次服务器状态的变更。在某一时刻,集群中的每台机器的ZXID值不一定完全一直,这和zookeeper服务器对于客户端的更新请求的处理逻辑有关Epoch:每个Leader任期的代号。没有Leader时同一轮投票过程中的逻辑时钟值是相同的,每投完一轮这个数据就会增加 选举状态
LOOKING: 竞选状态FOLLOWING: 随从状态,同步 leader 状态,参与投票OBSERVING: 观察状态,同步 leader 状态,不参与投票LEADING: 领导者状态 什么时候会进行选举?
zookeeper集群第一次启动的时候zookeeper集群第一次选举完毕,但是发生意外导致服务器在运行期间无法和Leader保持连接 第一次启动
假设一个zookeeper中的集群中有5台服务器:
第一台服务器启动,会发起一次选举,投给自己一票。发现自己的票数少于机器数的一半,选举无法完成,则服务器1状态保持为Looking。第二台服务器启动,再发起一次选举,服务器1和2均投给自己一票并且会交换自己的选票信息,此时服务器1发现服务器2的myid比自己的大,更改自己的选票,选服务器2,此时票数为服务器1:0,服务器2:2,但是最高的票数少于机器数的一半,选举无法完成,则服务器1和2状态均保持为Looking。第三台服务器启动,再发起一次选举,服务器1和2和3均投给自己一票并且会交换自己的选票信息,此时服务器1和2发现服务器3的myid比自己的大,都更改自己的选票,选服务器3,此时票数为服务器1:0,服务器2:0,服务器3:3,此时最高的票数大于机器数的一半,选举完成,服务器1和2状态更改为Follower,服务器3状态为Leader。第四台服务器启动,再发起一次选举,此时由于服务器1、2和3的状态不是Looking状态,不会更改选票信息。交换选票信息,此时服务器1:0,服务器2:0,服务器3:3,服务器4:1,此时服务器4少数服从多数,更改选票信息为服务器3,更改自己的状态为Follower第四台服务器启动,再发起一次选举,此时由于服务器1、2、3和4的状态不是Looking状态,不会更改选票信息。交换选票信息,此时服务器1:0,服务器2:0,服务器3:4,服务器4:0,服务器5:1;此时服务器5少数服从多数,更改选票信息为服务器3,更改自己的状态为Follower。 非第一次启动
此时发生意外,导致服务器在运行期间无法和Leader保持连接,此时会进行重新选举,会分两种情况:
Leader在集群中存在机器试图去选举Leader的时候,会被告知当前集群中Leader的信息,对于该机器来说,只需要去和Leader机器进行建立连接,同步状态即可
Leader不在集群中此时选举的规则顺序为:
EPOCH大的直接胜出EPOCH相同,事务ID大的胜出EPOCH相同,事务ID都相同,服务器ID大的胜出 监听器原理 监听器原理详解:
首先有一个main()线程在main线程中创建zookeeper客户端,这是就会创建两个线程,一个负责网络连接通信(connect),一个负责监听(listenr)通过connect线程将注册的监听时间发送给zookeeper在zookeeper的注册监听器列表中将注册的监听时间添加到列表中zookeeper监听到有数据或路径变化,就会将这个消息发送给listener线程listener线程内部调用了process()方法 常见的监听:
监听节点数据的变化:get path [watch]监听子节点增减的变化:ls path [watch] 注意
zookeeper的监听事件只会监听一次,如需再次监听,需要继续添加监听请求。
写数据原理 向Leader节点发送写数据的请求步骤:
首先客户端向Leader节点发起一个写的请求server写完之后,Follower1进行写的同步Follower1写完后,向server返回确认自己已经写完此时由于集群中有3台,已经有超过一半的机器写完了,就可以返回给client端,表示已完成写请求然后服务端再让Follower2同步写的数据Follower2写完后,向server返回确认自己已经写完 向Follower节点发送写数据的请求
步骤:
首先客户端向Follower1节点发起一个写的请求由于Follower节点没有写权限,于是转给有写权限的Leader,有写的请求server写完之后,Follower1进行写的同步Follower1写完后,向server返回确认自己已经写完此时由于集群中有3台,已经有超过一半的机器写完了,此时返回给Follower1(因为client是向Follower1发起的请求),表示操作已经完成了Follower1就可以返回给client端,表示已完成写请求然后服务端再让Follower2同步写的数据Follower2写完后,向server返回确认自己已经写完 分布式锁 分布式锁的由来
在以往单机应用中,我们可以通过synchronized或者ReentrantLcok等常用锁进行对资源访问时线程间的互斥。但在分布式系统中,由于系统中的进程、线程在不同的机器上,而synchronized或者ReentrantLcok等常用锁只对属于自己的JVM中的线程有效,这就会导致这些原来单机部署情况下的并发控制锁策略失效,这时候,我们就需要一个方式来解决这种跨机器的进程对同一资源访问时的互斥问题。
什么是分布式锁?当多个不在同一个系统中的进程,对同一资源进行访问时,就需要分布式锁来对这些进程的访问顺序进行控制。
分布式锁的特点互斥性:不管任何时候,只能有一个客户端获取到锁,不能出现两个客户端同时获取到锁的情况安全性:锁的释放只能被锁获取的客户端执行,不能被其他客户端执行不死锁:锁当前的拥有客户端,如果突然出现问题,不会出现一直持有锁,导致其他客户端获取不到锁的现象可重入:对于同一线程,可以多次重复加锁 zookeeper分布式锁
zookeeper中的临时顺序节点,让zookeeper能够轻松的实现分布式锁。
原理:服务端接收到请求后,在/locks节点(持久节点)下创建一个临时顺序节点判断自己是不是当前/locks节点下顺序最小的点:是,则获取到锁;不是,则监听前一个节点获取到锁之后,进行相应的业务处理;然后将删除节点,释放锁,而在该节点之后的节点将会收到前面的锁释放了的通知,重复第二步的判断



