【Zookeeper】应用场景及实现原理

1. 数据发布订阅——Watch机制

如:全局配置信息(配置更新频繁)

  • 推拉结合

客户端向服务器注册自己关注的节点、一旦该节点的数据发生变更,那么服务器就向相应的客户端发送Watcher事件通知,客户端收到通知之后,需要主动到服务端获取最新的数据。

2. 负载均衡——Watch机制

如:动态DNS(DDNS)动态域名负载均衡。

DNS

域名和IP地址一一映射,在实际开发中,往往使用本地HOST绑定来实现域名解析。缺陷:

  1. 域名变更,则需要在每个机器上逐个变更;
  2. 机器上线,需要在每台机器上去绑定域名。

DDNS

在Zookeeper上创建一个个 域名节点 ,将ip列表配置上去。

  1. 域名注册

每个服务提供者在启动的过程中,都注册自己的域名、ip等信息,然后DDNS自动根据域名将ip信息写入相应的节点中;

  1. 域名解析

由应用自己负责,通常先从域名节点获取一份ip地址的配置,进行自我解析。同时每个应用还会在域名节点注册一个数据变更Watcher监听,以便及时接收到域名变更的通知。

  1. 域名变更

zookeeper会向订阅的客户端发送这个事件,应用收到通知后,会再次进行域名配置的获取。

3.命名服务(分布式全局ID)——顺序节点

如果是单库单表系统,那么我们可以使用数据库自带的auto_increment属性。

对于分布式的应用,有一种方式是UUID:基于硬件、时间、随机数等特征生成。包含32位字符+4个短线,缺点是长度太长、含义不明。

Zookeeper实现唯一ID

利用Zookeeper提供的创建 顺序节点 的接口,对客户端的调用zookeeper会自动以后缀的形式在子节点上添加序号并返回。

4. 集群管理——临时节点 + Watch机制

目标:

  1. 希望知道当前集群中有多少机器在工作;
  2. 对集群中每台机器的运行时状态进行收集;
  3. 对集群中机器进行上下线操作;

客户端在zookeeper的一个节点注册临时节点,一旦会话失效,那么该临时节点也被自动清除。

5. Master选举——并发安全

场景:广告投放系统集群中,商品或广告投放id往往需要从海量数据中计算得到,通常是一个耗费IO与CPU的过程。我们需要让集群中的部分或者一台主机去处理,然后共享给整个集群中其他所有机器。

实现:Client集群每天定时通过zookeeper实现master选举,master节点计算出结果之后,存储到内存/数据库中,同时通知其他节点共享计算结果。

Master节点选取

  1. 关系型数据库的主键:所有节点向数据库插入一条相同主键的记录,哪个成功了哪个就是master。
    缺陷:选出的master如果挂了,其他节点不知道。

  2. zookeeper中有 多个客户端创建同一个节点,只有一个能成功 。其他失败的节点则注册一个watcher,用于监控当前master是否存活,一旦master挂了其余节点将重新选取。

关于并发创建节点,只有一个能成功的原因:

对于Zookeeper来说,写请求也就是事务请求,客户端不论连接到哪个集群节点,最终都会被转发到Leader节点执行,因此可以顺序处理。

6. 分布式锁——临时顺序节点 + Watch机制

6.1 排它锁

获取锁

  1. 客户端通过调用create创建同一个 临时节点 ,调用成功的那个客户端代表获取到了锁。
  2. 同时没有获取到锁的客户端,在该节点上注册watcher监听,以便监听到lock节点的变更情况。

释放锁

在获取锁时,客户端创建的是临时节点,有两种情况下都可能释放锁:

  1. 当前获取锁的客户端发生宕机,那么zookeeper上这个临时节点将被移除
  2. 正常执行完业务逻辑之后,客户端就会主动将自己创建的节点删除

6.2 共享锁

获取锁

  1. 客户端调用create创建一个 临时顺序节点
  2. 创建完节点之后,获取当前节点下的所有子节点,并注册 watcher监听所有子节点列表
  3. 确定自己的节点序号在子节点中的顺序
    • 如果是读请求,判断是否能成功获取锁:
      • 没有比自己序号小的节点
      • 比自己序号小的节点都是读请求
    • 如果是写请求,判断是否能成功获取锁:
      • 自己是最小的子节点
  4. 接收到watcher通知之后,重新获取该节点下所有子节点,重复上述步骤

释放锁

与排它锁的逻辑一样

共享锁的缺陷——羊群效应

当集群规模足够大,获取锁的客户端完成业务之后释放锁,其余所有节点都「收到watcher通知」、「子节点列表获取」。

然而只有一台机器检查到自己是序号最小的机器可以进行操作,其余节点仍然继续等待。缺陷在于客户端收到过多与自己并不相关的事件通知。

如果同一时间多个节点完成事务或者是事务中断,引起节点消失,zookeeper服务器就会 短时间内向其余客户端发送大量的时间通知 ——这就是所谓的羊群效应。

  • 改进:客户端只需要关注比自己序号小的那个节点,而不需要关注全局的子列表变更情况。

改进后的共享锁

获取锁

  1. 客户端调用create创建临时顺序节点,调用getChildren获取所有已经创建的子节点列表,注意,这里不注册任何watcher
  2. 如果无法获取共享锁,向自己的目标节点注册watcher。
    这里的目标节点:
    1. 读请求是比自己序号小的那个写节点;
    2. 写请求是前一个节点。
  3. 等待watcher通知

7. 分布式队列——临时顺序节点 + Watch机制

应用:FIFO先进先出队列

与共享锁的实现类似:注册临时顺序节点、确定自己的顺序,如果不是最小的,则监听最后一个节点。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值