ZooKepper

1 minute read

Published:

This is my personal notes for ZooKepper.

ZooKepper简介

ZooKeeper是一个分布式服务协调框架,可以用来维护分布式配置信息、服务注册中心、实现分布式锁等。在Hbase、Hadoop、kafka等项目中都有广泛的应用。随着分布式、微服务的普及,ZooKeeper已经成为我们日常开发工作中无法绕过的一环。
比如zookeeper的节点可以链接两台服务器(客户端和管理后端),一个是生产者一个是消费者,当生产者发生一个事件(增加节点),消费者通过监听获得事件信息,通过zk节点中的数据在消费者一端执行相应的操作,可以实现两个服务器的同步。

安装并本地启动ZooKepper

下载地址
1 下载3.4.14 (tar.gz文件), 解压到本地目录, 如(/Users/luolingwei/Application/zookepper)
2 配置环境变量 (vim .bash_profile)
加上以下内容, Zookepper需要Java编译, 所以会加上JAVA_HOME

export ZOOKEPPER_HOME=/Users/luolingwei/Application/zookepper
export PATH=$PATH:$ZOOKEPPER_HOME/bin:$JAVA_HOME/bin

3 复制conf目录下的”zoo_sample.cfg”并改名为”zoo.cfg”, 使其可默认找到
4 进入bin目录
./zkServer.sh start, 出现以下内容即启动成功

ZooKeeper JMX enabled by default
Using config: /Users/luolingwei/Application/zookepper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

常用命令

在bin目录下使用 ./zkCli.sh进入zookepper命令行, 按回车跳过watcher
出现[zk: localhost:2181(CONNECTED) 0]即进入zookepper命令行

ls / 显示当前所有节点
create /minitest hellomini 创建minitest节点并设置数据为hellomimi
get /minitest 获取minitest节点中的数据
set /minitest updatenew 更新节点中的数据, dataVersion会+1
delete /minitest 删除minitest节点

常见错误

1 报错 Could not find or load main class org.apache.zookeeper.server.quorum.
解决: 下载含有src目录和jar文件(如zookeeper-3.4.14.jar)的版本

2 找不到配置文件: ZooKeeper JMX enabled by default Using config: ./conf/zoo.cfg Starting zookeeper … FAILED TO START
解决: 复制conf目录下的”zoo_sample.cfg”并改名为”zoo.cfg”, 或者启动时直接指定配置文件路径

3 报错查看: ./zkServer.sh start-foreground

ZooKepper如何保证数据一致性–ZAB协议

ZAB 中三个主要的角色: Leader 领导者、Follower跟随者、Observer观察者 。

  • Leader :集群中 唯一的写请求处理者 ,能够发起投票(投票也是为了进行写请求)。
  • Follower:能够接收客户端的请求,如果是读请求则可以自己处理,如果是写请求则要转发给 Leader 。在选举过程中会参与投票,有选举权和被选举权 。
  • Observer :就是没有选举权和被选举权的 Follower 。

在 ZAB 协议中对 zkServer(即上面我们说的三个角色的总称) 还有两种模式的定义,分别是 消息广播崩溃恢复


  • 消息广播模式

    说白了就是 ZAB 协议是如何处理写请求的,因为只有 Leader 能处理写请求, 但是我们的 Follower 和 Observer 也需要 同步更新数据。第一步需要 Leader 将写请求 广播 出去,让 Leader 问问 Followers 是否同意更新,如果超过半数以上的同意那么就进行 Follower 和 Observer 的更新

    这两个 Queue 是干什么的?—-是 ZAB 需要让 Follower 和 Observer 保证顺序性 。

avatar

  • 崩溃恢复模式

    • leader选举算法

      说到崩溃恢复首先要提到 ZAB 中的 Leader 选举算法,当系统出现崩溃影响最大应该是 Leader 的崩溃,因为我们只有一个 Leader ,所以当 Leader 出现问题的时候我们势必需要重新选举 Leader 。

      Leader 选举可以分为两个不同的阶段,第一个是 Leader 宕机需要重新选举,第二则是当 Zookeeper 启动时需要进行系统的 Leader 初始化选举。

      流程:

      没有leader的时候集群处于Looking状态,需要投票选leader

      • 1 每一个server启动后先给自己投票(myid,ZXID), 然后将这个投票信息广播给其他的server
      • 2 其他server收到广播后, 将ZXID与自己的比较, 如果自己的ZXID小, 把自己的投票信息改为别人的, 再广播出去(ZXID相同比较myid)
      • 3 当某个server发现其收到的投票数超过半数时, 其成为leader, 集群状态变为following正常状态
      • 4 当某个server进来系统没有在Looking状态时, 直接以follwer身份加入集群
    • 崩溃恢复

      当集群中有机器挂了,整个集群如何保证数据一致性?

      如果只是 Follower 挂了,而且挂的没超过半数的时候,因为 Leader 会维护队列,所以不用担心后面的数据没接收到导致数据不一致性。

      如果 Leader 挂了那就麻烦了,需要先暂停服务变为 Looking 状态然后进行 Leader 的重新选举, 这里要分为两种情况了,分别是

      1 确保已经被Leader提交的提案最终能够被所有的Follower提交

      假设 Leader (server2) 发送 commit 请求),他发送给了 server3,然后要发给 server1 的时候突然挂了。这个时候重新选举的时候我们如果把 server1 作为 Leader 的话,那么肯定会产生数据不一致性,因为 server3 肯定会提交刚刚 server2 发送的 commit 请求的提案,而 server1 根本没收到所以会丢弃。

      avatar

      2 跳过那些已经被丢弃的提案

      假设 Leader (server2) 此时同意了提案N1,自身提交了这个事务并且要发送给所有 Follower 要 commit 的请求,却在这个时候挂了,此时肯定要重新进行 Leader 的选举,比如说此时选 server1 为 Leader (这无所谓)。但是过了一会,这个 挂掉的 Leader 又重新恢复了 ,此时它肯定会作为 Follower 的身份进入集群中,需要注意的是刚刚 server2 已经同意提交了提案N1,但其他 server 并没有收到它的 commit 信息,所以其他 server 不可能再提交这个提案N1了,这样就会出现数据不一致性问题了,所以 该提案N1最终需要被抛弃掉 。

      avatar