在了解Zookeeper之前,需要对分布式相关知识有一定了解,那么什么是分布式系统呢?

通常情况下,单个物理节点很容易达到性能,计算或者容量的瓶颈,所以这个时候就需要多个物理节点来共同完成某项任务,一个分布式系统的本质是分布在不同网络或计算机上的程序组件,彼此通过信息传递来协同工作的系统,而Zookeeper正是一个分布式应用协调框架,在分布式系统架构中有广泛的应用场景。

什么是Zookeeper?

==========================================================================

官方文档上这么解释zookeeper,它是一个分布式协调框架,是Apache Hadoop生态的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。

Zookeeper核心概念

==========================================================================

文件系统数据结构+监听通知机制。

1. 文件系统数据结构

=========================================================================

Zookeeper维护一个类似文件系统的数据结构:

每个子目录项都被称作为Znode(目录节点),和文件系统类似,我们能够自由的增加、删除znode,在一个znode下增加、删除子znode。

有四种类型的znode:

1、PERSISTENT持久化结点: 目录节点客户端与zookeeper断开连接后,该节点依旧存在,只要不手动删除该节点,他将永远存在。

2、PERSISTENT_SEQUENTIAL持久化顺序节点: 客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号。

3、EPHEMERAL临时节点: 客户端与zookeeper断开连接后,该节点被删除。且临时结点不能创建子结点。

4、EPHEMERAL_SEQUENTIAL临时顺序节点: 客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号。

5、 Container节点(3.5.3版本新增,如果Container节点下面没有子节点,则Container节点在未来会被Zookeeper自动清除,定时任务默认60s检查一次)。

6、 TTL节点(默认禁用,只能通过系统配置zookeeper.extendedTypesEnabled=true开启,不稳定)。

2. 监听通知机制

=======================================================================

客户端可以注册监听它关心的任意节点,包括目录节点以及递归子目录节点

如果注册的是对某个节点的监听,则当这个节点被删除,或者被修改时,对应的客户端将被通知 如果注册的是对某个目录的监听,则当这个目录有子节点被创建,或者有子节点被删除,对应的客户端将被通知 如果注册的是对某个目录的递归子节点进行监听,则当这个目录下面的任意子节点有目录结构的变化(有子节点被创建,或被删除)或者根节点有数据变化时,对应的客户端将被通知。

注意:所有的通知都是一次性的,及无论是对节点还是对目录进行的监听,一旦触发,对应的监听即被移除。递归子节点,监听是对所有子节点的,所以,每个子节点下面的事件同样只会被触发一次。

Zookeeper的应用场景

===========================================================================

大概说一下思路

分布式队列:通过ZK的持久化循序结点即可实现。 集群选举: 通过ZK的Leader选举功能即可实现。 发布订阅: 即ZK的注册监听功能。 分布式配置中心、注册中心 创建一个PERSISTENT持久化结点, create /config/项目名 配置文件的JSON格式 客户端监听该结点,get -w /config/项目名,当该结点数据发生变化时,也就意味着配置文件JSON发生了变化,客户端能第一时间感知到。由于监听是一次性的,循环监听即可。 分布式锁(这里重点说一下) ZK的分布式锁可以分为公平锁和非公平锁 非公平锁: 请求进来,创建一个临时结点/lock,create -s /lock, 如果该结点存在,ZK服务端会告知你该结点已经存在,不能重复创建,此时监听该结点,get -w /lock/ 获得锁的请求,处理完后释放锁,即delete /lock/当前获取锁的结点,此时,会通知监听该结点的所有连接,在高并发的情况下,相当是一个灾难。 如上实现方式在并发问题比较严重的情况下,性能会下降的比较厉害,主要原因是,所有的连接都在对同一个节点进行监听,当服务器检测到删除事件时,要通知所有的连接,所有的连接同时收到事件,再次并发竞争,这就是羊群效应。如何避免呢,我们看下面这种方式。 公平锁: 请求进来,直接在/lock结点下创建一个临时顺序结点。 判断自己是不是/lock结点下最小的结点。如果是最小的,即获得锁。如果不是,对前面一个结点进行监听get -w /lock/前面一个结点 获得锁的请求,处理完后释放锁,即delete /lock/当前获取锁的结点,然后它后面的一个结点会收到通知,重复第2步判断。

四、ZK和Redis两种分布式锁对比

===============================================================================

Redis分布式锁

======================================================================

1. setnx + lua脚本

优点:redis基于内存,读写性能很高,因此基于redis的分布式锁效率比较高

缺点:分布式环境下可能会有节点数据同步问题,可靠性有一定的影响。比如现在有一个3主3丛的Redis集群, 客户端发生的命令写入了机器1的master 节点,数据正准备主丛同步的时候,master 结点挂了,slave 结点没有接收到最新的数据,此时 slave结点竞选为master, 导致之前加的分布式锁失效。

2. Redission

优点:解决了Redis集群的同步可用性问题

缺点:网上是说:发布时间短,稳定性和可靠性有待验证。个人觉得,目前市面上已经稳定了,算是比较成熟的比较完善的分布式锁了。

ZK分布式锁

===================================================================

优点:不存在redis的数据同步(zookeeper是同步完以后才返回)、主从切换(zookeeper主从切换的过程中服务是不可用的)的问题,可靠性很高

缺点:保证了可靠性的同时牺牲了一部分效率(但是依然很高)。性能不如redis。

五、ZK集群的Leader选举

============================================================================

Zookeeper集群模式一共有3种类型的角色

Leader: 处理所有的事务请求(写请求),可以处理读请求,集群中只能有一个Leader。 Follower:只能处理读请求,同时作为Leader的候选节点,即如果Leader宕机,Follower节点要参与到新的Leader选举中,有可能成为新的Leader节点。 Observer:只能处理读请求。不能参与选举。

对于来自客户端的每个更新请求,ZooKeeper 都会分配一个全局唯一的递增编号。这个编号反映了所有事务操作的先后顺序,这个编号就是Zxid(ZooKeeper Transaction Id)。

Leader选举流程

=======================================================================

ZK内部采用一种快速选举算法,主要取决于两个因素(myid,Zxid), myid是配置文件中维护的集群序列号,Zxid为ZK的事务id。 假设现在启动两台ZK集群,对应的myid分别为1和2,那么在启动的过程中,就会发生Leader的选举,选举过程如下 由于项目刚启动,是没有任何事务的。所以,myid=1的机器,投出去的票为(1,0),收到的票是(2,0),将收到的票跟自己投出去的票对比,优先原则Zxid大的为Leader,因为Zxid越大则说明数据越新。如果Zxid一样,默认选择myid大的为Leader, 则推荐(2,0)成为Leader。 myid=2的机器,投出去的票为(2,0), 收到的票是(1,0),按照上面的规则,选择(2,0)作为Leader。 由于ZK的过半原则,当达到(集群个数/2+1)台机器选择同一个机器作为Leader时,改机器会从Looking状态切换到Leader状态,而其他的机器则会切换到Follower的状态。

为什么推荐ZK集群个数为奇数个?

=============================================================================

假设集群数量为4个,有一台Leader挂了,还剩3台Follower, 由于Leader选举的过半原则,需要(3/2+1)=2台Follower投票同一台机器才能成为Leader。 假设集群数量为3个,有一台Leader挂了,还剩2台Follower, 由于Leader选举的过半原则,需要(2/2+1)=2台Follower投票同一台机器才能成为Leader。 既然3台机器和4台机器的集群在Leader挂掉之后,都需要2台Follower投票同一台机器才能成为Leader,那为什么不节省一台机器的成本呢?

所以,总得来说,就是为了节省成本。

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)

最后

这份《“java高分面试指南”-25分类227页1000+题50w+字解析》同样可分享给有需要的朋友,感兴趣的伙伴们可挑战一下自我,在不看答案解析的情况,测试测试自己的解题水平,这样也能达到事半功倍的效果!(好东西要大家一起看才香)

片转存中…(img-Fzvg2007-1710743340363)]

最后

这份《“java高分面试指南”-25分类227页1000+题50w+字解析》同样可分享给有需要的朋友,感兴趣的伙伴们可挑战一下自我,在不看答案解析的情况,测试测试自己的解题水平,这样也能达到事半功倍的效果!(好东西要大家一起看才香)

[外链图片转存中…(img-j93KtjRC-1710743340364)]

[外链图片转存中…(img-K7GS5oS2-1710743340364)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

精彩内容

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: