Zookeeper 应用

ZooKeeper是一个集中服务,用于维护配置信息,命名,提供分布式同步和提供组服务。所有这些类型的服务都以某种形式被分布式应用程序使用。实现了高度可靠的分布式协调

应用:

学习资源:zookeeper系列

1 master选举

  •   描述

在集群中,有主从服务器(master-follow)之分。

master的职责是对外提供服务,follow的职责是监视master,当master宕机时,需要从follow中选举一个成为master,继续提供服务。

  • 原理

在zookeeper上创建master和server节点,master节点存储master机器信息,server节点保存服务器信息。

服务器启动时,在server节点下创建临时子节点。

服务器关闭时,删除子节点(自动执行),解除对master的绑定事件。如果自己是master,调用zkclient删除此节点。

所有的server子节点添加对master节点的监视,发现master被删除时,重新用自己的data创建master节点。

中间需要判断master是否已经存在的。

需要应对网络抖动的问题,即判断上一次的master是自己吗?如果是,则在延时后删除master,再次触发竞争。

2 数据发布和订阅

  • 描述

一对多的关系,当一个服务的变动需要同时触发其它多个服务的变动时,且这个服务不清楚需要触发多少个服务,可以使用发布-订阅机制。即多个订阅者监听这个服务的变化,变化发生,执行对应的操作。

可以用作:配置管理

  • 原理

启动发布服务时,在zookeeper上创建servers节点;

启动订阅服务器时,在servers节点下创建server子节点;

server节点绑定servers节点的dataChange事件,当父节点servers的data发生变化时,根据父节点的返回值修改自己的data

3 负载均衡

  • 描述   客户端访问集群中的服务器时,根据负载均衡算法获取最合适的服务器建立连接,选取服务器的过程可以使用zookeeper辅助实现

  • 原理

一个集群中的所有服务在zookeeper中的相同父节点(/servers)下创建对应的节点,节点data中包括属性当前负载数;

当客户端client连接服务器时,先去获取zookeeper中/servers的所有子节点,并对这个子节点列表的负载数排序;

选取当前负载数最小的服务,创建连接;

建立连接的服务器修改自己对应节点data的负载数属性加1;

建立连接可以使用netty中ChannelHandlerAdapter的channelActive主动触发。

4 实现分布式锁

  • 描述

当集群中多个线程的操作需要锁来控制并发性的时候,使用zookeeper的序列化节点可以实现分布式锁。

  • 原理

当线程需要获得一个锁的时候,在相同的locker节点下创建序列化的临时子节点;

当线程不再需要持有锁的时候,将刚刚创建的临时子节点删除;

当前线程是否拥有锁的判断条件是在locker的所有序列化子节点中,自己节点是否在所有子节点的index是0

如果是,则当前自己已经持有锁;

如果否,则找到自己序列的前一个节点,对这个节点添加删除事件的监视,当index-1的节点的删除事件触发时,则将持有锁的标记设置为true,开始执行自己的线程。执行完删除zookeeper中自己创建的临时节点。

5 分布式队列

  • 描述

使用zookeeper维护一个列表,不同的应用服务可以从同一个列表中获取要处理的资源,不同的应用服务也可以往同一个列表中加入需要其他应用处理的资源。

  • 原理

每当productor创建一个对象时,在zookeeper中的queue节点下创建一个序列化的临时子节点,子节点保存序列化后的对象;

每当consumer需要获取一个对象时,获取zookeeper的queue节点下的所有子节点,按照节点名称排序后,取出最小的一个节点的data返回,同时删除这个临时子节点;

阻塞队列的实现:依靠CountDownlatch来控制consumer获得对象前的阻塞。可以创建queue子节点的修改事件的监听,当事件发生时,调用countDownLatch.countDown()方法。当consumer获取对象时,如果获取对象不为null,直接返回;如果是null,则调用countDownLatch.wait()等待。

6 命名服务

  • 描述

当需要在分布式的环境中创建唯一的标示id,有两个途径,一个是uuid,另外一个是分布式命名服务。uuid的缺点在于生成的随机字串没有明确的含义,所以可以使用分布式的命名服务。

  • 原理

当需要获取一个自增的id时,在zookeeper的id节点下,创建一个序列化的临时子节点,创建成功后返回,并删除当前子节点(防止请求量大,生成了很多子节点);

返回的子节点经过字符串的切割,分离出自增的数字部分的内容,即可以作为自增的id。

一般,因为考虑到请求量大的关系,将获取命名的过程放在线程池中执行。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值