1.数据发布/订阅

数据发布/订阅(Publish/Subscribe)系统,即所谓的配置中心,顾明思义就是发布者将数据发布到zookeeper的一个或一系列的节点上,供订阅者进行数据订阅,进而达到动态获取数据的目的,实现配置信息的集中式管理和数据的动态更新。

zookeeper采用推拉结合的方式来实现发布订阅系统:客户端向服务端注册自己需要关注的节点,一旦该节点的数据发生变更,那么服务端就会向相应的客户端发送Watcher事件通知,客户端接收到这个消息通知之后,需要主动到服务端获取最新的数据。

程序总是需要配置的,如果程序分散部署在多台机器上,要这个改变配置就变得困难。好吧,现在把这些配置全部放到zookeeper上去,保存在zookeeper的某个目录节点中,然后所有相关应用程序对这个目录节点进行监控,一旦配置信息发生变化,每个应用程序就会收到zookeeper的通知,然后从zookeeper中获取新的配置信息应用到系统中就好
在这里插入图片描述

2.负载均衡

每台服务端在启动时都会去zookeeper的servers节点下注册临时节点(注册临时节点是因为,当服务不可用时,这个临时节点会消失,客户端也就不会请求这个服务端),每台客户端在启动时都会去servers节点下取得所有可用的工作服务器列表,并通过一定的负载均衡算法计算得出应该将请求发到哪个服务器上
在这里插入图片描述

3.生成分布式唯一ID

在过去的单库单表型系统中,通常可以使用数据库字段自带的auto_increment属性来自动为每条记录生成一个唯一的ID。但是分库分表后,就无法在依靠数据库的auto_increment属性来唯一标识一条记录了。此时我们就可以用zookeeper在分布式环境下生成全局唯一ID。做法如下:每次要生成一个新Id时,创建一个持久顺序节点,创建操作返回的节点序号,即为新Id,然后把比自己节点小的删除即可。
在这里插入图片描述

4.Master选举

Master选举是一个在分布式系统中非常常见的应用场景。在分布式系统中,Master往往用来协调系统中的其他系统单元,具有对分布式系统状态变更的决定权。例如,在一些读写分离的应用场景用,客户端的写请求往往是由Master来处理的,而在另一些场景中, Master则常常负负责处理一下复杂的逻辑,并将处理结果同步给集群中其他系统单元。Master选举可以说是zookeeper最典型的应用场景了

利用zookeeper的强一致性,能够很好地保证在分布式高并发情况下节点的创建一定能保证全局唯一性,即zookeeper将会保证客户端无法重复创建一个已经存在的数据节点。也就是说,如果同时有多个客户端请求创建同一个节点,那么最终一定只有一个客户端能够创建成功。利用这个特性,就很容易在分布式环
在这里插入图片描述
境中进行Master选举
客户端集群往zookeeper上创建一个/master临时节点。在这个过程中,只有一个客户端能够成功创建这个节点,那么这个客户端就成了master。同时其他没有在zookeeper上成功创建节点的客户端,都会在节点/master上注册一个变更的watcher,用于监控当前的master机器是否存活,一旦发现当前的master挂了,那么其余的客户端将会重新进行master选举

5.分布式锁

在同一个JVM中,为了保证对一个资源的有序访问,如往文件中写数据,可以用synchronized或者ReentrantLock来实现对资源的互斥访问,如果2个程序在不同的JVM中,并且都要往同一个文件中写数据,如何保证互斥访问呢?这时就需要用到分布式锁了

目前分布式锁的主流实现方式有两种

1.利用redis setnex(key value) key不存在返回0,key存在返回1

2.zookeeper实现排他锁,共享锁(读锁)

这里只简单介绍一下排他锁的实现方式

实现原理和master选举类似,所有客户端在/exclusive_lock节点下创建临时子节点/exclusive_lock/lock,zookeeper会保证在所有的客户端中,最终只有一个客户端能够创建成功,那么就认为该客户端获取了锁,其他没有获取到锁的客户端就需要到/exclusive_lock节点看上注册一个子节点变更的watcher监听,以便实时监听到lock节点的变更情况

释放锁的情况有如下两种

1.当前获取锁的客户端发生宕机,那么zookeeper上的这个临时节点就会被删除

2.正常执行完业务逻辑后,客户端会主动将自己创建的临时节点删除

整个排他锁的获取和释放流程可以用如下图表示
在这里插入图片描述

6.分布式队列

如下图,创建/queue作为一个队列,然后每创建一个顺序节点,视为一条消息(节点存储的数据即为消息内容),生产者每次创建一个新节点,做为消息发送,消费者监听queue的子节点变化(或定时轮询),每次取最小节点当做消费消息,处理完后,删除该节点。相当于实现了一个FIFO(先进先出)的队列。注:zookeeper强调的是CP(一致性),而非专为高并发、高性能场景设计的,如果在高并发,qps很高的情况下,分布式队列需酌情考虑。
在这里插入图片描述

引用文章链接:
https://mp.weixin.qq.com/s?__biz=MzIxMzk3Mjg5MQ==&mid=2247484102&idx=1&sn=601ba010b138c5c37d9d1612350e709a&chksm=97afe032a0d86924d8801703485cb44e33c293ea997a55cbd65b3dd9e61f1e2f091a96b69d65&scene=21#wechat_redirect

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐