![75479519-c3b9-426f-a95d-8cb3657ebc2e.gif](https://oscimg.oschina.net/oscnet/75479519-c3b9-426f-a95d-8cb3657ebc2e.gif)
更多精彩内容请关注Tom弹架构
前面花了30天时间整理了设计模式系列文章,得到了非常好的反馈,也让我更加有动力坚持写作,有兴趣的朋友可以回顾这篇文章。
同时,也收到了很多建议,希望我多发一些面试题,今天开始连载互联网公司高频面试题。经常有小伙伴提到分布式锁在面试的过程中经常被问到,通常面试官会从服务框架(Spring Cloud、Dubbo)聊起,一路聊到分布式事务、分布式锁、ZooKeeper等知识。所以这篇文章以 面试问答的角度 带你了解分布式锁这块知识。
![5f9cda3c-c1d6-4ffe-8290-e4fa291e82c7.gif](https://oscimg.oschina.net/oscnet/5f9cda3c-c1d6-4ffe-8290-e4fa291e82c7.gif)
1、Zoo Keeper 提供 了什么?
-
文件系统
-
通知机制
2、Zookeeper 做了什么?
-
命名服务
-
配置管理
-
集群管理
-
分布式锁
-
队列管理
3 、Zookeeper 的配置管理
程序分布式的部署在不同的机器上,将程序的配置信息放在 zk 的 znode 下 ,当有配置发生改变时,也就是 znode 发生变化时,可以通过改变 zk 中某个目录节点的内容,利用 watcher 通知 给各个客户端,从而更改配置。
4、Zookeeper 集群管理
所谓集群管理 有 两点: 是否有机器退出和加入 、 选举 master 。
对于第一点, 所有机器约定在父目录下创建临时目录节点,然后监听父目录节点的子节点变化消息 。一旦有机器挂掉,该机器与 zookeeper 的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个兄弟目录被删除,于是,所有人都知道:它上船了。新机器加入也是类似,所有机器收到通知:新兄弟目录加入,highcount又有了,
对于第二点,我们稍微改变一下, 所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为 master 就好 。
5、Zookeeper 分布式锁
有了 zookeeper 的一致性文件系统,锁的问题变得容易。锁服务可以分为两类,一个是 保持独占 ,另一个是 控制时序 。 对于第一类,我们将zookeeper上的一个znode看作是一把锁,通过 createznode 的方式来实现。所有客户端都去创建 /distribute_lock 节点 ,最终成功创建的那个客户端也即拥有了这把锁。用完删除掉自己创建的 distribute_lock 节点就释放出锁。 对于第二类, /distribute_lock 已经预先存在 ,所有客户端在它下面创建临时顺序编号目录节点,和选 master 一样,编号最小的获得锁,用完删除,依次方便。
6、获取分布式锁的流程
在获取分布式锁的时候在 locker 节点下创建临时顺序节点,释放锁的时候 删除该临时节点 。
客户端调用 createNode 方法在 locker 下创建临时顺序节点, 然后调用 getChildren(“locker”) 来获取 locker 下面的所有子节点,注意此时不用设置任何 Watcher。
客户端获取到所有的 子节点 path 之后,如果发现自己创建的节点在所有创建的子节点序号最小,那么就认为该客户端获取到了锁。如果发现自己创建的节点并非 locker 所有子节点中最小的,说明自己还没有获取到锁, 此时客户端需要找到比自己小的那个节点,然后对其调用 exist()方法 ,同时对其 注册事件监听器 。
之后,让这个被关注的节点删除,则客户端的 Watcher 会收到相应通知,此时再次判断自己创建的节点是否是 locker 子节点中序号最小的, 如果是则获取到了锁,如果不是则重复以上步骤继续获取到比自己小的一个节点 并注册监听。当前这个过程中还需要许多的逻辑。
代码的实现主要是 基于互斥锁 ,获取分布式锁的重点逻辑在于 BaseDistributedLock ,实现了基于 Zookeeper 实现分布式锁的细节。
7、Zookeeper 工作原理
Zookeeper 的核心是 原子广播 ,这个机制保证了各个 Server 之间的同步。实现这个机制的协议叫做 Zab协议 。Zab 协议有两种模式,它们分别是 恢复模式(选主)和广播模式(同步) 。 当服务启动或者在领导者崩溃后,Zab 就进入 了恢复模式,当领导者被选举出来,且大多数 Server 完成了和 leader 的状态同步以后,恢复模式就结束了。状态同步保证了 leader 和 Server 具有相同的系统 状态。
8、Zookeeper 同步流程
选完 Leader 以后,zk 就进入状态同步过程。 ①Leader 等待 server 连接; ②Follower 连接 leader,将最大的 zxid 发送给 leader; ③Leader 根据 follower 的 zxid 确定同步点; ④完成同步后通知 follower 已经成为 uptodate 状态; ⑤Follower 收到 uptodate 消息后,又可以重新接受 client 的请求进行服务了。
9、 zk 节点宕机如何处理?
Zookeeper 本身也是集群, 推荐配置不少于 3 个服务器 。
Zookeeper 自身也要保证当一个节点宕机时,其他节点会继续提供服务。如果是一个 Follower 宕机 ,还有 2 台服务器提供访问,因为 Zookeeper 上 的数据是有多个副本的,数据并不会丢失;如果是一个 Leader宕机 ,Zookeeper 会选举出新的 Leader 。
ZK 集群的机制是只要超过半数的节点正常,集群就能正常提供服务。 只有在 ZK 节点挂得太多,只剩一半或不到一半节点能工作,集群才失效。 所以 3 个节点的 cluster 可以挂掉1个节点(leader 可以得到 2 票>1.5),2 个节点的 cluster 就不能挂掉任何 1个节点了(leader 可以得到 1 票<=1)。
10、Zookeeper 机制的特点
①一次性触发数据发生改变时,一个 watcher event 会被发送到 client,但 是 client 只会收到一次这样的信息。
②watcher event 异步发送 watcher 的通知事件从 server 发送到 client是异步的,这就存在一个问题,不同的客户端和服务器之间通过 socket 进行通信, 由于网络延迟或其他因素导致客户端在不通的时刻监听到事件,由于 Zookeeper 本身提供了 ordering guarantee,即客户端监听事件后,才会感知它所监视 znode 发生了变化。所以我们 使用 Zookeeper 不能期望能够监控到节点每次的变化 。 Zookeeper 只能保证最终的一致性,而无法保证强一致性 。
③数据监视 Zookeeper 有数据监视和子数据监视 getdata() and exists()设置 数据监视,getchildren()设置了子节点监视 。
④ 注册 watcher getData、exists、getChildren
⑤ 触发 watcher create、delete、setData
⑥ setData() 会触发 znode 上设置的 data watch(如果 set 成功的话)。一个 成功的 create() 操作会触发被创建的 znode 上的数据 watch,以及其父节点上 的 child watch。而一个成功的 delete()操作将会同时触发一个 znode 的 data watch 和 child watch(因为这样就没有子节点了),同时也会触发其父节点的 childwatch。
⑦当一个客户端连接到一个新的服务器上时, watch 将会被以任意会话事件触发。当与一个服务器失去连接的时候,是无法接收到 watch 的。而当client 重新连接时,如果需要的话,所有先前注册过的 watch,都会被重新注册。通常这是完全透明的。
只有在一个特殊情况下,watch 可能会丢失:对于一个未创建 的 znode 的 exist watch,如果在客户端断开连接期间被创建了,并且随后在客户端连接上之前又删除了,这种情况下,这个 watch 事件可能会被丢失。
⑧Watch是轻量级的,其实就是本地 JVM 的 Callback,服务器端只是存了是否有设置了 Watcher 的布尔类型。
为了方便大家更好的准备笔试,顺利通过残酷的笔试环节。
这里向大家推荐 一份收录了1700+真题;涵盖 BAT 、美团等一线大厂的面试题合集 :
![2183b6a1-0fdb-4c39-ad76-051c8c009e23.png](https://oscimg.oschina.net/oscnet/2183b6a1-0fdb-4c39-ad76-051c8c009e23.png)
![c5a5b75d-39f7-4262-b2d5-9e001f0e5a3f.png](https://oscimg.oschina.net/oscnet/c5a5b75d-39f7-4262-b2d5-9e001f0e5a3f.png)
![d1b97582-6f5a-48b1-95db-f3d8411371cb.png](https://oscimg.oschina.net/oscnet/d1b97582-6f5a-48b1-95db-f3d8411371cb.png)
![40b2afde-abb1-4d08-a0bd-8aa120e23ad2.png](https://oscimg.oschina.net/oscnet/40b2afde-abb1-4d08-a0bd-8aa120e23ad2.png)
左右滑动查看更多
第一:十秒检索!
秉承拿来即用、精简实用的观 念,投入大量时间对收集的资料进行筛选、分类、去重和统一排版。对大家关 心的Case Interview、面经等内容排出目录方便查找。让你 只需一点点时间便能快速找到想要且有用的内容。
第二:每月更新!不满足于现状,题库及时收纳各厂本月最新面试题。 带你了解大厂实时需求,准备什么、补强什么一目了然。 不会真的有人可以拒绝“带着剧本”去面试的诱惑吧。
懂你所想、知你所需,后台回复「 面试题库 」,做足功课为自己的面试交出满意答卷吧。
![221c5d0e-db0c-465a-8712-e64684e22113.gif](https://oscimg.oschina.net/oscnet/221c5d0e-db0c-465a-8712-e64684e22113.gif)
这是一个为 程序员 量身定做的公众号。 有互联网企业创始人,技术类畅销书作者等行业大牛进行 职业生涯经验的分 享 及专注互联网行业、指导过上万份简历的 资深HR面试tips 分享;累积四年以上的10余项 主流技术的面试题库 ,涵盖各大厂、互联网名企面试题;针对不同岗位的 精选面试简历 。 懂你所想,知你所需! 关注Tom弹架构,有机会获得1V1专属职业规划!
![93f2e4de-9b0d-4c14-a25a-0e277e8ae134.gif](https://oscimg.oschina.net/oscnet/93f2e4de-9b0d-4c14-a25a-0e277e8ae134.gif)
![8baff9fa-e3a3-4753-b54c-12c98fd67776.gif](https://oscimg.oschina.net/oscnet/8baff9fa-e3a3-4753-b54c-12c98fd67776.gif)
![3cc1dbaf-786e-47ec-91f0-c025a02608b1.gif](https://oscimg.oschina.net/oscnet/3cc1dbaf-786e-47ec-91f0-c025a02608b1.gif)
本文分享自微信公众号 - Tom弹架构(gh_e3be84a8ccb2)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“ OSC源创计划 ”,欢迎正在阅读的你也加入,一起分享。