ZooKeeper实现分布式的思路

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介:

Hadoop生态系统为开源届提供很多优秀软件,zookeeper便是其中一员。

前段时间项目中用到了zookeeper,主要是用作服务的注册和发现使用方式类似阿里的dubbo。实际上zookeeper的功能不仅仅只有这些内容,它提供了一系列非常方便使用的功能,后面会提到。这篇文章仅仅是我个人的一点儿理解,如有错误烦请指正,以免给别人误导。

1、zookeeper是什么

zookeeper的名字很有趣被称为动物管理员,这是因为Hadoop生态系统中很多软件的名字都是动物,hadoop本身就是小象的意思,还有hive小蜜蜂,pig。zookeeper作为一个分布式协调系统在hadhoop中被广泛的应用,其中HBase默认带有zookeeper。zookeeper主要功能有配置维护、分布式锁、选举、分布式队列等,并且zookeeper本身可以是一个集群,提供了高可用性。这一切的功能都离不开zookeeper的数据模型。

2、zookeeper数据模型

zookeeper提供的命名服务看起来和一个unix的文件系统非常相似,下面是从官网复制的一张图:

其中的每个节点称为znode,每个znode节点既可以包含数据又可以包含子节点,由于zookeeper被定位为协调程序因此znode中的数据通常存储的是非常小的数据,比如状态信息,位置信息等等。znode中有一个很重要的概念——节点类型,znode有两种类型的节点:临时节点,永久节点。其中这两种节点又分为有序和无序,重点讲一下临时节点,因为zk中很多基础的功能都是基于临时节点实现的,client在和zookeeper连接的时候两者之间会建立起session,session的状态由zookeeper服务端维护,临时节点的特点是随着session的超时服务端会将client建立的所有临时节点移除,而永久节点即使客户端退出节点也不会消失,同时临时节点不能有子节点但是可以挂载数据。结合watcher机制可以实现非常丰富和灵活的功能。

3、zookeeper集群结构

zookeeper实现分布式的思路

zookeeper本身支持单机部署和集群部署,生产环境建议使用集群部署,因为集群部署不存在单点故障问题,并且zookeeper建议部署的节点个数为奇数个,只有超过一半的机器不可用整个zk集群才不可用。zookeeper集群中主要有两个角色leader和flower,每个客户端可以连接集群中的任何一个zookeeper节点,同时从其上面read信息,但是针对write操作,flower节点会转发给leader,由leader负责原子广播,从而保证集群中各个节点的数据一致性,zookeeper中规定只有当多余一半的节点同步完成整个write操作才算完成。也就是说可能会有少于一半的数据不是新数据,因此zookeeper中不是强一致性而是实现的最终一致性。但是客户端可以使用sync来强制读取最新的数据。

4、replaction

zookeeper中的高可用性是通过数据冗余和实现的,也就是一份数据存在多个节点中,zookeeper中要求同一份数据需要在超过一半的节点上存在,只有这样才能实现对宕机数量的容忍度更高。zk建议配置奇数个节点,是因为在flower同步数据和进行leader选举的时候都要求有超过一半完成或同意才算ok。举例来说,假如有3个节点,至少需要有2个节点正常,就是容忍度为1(允许宕掉的节点数),有4个节点,至少需要有三个节点正常,容忍度同样为1,多出来一个机器但是容忍度相同在任何时候看来都得不偿失。因此zk建议部署奇数个节点,但这不是强制。另外再看一下为什么写操作的时候要求至少有超过一半节点commit成功整体才成功,假如有2t+1个zk节点,也就是必须有t+1个节点commit成功才算成功,因为只有这种情况下才能达成至少有一个节点存有前后两次的更新操作(两次t+1节点至少会重复一个)。zookeeper使用zab算法实现数据的原子广播,并且每次write会写日志然后更新缓存,每个zk节点维护一个zxid,zxid是一个全局变量,随着znode的每一次改变而递增,当leader挂掉的时候,剩余的flower选择zxid最大的节点作为新的leader,在新leader提供服务前还需要一次数据恢复,新leader只是拥有最多的数据,但不一定拥有最新的数据,因此leader和flower的数据需要同步到最新的状态,通过合并的过程完成整个数据的恢复。

zookeeper实现分布式的思路

上图5个zk节点允许两个宕机,其他三个节点总是能恢复出来ABCDE。

5、Watch机制

zookeeper允许客户端对znode节点或者节点中的数据设置监听器,当znode改变的时候服务器触发监听,客户端完成一个回调做自己需要处理的逻辑。zookeeper中的watch是一次性的,也就是当监听触发后,需要再次应用watcher,下次才能在收到变化的通知。exists,getData,getChildren接口都可以指定是否应用watcher,可以使用默认的watcher或者自定义watcher。触发watcher的可以为create、delete、setData、setACL。

6、配置管理

如果是单机或者几台机器,当应用的配置项变更的时候,可能通过手动的方式去修改一下,但是假如一个集群中有成百上千个应用节点,如何才能保证快速无差错的完成配置项的变更。zookeeper的出现可以轻松地解决这个问题

zookeeper实现分布式的思路

每个节点在zk上建立永久型znode并写入配置项,然后监听该节点下数据的变化,一旦其他客户端修改了其中的数据,所有的监听客户端都会收到变更通知。

7、Leader选举

zookeeper本身提供leader选举机制,大概的思路是所有的节点创建临时有序的znode然后监听所有节点的变化情况,获取最小序号和自己创建的序列作比较,如果自己为最小则当选为leader,当主动删除自己创建的节点或者leader宕机后,临时节点消失,该变化会被其他存活的节点获取到从而触发第二次的leader选举,依次类推。实际上zookeeper提到的很多recipes curator都提供了很好的实现(除了两阶段提交),同时基于底层的zookeeper api开发应用需要考虑的东西很多,curator对这些都提供了封装,所以如果要编写zookeeper应用推荐使用curator。

leader应用的场景很广泛,curator提供了两种不同的选举实现,一种是轮询做leader,另外一种是永久获取leader权直到退出,两种选举实现可以应用在不同的集群应用中。HBase中使用的是获取leader的永久权


.本文作者:佚名

来源:51CTO

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
相关文章
|
1月前
|
监控 负载均衡 Cloud Native
ZooKeeper分布式协调服务详解:面试经验与必备知识点解析
【4月更文挑战第9天】本文深入剖析ZooKeeper分布式协调服务原理,涵盖核心概念如Server、Client、ZNode、ACL、Watcher,以及ZAB协议在一致性、会话管理、Leader选举中的作用。讨论ZooKeeper数据模型、操作、会话管理、集群部署与管理、性能调优和监控。同时,文章探讨了ZooKeeper在分布式锁、队列、服务注册与发现等场景的应用,并在面试方面分析了与其它服务的区别、实战挑战及解决方案。附带Java客户端实现分布式锁的代码示例,助力提升面试表现。
124 2
|
2月前
|
监控 Dubbo 前端开发
快速入门分布式系统与Dubbo+zookeeper Demo
快速入门分布式系统与Dubbo+zookeeper Demo
42 0
|
2月前
|
监控 NoSQL Java
Zookeeper分布式锁
Zookeeper分布式锁
90 1
|
5天前
|
存储 大数据 Apache
深入理解ZooKeeper:分布式协调服务的核心与实践
【5月更文挑战第7天】ZooKeeper是Apache的分布式协调服务,确保大规模分布式系统中的数据一致性与高可用性。其特点包括强一致性、高可用性、可靠性、顺序性和实时性。使用ZooKeeper涉及安装配置、启动服务、客户端连接及执行操作。实际应用中,面临性能瓶颈、不可伸缩性和单点故障等问题,可通过水平扩展、集成其他服务和多集群备份来解决。理解ZooKeeper原理和实践,有助于构建高效分布式系统。
|
1月前
|
Java 网络安全 Apache
搭建Zookeeper集群:三台服务器,一场分布式之舞
搭建Zookeeper集群:三台服务器,一场分布式之舞
47 0
|
3月前
|
Java Linux Spring
Zookeeper实现分布式服务配置中心
Zookeeper实现分布式服务配置中心
50 0
|
3月前
|
存储 分布式计算 Hadoop
ZooKeeper初探:分布式世界的守护者
ZooKeeper初探:分布式世界的守护者
67 0
|
15天前
|
NoSQL Java 关系型数据库
【Redis系列笔记】分布式锁
分布式锁:满足分布式系统或集群模式下多进程可见并且互斥的锁。 分布式锁的核心思想就是让大家都使用同一把锁,只要大家使用的是同一把锁,那么我们就能锁住线程,不让线程进行,让程序串行执行,这就是分布式锁的核心思路
112 2
|
10天前
|
监控 NoSQL 算法
探秘Redis分布式锁:实战与注意事项
本文介绍了Redis分区容错中的分布式锁概念,包括利用Watch实现乐观锁和使用setnx防止库存超卖。乐观锁通过Watch命令监控键值变化,在事务中执行修改,若键值被改变则事务失败。Java代码示例展示了具体实现。setnx命令用于库存操作,确保无超卖,通过设置锁并检查库存来更新。文章还讨论了分布式锁存在的问题,如客户端阻塞、时钟漂移和单点故障,并提出了RedLock算法来提高可靠性。Redisson作为生产环境的分布式锁实现,提供了可重入锁、读写锁等高级功能。最后,文章对比了Redis、Zookeeper和etcd的分布式锁特性。
111 16
探秘Redis分布式锁:实战与注意事项
|
12天前
|
NoSQL Java 大数据
介绍redis分布式锁
分布式锁是解决多进程在分布式环境中争夺资源的问题,与本地锁相似但适用于不同进程。以Redis为例,通过`setIfAbsent`实现占锁,加锁同时设置过期时间避免死锁。然而,获取锁与设置过期时间非原子性可能导致并发问题,解决方案是使用`setIfAbsent`的超时参数。此外,释放锁前需验证归属,防止误删他人锁,可借助Lua脚本确保原子性。实际应用中还有锁续期、重试机制等复杂问题,现成解决方案如RedisLockRegistry和Redisson。