Zookeeper

作者: 墨小雨的猫 | 来源:发表于2020-02-20 01:13 被阅读0次

    一、What

    • 一个主从架构的分布式框架
    • 给分布式框架提供协调服务(service)

    作用

    • 提供简版文件系统来存储数据
    • 维护和监控存储的数据状态变化,通过监控数据状态变化达到基于数据的集群管理
    • 主要用来解决分布式集群中应用系统的一致性问题

    应用场景

    1. 主备切换
    2. 节点的上下线感知
    3. 统一命名服务
    4. 状态同步服务
    5. 集群管理
    6. 分布式应用配置管理
    

    二、基本概念

    ZooKeeper=简版文件系统(Znode)+原语+通知机制(Watcher)

    • ZK文件系统
      基于类似于文件系统的目录节点树方式的数据存储
    • 原语
      提供类linux指令进行操作
    • Watcher(监听器)

    数据节点ZNode

    数据节点本质就是目录

    持久节点 临时节点
    非有序节点 create create -e
    有序节点 create -s create -s -e
    1. 持久节点(无序)
      节点创建以后,即便连接断开,除非主动删除,不然会一直存在
    2. 持久节点(有序)
      创建节点的时候加上 -s ,会默认的在目录后加上数字
      防止同一目录创建同名ZNode导致失败
    3. 临时节点(无序)
      节点创建以后,一旦连接断开会自动删除
      创建节点的时候通过 -t 指定
    4. 持久节点(有序)
      同上

    会话

    与zk交互时会建立TCP长连接,称为会话
    建立会话后,如果超过SessionTimeout时间,两者间没有通信,会话超时
    特点:同一个会话里执行的指令是有序的;不同会话之间的指令是无序的

    事务zxid

    • 每个对数据的增删改操作都会生成一个对应的zxid
    • zxid全局唯一,并且是自增的
    • zxid通常是由64位数字,epoch+counter组成

    Watch监视与通知

    方式一(轮询):ZooKeeper以远程服务的方式,被客户端访问;客户端以轮询的方式获得znode数据,效率会比较低(代价比较大)

    方式二(通知机制):客户端在znode上注册一个Watcher监视器,当znode上数据出现变化,watcher监测到此变化,通知客户端

    1. Watch作用流程
    • 客户端在服务器端,注册的事件监听器
    • watcher用于监听znode上的某些事件
    • 比如znode数据修改、节点增删等
    • 当监听到事件后,watcher会触发通知客户端
    1. 节点上下线原理
      ① 节点1(client1)创建临时节点
      ② 节点2(client2)在临时节点,注册监听器watcher
      ③ 当client1与zk集群断开连接,临时节点会被删除
      ④ watcher发送消息,通知client2,临时节点被删除的事件
      用到的zk特性:Watcher+临时节点
      好处:通过这种方式,检测和被检测系统不需要直接关联(如client1与client2),而是通过ZK上的某个节点进行关联,大大减少了系统耦合

    三、HDFS HA方案

    工作原理

    ZooKeeper使用原子广播协议叫做Zab(ZooKeeper Automic Broadcast)协议

    • Zab协议有两种模式
      • 恢复模式(选主):因为ZooKeeper是主从架构;当ZooKeeper集群没有主的角色leader时,从众多服务器中选举leader时,处于此模式
      • 广播模式(同步):当集群有了leader后,客户端向ZooKeeper集群读写数据时,集群处于此模式
    • 为了保证事务的顺序一致性,ZooKeeper采用了递增的事务id号(zxid)来标识事务,所有提议(proposal)都有zxid

    监听器

    • 注册:客户端向ZooKeeper集群注册监听器

    • 监听事件:监听器负责监听特定的事件

    • 回调函数:当监听器监听到事件的发生后,调用注册监听器时定义的回调函数

    HA原理

    HDFS HA方案,主要分两部分:

    ①元数据同步

    • 在同一个HDFS集群,运行两个互为主备的NameNode节点。
    • 一台为主Namenode节点,处于Active状态,一台为备NameNode节点,处于Standby状态。
    • 只有Active NameNode对外提供读写服务,Standby NameNode会根据Active NameNode的状态变化,在必要时切换成Active状态。
    • JournalNode集群
      • 在主备切换过程中,新的Active NameNode必须确保与原Active NamNode元数据同步完成,才能对外提供服务
      • 所以用JournalNode集群作为共享存储系统;
      • 当客户端对HDFS做操作,会在Active NameNode中edits.log文件中作日志记录,同时日志记录也会写入JournalNode集群;负责存储HDFS新产生的元数据
      • 当有新数据写入JournalNode集群时,Standby NameNode能监听到此情况,将新数据同步过来
      • Active NameNode(写入)和Standby NameNode(读取)实现元数据同步
      • 另外,所有datanode会向两个主备namenode做block report

    ②主备切换

    • 每个NameNode节点上各有一个ZKFC进程
    • ZKFC即ZKFailoverController,作为独立进程存在,负责控制NameNode的主备切换
    • ZKFC会监控NameNode的健康状况,当发现Active NameNode异常时,通过Zookeeper集群进行namenode主备选举,完成Active和Standby状态的切换
      • ZKFC在启动时,同时会初始化HealthMonitor和ActiveStandbyElector服务
      • ZKFC同时会向HealthMonitor和ActiveStandbyElector注册相应的回调方法(如上图的①回调、②回调)
      • HealthMonitor定时调用NameNode的HAServiceProtocol RPC接口(monitorHealth和getServiceStatus),监控NameNode的健康状态,并向ZKFC反馈
      • ActiveStandbyElector接收ZKFC的选举请求,通过Zookeeper自动完成namenode主备选举
      • 选举完成后回调ZKFC的主备切换方法对NameNode进行Active和Standby状态的切换

    主备切换过程

    • ① 启动NameNode,ZKFC,此时两个NameNode的状态都是竞选状态
    • ② 两个ZKFC分别通过ActiveStandbyElector发起NameNode的选举
      通过zookeeper的写一致性以及临时节点来实现
    • ③ 发起主备选举的时候,ActiveStandbyElector会尝试在zookeeper的某个目录下创建一个临时节点,zookeeper的写一致性会保证只有一个节点创建成功
    • ④ 创建成功的ActiveStandbyElector通过回调方式通知ZKFC,将对应的NameNode切换为Active状态;创建失败的也通过同样方式将NameNode切换为Standby状态
    • ⑤ 无论是否创建成功,这些ActiveStandbyElector都会监听那个目录;
      当Active NameNode对应的HealthMonitor监控到NameNode异常时,会告知ZKFC,ZKFC通过ActiveStandbyElector删除所创建的临时节点,以及目录A
      若是ZKFC是因为异常断开的连接,那么目录A还会存在
    • ⑥ 此时处于Standby的NameNode会监控到这个消息
      它首先会通过判断目录A是否存在来确认情况
      如果是正常关闭的,则发起主备选举,成功创建临时节点,并且将NameNode的状态切换为Active
      如果是异常关闭的,则会
      1、通过RPC调用,试图让之前的Active的NameNode切换为StandBy
      2、隔离:① 发送kill指令 ② 使用hadoop的隔离方式

    脑裂
    在分布式系统中双主现象又称为脑裂,由于Zookeeper的“假死”、长时间的垃圾回收或其它原因都可能导致双Active NameNode现象,此时两个NameNode都可以对外提供服务,无法保证数据一致性

    • 隔离
      对于生产环境,这种情况的出现是毁灭性的,必须通过自带的隔离(Fencing)机制预防此类情况
    • 原理
      • ActiveStandbyElector成功创建ActiveStandbyElectorLock临时节点后,额外创建一个ActiveBreadCrumb持久节点

      • ActiveBreadCurmb持久节点保存Active NameNode的服务器信息

      • 当Active NameNode正常状态下断开与Zookeeper Session,会一并删除临时节点ActiveStandbyElectorLock和ActiveBreadCurmb持久节点

      • 如果是异常断开的,那么此时临时节点ActiveStandbyElectorLock不存在,但是ActiveBreadCurmb持久节点还存在;Standby节点会收到监听器发来的提醒将要从Standby切换成Active时,会先通过ActiveBreadCurmb里的服务器信息做隔离
        1、通过RPC调用,试图让之前的Active的NameNode切换为StandBy
        2、隔离(hadoop提供这两种隔离):① 发送kill指令 ② 使用hadoop的隔离方式

        只有成功地fencing之后,选主成功的ActiveStandbyElector才会回调ZKFC的becomeActive方法transitionToActive将对应的NameNode切换为Active,开始对外提供服务

    四、Zookeeper架构

    ZooKeeper服务器四种状态:

    • looking:服务器处于寻找Leader群首的状态

    • leading:服务器作为群首时的状态

    • following:服务器作为follower跟随者时的状态

    • observing:服务器作为观察者时的状态

    1、安其内

    全新leader选举(重启集群)
    原则:集群超过半数的服务器启动后,才能选出leader
    选举规则:

    1. 初始化:每个节点都投自己一票,然后向其他所有节点发送自己票的信息
    2. 交换投票信息:接收其他节点的选举信息,与自己的那票进行比较
      投票信息vote信息结构为(serverId, zxid)
      会先比较zxid,zxid大的那台服务器胜出(zxid越大意味存储了更多的数据)
      若是zxid相同则serverId大的那台服务器会胜出
      比较结束后,每台服务器会更新自己的投票信息,继续给其他服务器发送
    3. 决定投票结果:假设服务器B接收到超过半数的票选举自己,则自己从looking切换为leading,其他服务器从looking切换为following
    4. 当服务器C启动时,发现已有Leader,不再选举,直接从Looking改为Following

    全新leader选举(leading挂掉或者出现网络分区)

    攘其外

    读操作

    • 常见的读取操作,如ls /查看目录;get /zktest查询ZNode数据
    • 读操作
      • 客户端先与某个zk任意一台服务器建立Session
      • 然后,直接从此ZK服务器读取数据,并返回客户端即可
      • 关闭Session

    写操作

    • ① 与zk任意一台服务器建立Session建立连接
    • ② follower将写请求转发给leader(不执行)
    • ③ leader收到消息后,发起proposal提案
    • ④ 每台服务器都会收到proposal后会记录这次操作并向leader返回同意,但不执行
    • ⑤ 超过半数quorum同意,则leader提交commit提案,leader执行该操作
    • ⑥ leader通知所有节点也commit提交该提案;所有节点在所在服务器执行该操作
    • ⑦ client连接的那台follower响应Client

    五、原理

    quorum仲裁

    • 什么是仲裁quorum?
      • 发起proposal时,只要多数派同意,即可生效
    • 为什么要仲裁?
      • 多数据派不需要所有的服务器都响应,proposal就能生效
      • 提高集群的响应速度
    • quorum数如何选择?
      • 集群节点数 / 2 + 1

    为什么集群节点数强烈建议奇数个?
    5节点的比6节点的集群

    • 容灾能力一样,
    • quorum小,响应快
    • 偶数个如果被网络分区平分,则不能提供服务

    网络分区和脑裂

    • 网络分区:网络通信故障,集群被分成了2部分
    • 脑裂:
      • 原leader处于一个分区;
      • 另外一个分区选举出新的leader
      • 集群出现2个leader

    ZAB算法

    1. 每个节点都有一个计时器(150毫秒~300毫秒之间的随机数),时间到后会发起选举的操作

    2. 非leader节点会定时的向leader节点发送心跳,leader收到心跳后会返回信息,非leader节点收到这个信息后会重置计时器

    3. 当发生网络分区并且leader处于少数的那边时,其他follower会进行选举,假设B服务器选举成功,那么它会和其他follower进行zxid的比较

      ① 假设服务器C的zkid比服务器B的少10个,那么服务器B会将这十个操作封包发给服务器C来执行
      ② 假设服务器D的zxid比服务器B多10个,那么服务器B会让它将这十个记录都删除
      做完以上操作后,服务器B才会从follower切换成leader,并且将epoch里的值进行加1,zxid进行重置

    4. 当网络恢复了之后,旧leader比较路径下的epoch值的时候,发现已经有新的leader产生,会将自己切换成follower,并且进行数据的同步

    状态同步

    完成选举后,zk之间会进行状态同步操作

      1. leader构建NEWLEADER封包,包含leader最大zxid值,广播给其他follower
      1. follower收到后会跟自己最大zxid比较,若是比它小则进行同步操作
      1. leader给每个需要同步的follower创建LearnerHandler同步线程,负责进行同步操作
      1. leader主线程等待LearnerHandler线程处理结果
      1. 只有当大部分follower完成同步,该集群才对外提供服务,相应写请求
      1. LearnerHandler线程处理逻辑
        1. 接收follower封包FOLLOWERINFO,包含此follower最大zxid(代称f-max-zxid)
        1. f-max-zxid与leader最大zxid(代称l-max-zxid)比较
        1. 若相等,说明当前follower是最新的
        1. 另外,若在判断期间,有没有新提交的proposal
          1. 如果有,那么会发送DIFF封包将有差异的数据同步过去.同时将follower没有的数据逐个发送COMMIT封包给follower要求记录下来.
          1. 如果follower数据id更大,那么会发送TRUNC封包告知截除多余数据.
          1. 如果这一阶段内没有提交的提议值,直接发送SNAP封包将快照同步发送给follower.
        1. 以上消息完毕之后,发送UPTODATE封包告知follower当前数据就是最新的了
        1. 再次发送NEWLEADER封包宣称自己是leader,等待follower的响应.

    分布式锁

      1. 所有需要获取锁的引用都在 /locker路径下创建一个有序临时节点
      1. 该路径下序号最小的应用获取该锁,其他应用分别监视比自己小一点的那个ZNode
      1. 当序号最小的那个应用操作完后,断开连接时,比它稍微大一点的那个应用会获取锁

    分布式锁主要是应用了zk的一致性、临时节点、watch监视器这几个特性来保证的

    WHO

    1. NameNode使用ZooKeeper实现高可用.
    2. Yarn ResourceManager使用ZooKeeper实现高可用.
    3. 利用ZooKeeper对HBase集群做高可用配置
    4. kafka使用ZooKeeper(仅限0.9以及之前版本)
      • 保存消息消费信息比如offset.
      • 用于检测崩溃
      • 主题topic发现
      • 保持主题的生产和消费状态

    常用操作

    # 使用ZooKeeper自带的脚本,连接ZooKeeper的服务器
    zkCli.sh -server node01:2181,node02:2181,node03:2181
    
    #创建节点,并指定数据(必须要指定数据)
    create /kkb kkb
    

    相关文章

      网友评论

          本文标题:Zookeeper

          本文链接:https://www.haomeiwen.com/subject/lrkofhtx.html