zookeeper面试题
1.zk的用途?
为了让多个程序协调工作。zk从文件系统api得到启发,提供一组简单的api,使得开发人员可以实现通用的协作任务,包括选择主节点,管理组内成员关系,管理元数据等。
2.CAP
C:consistency 一致性
A:availability 可用性
P:partition-tolerance 分区容错性
该定律指出,当设计一个分布式系统时,我们希望这三种属性全部满足,但没有系统可以同时满足这三种属性。zk的设计是尽可能满足一致性和可用性。
3.zk的watch机制?
zk通常以远程服务的方式被访问,如果每次访问znode时,客户端都需要获得节点中的内容,这样的就会导致有更高的延迟。这是一个常见的轮询问题。为了替换客户端的轮询,zk选择了基于通知notification的机制:客户端向zk注册需要接受通知的znode,通过对znode设置监视点watch来接受通知。监视点是一个单次触发的操作,即监视点只会触发一个通知。如果想要接受多个通知,客户端必须在每次通知后重新设置一个新的监视点。
zk可以定义不同类型的通知,这依赖于设置监视点对应的通知类型。如监控znode的数据变化,监控znode子节点的变化,监控znode的创建和删除。
4.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)
5. 用zk实现一个分布式锁?
假设一个应用的n个进程在尝试获取一个锁,我们使用zk的接口api来管理znode来实现锁。为了获得一个锁,每个进程p尝试创建znode,名为/lock。如果进程p成功创建了znode,就表示它获得了锁,并可以继续执行其临界区域的代码。为了避免进程p奔溃导致这个锁永远无法释放,创建的/lock节点指定为临时节点。并且如果其他进程因为znode已经存在而获取锁失败,则该进程继续监听/lock的变化,并在检测到/lock删除时再次尝试创建节点来获取锁。
6. zk的选举机制?
群首选择:群首为集群的服务器选择出来的一个服务器,并会一直被集群所认可。
设置群首的目的是为了对客户端发起的zk状态变更请求进行排序,包括:create、setData和delete操作。群首将每一个请求转换为一个事务,并将这些事务发送给追随者,确保集群按照群首确定的顺序接受并处理这些事务。
每个服务器启动后进入LOOKING状态,开始选举一个新的群首或者查找已经存在的群首。如果群首已经存在,其他服务器就会通知这个新启动的服务器,告知哪个服务器是群首,于此同时,新的服务器会与群首建立连接,以确保自己的状态与群首一致。
如果集群中所有的服务器都处于LOOKING状态,这些服务器之间就会进行通信来选举一个群首,通过信息交换对群首选举达成共识的选择。在本次选举过程中胜出的服务器将进入LEADING状态,而集群中其他服务器将会进入FOLLOWING状态。
选举的协议非常简单:当一个服务器将于LOOKING状态并参与选举群首时,会向集群中的每个服务器发送一个群首选举通知消息,该消息中包含该服务器的投票vote信息,==投票中包含服务器标识符sid,和最近执行的事务的zxid信息。(sid,zxid)。==比如投票信息(1,5)标识服务器sid为1,最近执行的事务的zxid是5。==简而言之,zxid大的代表最新的服务器将赢得选举。==如果多个服务器zxid一致,则选择sid大的服务器。当一个服务器接收到仲裁数量的服务器发来的投票都一样时,就标识群首选举成功,如果被选择的群首是某个服务器自己,该服务器将行使群首角色,否则就成为一个追随者并尝试连接被选举的群首服务器。