【总结】ZooKeeper应用分析

来源:互联网 发布:ubuntu gps.h 编辑:程序博客网 时间:2024/06/10 08:13
1,ZooKeeper
  • ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务
  • 是Google的Chubby一个开源的实现,是HadoopHbase重要组件
  • 分布式应用提供一致性服务的软件,提供的功能包括:配置维护、名字服务、分布式同步、组服务
2,ZooKeeper使用场景
  • 分布式配置中心(数据发布与订阅)
    • 【说明】发布者将数据发布ZK节点上,供订阅者动态获取数据,实现配置信息集中式管理动态更新
    • 配置
      • 应用在启动的时候会主动来获取一次配置,同时,在节点上注册一个Watcher
      • 以后每次配置有更新的时候,都会实时通知订阅的客户端,从来达到获取最新配置信息的目的
    • 分布式搜索
      • 索引的元信息和服务器集群机器的节点状态存放在ZK的一些指定节点,供各个客户端订阅使用
    • 分布式日志收集系统
      • 核心工作是收集分布在不同机器的日志
      • 收集器通常是按照应用来分配收集任务单元,因此需要在ZK上创建一个以应用名作为path的节点P,并将这个应用的所有机器ip,以子节点的形式注册节点P
      • 这样一来就能够实现机器变动的时候,能够实时通知收集器调整任务分配
    • 动态信息获取
      • 系统中有些信息需要动态获取,并且还会存在人工手动去修改这个信息的访问
  • 命名服务(Naming Service)
    • 分布式系统中,通过使用命名服务,客户端应用能够根据指定名字获取资源服务的地址提供者等信息
    • 被命名的实体通常可以是集群中的机器提供的服务地址远程对象等等——这些我们都可以统称他们为名字(Name)
    • 较为常见的就是一些分布式服务框架中服务地址列表。通过调用ZK提供的创建节点的API,能够很容易创建一个全局唯一的path,这个path就可以作为一个名称
      • 服务提供者在启动的时候,向ZK上的指定节点/dubbo/${serviceName}/providers目录下写入自己的URL地址,这个操作就完成了服务的发布
      • 服务消费者启动的时候,订阅/dubbo/${serviceName}/providers目录下的提供者URL地址, 并向/dubbo/${serviceName} /consumers目录下写入自己的URL地址
      • 注意,所有向ZK上注册的地址都是临时节点,这样就能够保证服务提供者和消费者能够自动感应资源的变化
      • Dubbo还有针对服务粒度的监控,方法是订阅/dubbo/${serviceName}目录下所有提供者和消费者的信息
  • 分布式通知/协调
    • 原理
      • 使用zookeeper来进行分布式通知和协调能够大大降低系统之间耦合
      • ZooKeeper中特有Watcher注册异步通知机制,能够很好的实现分布式环境下不同系统之间通知协调,实现对数据变更实时处理
      • 不同系统都对ZK上同一个znode进行注册监听znode的变化(包括znode本身内容及子节点的),其中一个系统update了znode,那么另一个系统能够收到通知,并作出相应处理
    • 使用场景
      • 另一种心跳检测机制
        • 检测系统和被检测系统之间并不直接关联起来,而是通过zk上某个节点关联,大大减少系统耦合
      • 另一种系统调度模式
        • 某系统有控制台推送系统两部分组成,控制台的职责是控制推送系统进行相应的推送工作
        • 管理人员在控制台作的一些操作,实际上是修改了ZK上某些节点的状态,而ZK就把这些变化通知给他们注册Watcher的客户端推送系统,于是,作出相应的推送任务
      • 另一种工作汇报模式
        • 一些类似于任务分发系统,子任务启动后,到zk来注册一个临时节点,并且定时将自己的进度进行汇报(将进度写回这个临时节点),这样任务管理者就能够实时知道任务进度
  • 集群管理与Master选举
    • 利用ZooKeeper有两个特性,就可以实施另一种集群机器存活性监控系统
      • 客户端在节点 x 上注册一个Watcher,那么如果 x 的子节点变化了,会通知该客户端
      • 创建EPHEMERAL类型的节点,一旦客户端服务器会话结束过期,那么该节点就会消失
    • 使用场景
      • 监控系统
        • 监控系统在 /clusterServers 节点注册一个Watcher,以后每动态加机器,那么就往 /clusterServers 下创建一个 EPHEMERAL类型的节点:/clusterServers/{hostname}
        • 监控系统就能够实时知道机器的增减情况,至于后续处理就是监控系统的业务了
        • 一旦有机器挂掉,该机器与 zookeeper的连接断开,其所创建的临时目录节点被删除(跟上一条重复)
      • Master选举则是zookeeper中最为经典的应用场景
        • 分布式环境中,相同的业务应用分布在不同的机器上,有些业务逻辑(例如一些耗时的计算,网络I/O处理),往往只需要让整个集群中的某一台机器进行执行其余机器可以共享这个结果,这样可以大大减少重复劳动,提高性能,于是这个master选举便是这种场景下的碰到的主要问题
        • 利用ZooKeeper的强一致性,能够保证在分布式高并发情况下节点创建的全局唯一性
          • 同时有多个客户端请求创建 /currentMaster 节点,最终一定只有一个客户端请求能够创建成功
          • 利用这个特性,就能很轻易的在分布式环境中进行集群选取了
        • 动态Master选举
          • 这就要用到EPHEMERAL_SEQUENTIAL类型节点的特性了
          • 就是允许所有请求都能够创建成功,但是得有个创建顺序
          • 于是所有的请求最终在ZK上创建结果的一种可能情况是这样: /currentMaster/{sessionId}-1 ,?/currentMaster/{sessionId}-2 ,?/currentMaster/{sessionId}-3 ….. 每次选取序列号最小的那个机器作为Master
          • 如果这个机器挂了,由于他创建的节点会马上消失,那么之后最小的那个机器就是Master
      • 搜索系统
        • 如果集群中每个机器都生成一份全量索引,不仅耗时,而且不能保证彼此之间索引数据一致
        • 因此让集群中的Master来进行全量索引的生成,然后同步到集群中其它机器
        • Master选举的容灾措施是,可以随时进行手动指定master,就是说应用在zk在无法获取master信息时,可以通过比如http方式,向一个地方获取master
      • Hbase
        • 使用ZooKeeper来实现动态HMaster的选举
        • 在Hbase实现中,会在ZK上存储一些ROOT表的地址HMaster的地址HRegionServer也会把自己以临时节点(Ephemeral)的方式注册到Zookeeper,使得HMaster可以随时感知到各个HRegionServer的存活状态
        • 同时,一旦HMaster出现问题,会重新选举出一个HMaster来运行,从而避免了HMaster的单点问题
  • 分布式锁
    • 分布式锁,这个主要得益于ZooKeeper为我们保证了数据的强一致性。锁服务可以分为两类,一个是保持独占,另一个是控制时序
    • 独占
      • 所谓保持独占,就是所有试图来获取这个锁的客户端,最终只有一个可以成功获得这把锁
      • 通常的做法是把zk上的一个znode看作是一把,通过create znode的方式来实现
      • 所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁
    • 控制时序
      • 控制时序,就是所有视图来获取这个锁的客户端,最终都是会被安排执行,只是有个全局时序
      • 做法和上面基本类似,只是这里 /distribute_lock 已经预先存在,客户端在它下面创建临时有序节点(这个可以通过节点的属性控制:CreateMode.EPHEMERAL_SEQUENTIAL来指定)
      • Zk的父节点(/distribute_lock)维持一份sequence,保证子节点创建的时序性,从而也形成了每个客户端的全局时序
  • 分布式队列
    • 队列方面,简单地讲有两种,一种是常规的先进先出队列,另一种是要等到队列成员聚齐之后的才统一按序执行(屏障/Barrier)
    • 先进先出队列(FIFO),和分布式锁服务中的控制时序场景基本原理一致
    • 等到队列成员聚齐之后的才统一按序执行屏障(Barrier)
      • 类似Java多线程的CyclicBarrier
      • 第二种队列其实是在FIFO队列的基础上作了一个增强
      • 通常可以在 /queue 这个znode下预先建立一个/queue/num 节点,并且赋值为n(或者直接给/queue赋值n),表示队列大小,之后每次有队列成员加入后,就判断下是否已经到达队列大小,决定是否可以开始执行了
      • 这种用法的典型场景是,分布式环境中,一个大任务Task A,需要在很多子任务完成(或条件就绪)情况下才能进行。这个时候,凡是其中一个子任务完成(就绪),那么就去 /taskList建立自己的临时时序节点(CreateMode.EPHEMERAL_SEQUENTIAL),当 /taskList 发现自己下面的子节点满足指定个数,就可以进行下一步按序进行处理了
3,ZooKeeper原理
  • 数据模型
    • ZooKeeper数据模型的结构与Unix文件系统很类似,整体上可以看作是一棵树,每个节点称做一个ZNode
    • 每个ZNode都可以通过其路径唯一标识
    • 每个ZNode上可存储少量数据(默认是1M, 可以通过配置修改, 通常不建议在ZNode上存储大量的数据)
    • 每个ZNode上还存储了其Acl信息
    • 每个ZNode的Acl的独立的,子结点不会继承父结点的
  • ZNode
    • 持久性分类
      • Regular ZNode: 常规型ZNode, 用户需要显式的创建、删除
      • Ephemeral ZNode: 临时型ZNode, 用户创建它之后,可以显式的删除,也可以在创建它的Session结束后,由ZooKeeper Server自动删除
      • ZNode还有一个Sequential的特性,如果创建的时候指定的话,该ZNode的名字后面会自动Append一个不断增加的SequenceNo
    • 细分
      • PERSISTENT-持久化目录节点:客户端与zookeeper断开连接后,该节点依旧存在
      • PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点:客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号
      • EPHEMERAL-临时目录节点:客户端与zookeeper断开连接后,该节点被删除
      • EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点:客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号
  • Session
    • ClientZooKeeper之间的通信,需要创建一个Session,这个Session会有一个超时时间
    • 因为ZooKeeper集群会把Client的Session信息持久化,所以在Session没超时之前,Client与ZooKeeper Server的连接可以在各个ZooKeeper Server之间透明地移动
    • 在实际的应用中,如果Client与Server之间的通信足够频繁,Session的维护就不需要其它额外的消息了,否则,ZooKeeper Client会每t/3 ms发一次心跳给Server,如果Client 2t/3 ms没收到来自Server的心跳回应,就会换到一个新的ZooKeeper Server上。这里t是用户配置的Session的超时时间
  • Zab协议
    • Zookeeper 的核心是原子广播,这个机制保证了各个Server之间的同步
    • Zab协议有两种模式,它们分 别是恢复模式(选主)广播模式(同步)
    • 当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和 leader的状态同步以后,恢复模式就结束了
    • 状态同步保证了leader和Server具有相同的系统状态
    • 为 了保证事务的顺序一致性,zookeeper采用了递增的事务id号(zxid)来标识事务。所有的提议(proposal)都在被提出的时候加上 了zxid。实现中zxid是一个64位的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的统治时期。低32位用于递增计数
  • Leader(选举)选主流程
    • 基于fast paxos算法实现
      • 原则:在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点都执行相同的操作序列,那么他们最后能得到一个一致的状态
      • Paxos解决的就是保证每个节点执行相同的操作序列
    • 数据一致性与paxos算法
    • ZooKeeper三个角色
      • Leader:进行投票发起决议更新系统状态
      • Learner
        • Follower
          • 用于接受客户请求向客户端返回结果
          • 在选主过程中参与投票
        • Observer
          • 可以接受客户端连接,将写请求转发给Leader节点
          • Observer不参与投票过程只同步Leader的状态
          • Observer的目的是为了扩展系统,提高读取速度
      • Client
        • Curator
          • Recipes
            • Elections
              • Leader Latch
              • Leader Election
            • Locks
              • Shared Reentrant Lock
              • Shared Lock
              • Shared Reentrant Read Write Lock
              • Shared Semaphore
              • Multi Shared Lock
            • Barriers
              • Barrier
              • Double Barrier
            • Counters
              • Shared Counter
              • Distributed Atomic Long
            • Caches
              • Path Cache
              • Node Cache
              • Tree Cache
            • Nodes
              • Persistent Ephemeral Node
            • Queues
              • Distributed Queue
              • Distributed Id Queue
              • Distributed Priority Queue
              • Distributed Delay Queue
              • Simple Distributed Queue
          • Framework
          • Utilities
          • Client
          • Errors
          • Extensions
        • ZooKeeper
0 0
原创粉丝点击