• Zookeeper


    概述

    Zookeeper字面上理解就是动物管理员,是大数据框架Hadoop生态圈中的一个服务中间件,Hadoop生态圈中很多开源项目使用动物命名,那么需要一个管理员来管理这些“动物”。他负责分布式应用程序协调的工作。

    img

    Hadoop框架

    Zookeeper主要提供以下四点功能:统一命名服务、配置管理、集群管理、共享锁和队列管理,用于高效的管理集群的运行。
    Zookeeper通过心跳机制可以检测挂掉的机器并将挂掉机器的ip和服务对应关系从列表中删除。
    Zookeeper 部署有三种方式,单机模式、集群模式、伪集群模式,以下采用Docker 的方式部署

    注意: 集群为大于等于3个奇数,如 3、5、7,不宜太多,集群机器多了选举和数据同步耗时长,不稳定。

    zk安装

    docker-compose-yml

    version: '3.1'
    
    services:
        zoo1:
            image: zookeeper
            restart: always
            hostname: zoo1
            ports:
                - 2181:2181
            environment:
                ZOO_MY_ID: 1
                ZOO_SERVERS: server.1=zoo1:2888:3888
    配置说明
    
    • 2181:客户端连接 Zookeeper 集群使用的监听端口号
    • 3888:选举 leader 使用
    • 2888:集群内机器通讯使用(Leader 和 Follower 之间数据同步使用的端口号,Leader 监听此端口)

    验证是否安装成功

    • 以交互的方式进入容器
    docker exec -it zookeeper_zoo1_1 /bin/bash
    
    • 使用客户端连接到服务端
    bash-4.3# ./bin/zkCli.sh
    Connecting to localhost:2181
    
    • 使用服务端工具检查服务器状态
    bash-4.3# ./bin/zkServer.sh status
    ZooKeeper JMX enabled by default
    Using config: /conf/zoo.cfg
    Mode: standalone
    

    ZK集群安装

    可以参考这个网页
    https://www.cnblogs.com/kingkoo/p/8732448.html

    ZK常用命令

    命令 作用 示例
    help 查看zk命令清单 help
    ls 列出文件及目录 ls /
    create 创建节点 create /test "bb"、create -e /test/e1 "bb"
    get 获取节点信息 get /test/e1
    set 修改节点内容 set /aa haha123
    delete 删除节点 delete /test
    通过上面的命令操作,我们不难看出ZK是通过一个特殊的文件系统,帮我们系统分布式系统间的协调。
    
    • 原则性:根据文件系统的原子性,同一个目录下不能创建2个相同的文件
    • 独特性:可以创建跟客户端绑定的临时文件
    服务器命令
    ./zkServer.sh start  //启动服务
    ./zkServer.sh stop   //停止服务
    ./zkServer.sh restart //重启服务器
    ./zkServer.sh         //执行状态
    

    注:Zookeeper不能用于存放大量的数据,每个节点的存放数据上限为1M

    什么是分布式锁

    为了防止分布式系统中的多个进程之间相互干扰,我们需要一种分布式协调技术来对这些进程进行调度。而这个分布式协调技术的核心就是来实现这个分布式锁
    比如:12306抢票,10W人抢同一张火车票。这个时候用户并发数已经超过了mysql所能承受的极限,无法再用数据库实现分布式锁,必须通过zk等来实现。

    分布式锁的实现有哪些

    • Memcached:利用 Memcached 的 add 命令。此命令是原子性操作,只有在 key 不存在的情况下,才能 add 成功,也就意味着线程得到了锁。
    • Redis:和 Memcached 的方式类似,利用 Redis 的 setnx 命令。此命令同样是原子性操作,只有在 key 不存在的情况下,才能 set 成功。
    • Zookeeper:利用 Zookeeper 的顺序临时节点,来实现分布式锁和等待队列。Zookeeper 设计的初衷,就是为了实现分布式锁服务的。
    • Chubby:Google 公司实现的粗粒度分布式锁服务,底层利用了 Paxos 一致性算法。

    Zookeeper 的数据模型

    Zookeeper 的数据模型是什么样子呢?它很像数据结构当中的树,也很像文件系统的目录。

    img

    Zookeeper 的数据模型

    树是由节点所组成,Zookeeper 的数据存储也同样是基于节点,这种节点叫做 Znode

    但是,不同于树的节点,Znode 的引用方式是路径引用,类似于文件路径:

    /动物/猫
    /汽车/宝马
    

    这样的层级结构,让每一个 Znode 节点拥有唯一的路径,就像命名空间一样对不同信息作出清晰的隔离。

    Znode 包含哪些元素

    img

    Znode元素

    • data:Znode 存储的数据信息。
    • ACL:记录 Znode 的访问权限,即哪些人或哪些 IP 可以访问本节点。
    • stat:包含 Znode 的各种元数据,比如事务 ID、版本号、时间戳、大小等等。
    • child:当前节点的子节点引用

    这里需要注意一点,Zookeeper 是为读多写少的场景所设计。Znode 并不是用来存储大规模业务数据,而是用于存储少量的状态和配置信息,每个节点的数据最大不能超过 1MB

    Zookeeper 的事件通知

    Zookeeper 客户端在请求读操作的时候,可以选择是否设置 Watch。我们可以把 Watch 理解成是注册在特定 Znode 上的触发器。当这个 Znode 发生改变,也就是调用了 createdeletesetData 方法的时候,将会触发 Znode 上注册的对应事件,请求 Watch 的客户端会接收到异步通知。

    具体交互过程如下:

    • 客户端调用 getData 方法,watch 参数是 true。服务端接到请求,返回节点数据,并且在对应的哈希表里插入被 Watch 的 Znode 路径,以及 Watcher 列表。

    img

    image

    • 当被 Watch 的 Znode 已删除,服务端会查找哈希表,找到该 Znode 对应的所有 Watcher,异步通知客户端,并且删除哈希表中对应的 Key-Value。

    img

    image

    Zookeeper 的一致性

    Zookeeper 身为分布式系统协调服务,如果自身挂了如何处理呢?为了防止单机挂掉的情况,Zookeeper 维护了一个集群。如下图:

    img

    image

    Zookeeper Service 集群是一主多从结构。

    在更新数据时,首先更新到主节点(这里的节点是指服务器,不是 Znode),再同步到从节点。

    在读取数据时,直接读取任意从节点。

    为了保证主从节点的数据一致性,Zookeeper 采用了 ZAB 协议,这种协议非常类似于一致性算法 PaxosRaft

    什么是 ZAB

    Zookeeper Atomic Broadcast,有效解决了 Zookeeper 集群崩溃恢复,以及主从同步数据的问题。

    ZAB 协议定义的三种节点状态

    • Looking :选举状态。
    • Following :Follower 节点(从节点)所处的状态。
    • Leading :Leader 节点(主节点)所处状态。

    最大 ZXID

    最大 ZXID 也就是节点本地的最新事务编号,包含 epoch 和计数两部分。epoch 是纪元的意思,相当于 Raft 算法选主时候的 term。

    ZAB 的崩溃恢复

    假如 Zookeeper 当前的主节点挂掉了,集群会进行崩溃恢复。ZAB 的崩溃恢复分成三个阶段:

    Leader election

    选举阶段,此时集群中的节点处于 Looking 状态。它们会各自向其他节点发起投票,投票当中包含自己的服务器 ID 和最新事务 ID(ZXID)。

    img

    image

    接下来,节点会用自身的 ZXID 和从其他节点接收到的 ZXID 做比较,如果发现别人家的 ZXID 比自己大,也就是数据比自己新,那么就重新发起投票,投票给目前已知最大的 ZXID 所属节点。

    img

    image

    每次投票后,服务器都会统计投票数量,判断是否有某个节点得到半数以上的投票。如果存在这样的节点,该节点将会成为准 Leader,状态变为 Leading。其他节点的状态变为 Following。

    img

    image

    Discovery

    发现阶段,用于在从节点中发现最新的 ZXID 和事务日志。或许有人会问:既然 Leader 被选为主节点,已经是集群里数据最新的了,为什么还要从节点中寻找最新事务呢?

    这是为了防止某些意外情况,比如因网络原因在上一阶段产生多个 Leader 的情况。

    所以这一阶段,Leader 集思广益,接收所有 Follower 发来各自的最新 epoch 值。Leader 从中选出最大的 epoch,基于此值加 1,生成新的 epoch 分发给各个 Follower。

    各个 Follower 收到全新的 epoch 后,返回 ACK 给 Leader,带上各自最大的 ZXID 和历史事务日志。Leader 选出最大的 ZXID,并更新自身历史日志。

    Synchronization

    同步阶段,把 Leader 刚才收集得到的最新历史事务日志,同步给集群中所有的 Follower。只有当半数 Follower 同步成功,这个准 Leader 才能成为正式的 Leader。

    自此,故障恢复正式完成。

    选举原理总结
      1. 每个 server 发出一个投票: 投票的最基本元素是(SID-服务器id,ZXID-事物id)
      1. 接受来自各个服务器的投票
        处理投票:优先检查 ZXID(数据越新ZXID越大),ZXID比较大的作为leader,ZXID一样的情况下比较SID
      1. 统计投票:这里有个过半的概念,大于集群机器数量的一半,即大于或等于(n/2+1),我们这里的由三台,大于等于2即为达到“过半”的要求。这里也有引申到为什么 Zookeeper 集群推荐是单数。
    Zookeeper同步流程

    选完Leader以后,zk就进入状态同步过程。
    1、Leader等待server连接;
    2、Follower连接leader,将最大的zxid发送给leader;
    3、Leader根据follower的zxid确定同步点;
    4、完成同步后通知follower 已经成为uptodate状态;
    5、Follower收到uptodate消息后,又可以重新接受client的请求进行服务了。

    Java三种ZooKeeper客户端比较

    原生 zkClient Curator
    直接使用Zookeeper原生API的人并不多,因为: 1)连接的创建是异步的,需要开发人员自行编码实现等待 2)连接没有超时自动的重连机制 3)Zookeeper本身没提供序列化机制,需要开发人员自行指定,从而实现数据的序列化和反序列化 4)Watcher注册一次只会生效一次,需要不断的重复注册 5)Watcher的使用方式不符合java本身的术语,如果采用监听器方式,更容易理解 6)不支持递归创建树形节点 ZkClient是Github上的一个开源Zookeeper客户端,是由Datameer工程师Stefan Groschupf和Peter Voss一起开发。ZkClient在原生Zookeeper api的基础上进行封装,是一个更易用的客户端,解决和如下问题: 1)session会话超时重连 2)解决Watcher反复注册 3)简化API开发 Curator是Netflix公司开源的一套Zookeeper客户端框架,作者是Jordan Zimmerman。Curator解决除了ZkClient提供的功能外,新增如下功能: 1)提供了一套Fluent风格的客户端API框架。 2)提供了各种应用场景(Recipe,如共享锁服务、Master选举机制和分布式计数器)的抽样封装。
  • 相关阅读:
    Android 中adb 命令(实用)
    Mac安装Scala
    使用阿里云镜像maven管理配置开发环境
    Nginx学习笔记3--Nginx和PHP(fastCGI)的配置和优化
    《实战Nginx》读书笔记--Nginx配置文件
    《实战Nginx》读书笔记
    PHP解码unicode编码中文字符代码
    yii学习笔记--使用gii快速创建控制器和模型
    yii学习笔记--配置文件的配置
    yii学习笔记--快速创建一个项目
  • 原文地址:https://www.cnblogs.com/snake107/p/11938914.html
Copyright © 2020-2023  润新知