zoukankan      html  css  js  c++  java
  • Zookeeper



    学习Dubbo需要用到注册中心,前来学习


    1. 概述

    ZooKeeper本身是分布式的,是一个为分布式应用提供协调服务的一个Apache项目,常用于注册中心

    底层基于观察者模式设计,主要负责存储和管理数据并且接收观察者的注册,数据更新时通知观察者


    1.1 特点

    • 可组成集群:一个Leader,多个Follower
    • 集群中半数以上节点存活,Zookeeper集群才能正常服务
    • 全局数据一致,集群每个数据内容都一致
    • 更新请求顺序进行:来自同一个Client的更新请求按其发送顺序依次执行
    • 数据更新原子性:集群集群都成功应用了某个事务
    • 实时性:一定时间范围内能读取到最新的数据,也是ZK突出的特点

    1.2 数据结构

    ZK的数据模型和Linux的文件系统类似,整体看成一棵树,每个节点称为ZNode。每一个ZNode默认可存储1MB的数据,每个ZNode通过其路径唯一标识,其主要用于协调服务,而不是存储数据


    1.2.1 节点类型分为:

    • 持久(Persistent)型,客户端和服务器断开连接,创建的节点不删除
    • 持久顺序型(Persistent_Sequential),在持久性基础上,名字中添加了序号
    • 短暂型(Ephemeral),客户端和服务器断开连接,创建的节点自己删除,并且只能做叶子节点,不能创建子节点
    • 短暂顺序型(Ephemeral_Sequential),同理


    1.2.2 节点数据分为:

    • stat :状态信息
    • data :节点存放的数据的具体内容
    [zk: 127.0.0.1:2181(CONNECTED) 0] get /dubbo
    
    # data 存放的数据
    192.168.XXX.XXX		
    
    # stat 格式化输出有下表内容
    
    node 状态信息 解释
    cZxid create ZXID,即该数据节点被创建时的事务 id
    ctime create time,即该节点的创建时间
    mZxid modified ZXID,即该节点最终一次更新时的事务 id
    mtime modified time,即该节点最后一次的更新时间
    pZxid 该节点的子节点列表最后一次修改时的事务 id,只有子节点列表变更才会更新 pZxid,子节点内容变更不会更新
    cversion 子节点版本号,当前节点的子节点每次变化时值增加 1
    dataVersion 数据节点内容版本号,节点创建时为 0,每更新一次节点内容(不管内容有无变化)该版本号的值增加 1
    aclVersion 节点的 ACL 版本号,表示该节点 ACL 信息变更次数
    ephemeralOwner 创建该临时节点的会话的 sessionId;如果当前节点为持久节点,则 ephemeralOwner=0
    dataLength 数据节点内容长度
    numChildren 当前节点的子节点个数

    ACLZooKeeper 采用 ACL(AccessControlLists)策略来进行权限控制,类似于 UNIX 文件系统的权限控制


    1.3 应用场景

    • 统一配置管理:将多个系统共用的配置文件放入ZooKeeper里监听变化即可
    • 统一命名管理:根据指定名字来获取资源或服务的地址
    • 统一集群管理:集群中保证数据一致性
    • 服务器节点动态上下线:
    • 负载均衡:
    • 分布式锁:数据更新的原子性使用version的乐观锁
    • 数据发布/订阅:watcher监听机制
    • 分布式协调/通知:采用了Watcher(事件监听器),即在特定节点上注册监听器,事件触发时通知客户端

    1.4 安装

    • 下载 安装包并解压
    • 修改conf里面的配置,并重命名为zoo.cfg
    # 修改数据的存放地址
    dataDir=../zkData
    
    • 启动ZK(zkServer:2181)
    • 启动ZK客户端(zkCli)

    客户端操作需要添加依赖 Curator


    1.5 身份认证

    • world:默认方式,所有用户都可无条件访问
    • auth:不使用任何 id,代表任何已认证的用户
    • digest:用户名:密码认证方式: username:password
    • ip:对指定 ip 进行限制




    2. 基本命令与使用

    命令比较简单,列出概要自己探索一下即可

    # 创建节点
    create [-e/-s] 节点 关联内容						create /howl 12346
    
    # 更新节点内容
    set 节点 关联内容									set /howl 11111
    
    # 查看某路径的子节点
    ls 节点路径										  ls /howl
    
    # 获取节点内容
    get [watch监听] 节点							  get /howl
    
    # 删除节点
    delete/rmr 节点                                  delete /howl
    
    # 退出客户端
    quit
    




    3. 底层原理


    3.1 选举机制

    其为半数机制,即集群中半数以上存活才有效。虽然配置文件中没有指定Master和Slave,但Leader是通过内部的选举机制临时产生的,其流程如下:

    假设5台服务器一个个依次启动:

    • 服务器1启动:给自己投票,然后发投票信息。由于没有通信对象,服务器1处于Looking(选举状态)
    • 服务器2启动:给自己投票,与之前启动的服务器1交换选举数据,服务器2编号大胜出,但投票数没有大于半数,所以两个服务器的状态依然是LOOKING
    • 服务器3启动:给自己投票,与之前启动的服务器1,2交换选举数据,服务器3的编号最大所以服务器3胜出,此时投票数大于半数,所以服务器3成为Leader,服务器1,2成为Slave
    • 服务器4启动:给自己投票,与之前启动的服务器1,2,3交换信息,虽然服务器4的编号大,但之前服务器3已经胜出,所以服务器4只能成为Slave
    • 服务器5启动:同理服务器5成为Slave

    3.2 分布式部署

    • 解压安装Zookeeper到各个服务器(hadoop可以同步各个服务器??)
    • 配置每个服务器的编号(myid)
    # 在 /zkData 目录下创建一个myid文件
    touch myid
    
    # 往里面添加编号,一个数字即可
    1
    
    • 配置zoo.cfg文件
    #############Cluster###############
    server.2 = 127.0.0.1:22:22
    server.3 = 127.0.0.1:23:23
    server.4 = 127.0.0.1:24:24
    
    • 逐个启动

    3.3 监听器原理

    1. 首先要有一个main()线程
    2. 在main线程中创建Zookeeper客户端,内有两个线程,分别负责网络连接(Connect)和监听(Listener)
    3. Connect将需要监听的事件发给Zookeeper
    4. Zookeeper进行监听事件的注册
    5. 发生监听的事件,Zookeeper将消息发送给Listener
    6. Listener线程内部调用process()方法

    3.4 写数据流程

    • Client向Zookeeper的follower写数据,那么follower会将请求转发给Leader
    • Leader再将请求广播给每个follower,follower写成功后会通知Leader
    • Leader收到半数以上的写成功通知后会认为写数据成功,然后通知最初的follower
    • 最初的follower会进一步通知Client写数据成功

    3.5 Session

    客户端与ZooKeeper建立会话是用TCP长连接的,使用心跳检测来保持会话有效,这个连接可请求响应,以及接收监听事件。断开时长不超过sessionTimeout,那么重连后之前创建的会话有效


    3.6 分布式锁

    多个系统访问锁节点,那么每个系统都会在锁节点下创建一个带序号的临时节点

    序号最小的临时节点获取到锁,执行完操作则删除自身的临时节点

    其余临时节点监听序号比自己小1的节点


    3.7 集群

    最常见的集群就是主从复制了,采用Master选举方法。

    Master负责提供写服务、而其他Slave负责异步同步数据,提供读服务


    3.8 一致性问题CAP 和 算法

    • 2PC(二阶段提交)
    1. 协调者向参与者发送prepare,要参与者执行事务但不提交并记录undo,redo日志,执行后反馈给协调者
    2. 当所有参与者准备好后,协调者发送commit请求,即参与者全提交、所有参与者没有准备则进行rollback
    
    单点故障问题:协调者挂了
    阻塞问题:协调者发送prepare请求阻塞挂了,参与者占有资源不释放
    数据不一致:协调者发送了一部分commit就挂了
    
    • 3PC(三阶段提交)
    1. 向所有参与者发送CanCommit,查看是否都可以执行事务,是就进入预备状态
    2. 向所有参与者发送PreCommit,参与者执行事务不提交写日志响应结果。若收到一阶段NO或超时,会群发中断请求
    3. 在二阶段全部YES之后,群发DoCommit进行提交事务,并接收响应。若收到二阶段NO或超时,群发中断请求
    
    解决了阻塞问题,有超时机制
    
    • Paxos
    Paxos算法是基于消息传递且具有高度容错特性的一致性算法,是目前公认的解决分布式一致性问题最有效的算法之一
    
    1. 每个提案者提案时获取一个全局唯一性编号N,赋予提案
       每个表决者接受某提案后,将编号存到本地,以后仅接受大于本地编号的提案,最后将最大编号反馈给提案者
       
    2. 当提案者的提案超过半数表决者接受,那么此提案为真,群发此提案内容和编号
       表决这收到为真的提案,比较自己本地最大编号,大于则接受,小于则反馈NO
       
    有提案A被批准,提案B又批准,那么A编号小于B,重新提出编号+1的死循环
    解决思路:只有一个提案者
    


    参考:

    JavaGuide


  • 相关阅读:
    单例模式
    Curator Zookeeper分布式锁
    LruCache算法原理及实现
    lombok 简化java代码注解
    Oracle客户端工具出现“Cannot access NLS data files or invalid environment specified”错误的解决办法
    解决mysql Table ‘xxx’ is marked as crashed and should be repaired的问题。
    Redis 3.0 Cluster集群配置
    分布式锁的三种实现方式
    maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令
    How to Use Convolutional Neural Networks for Time Series Classification
  • 原文地址:https://www.cnblogs.com/Howlet/p/13837546.html
Copyright © 2011-2022 走看看