Zookeeper学习笔记(中)

Zookeeper的基本原理和基本实现

深入了解ZK的基本原理

ZK的一致性:

  • ZAB 协议: Zookeeper 原子消息广播协议

      ZK通过选举保证 leader 的高可用, 
    
      三个阶段:
    * 发现:选举 leader
    * 同步:Follower 或者 Observer 从 leader 中同步最新数据
    * 广播: 服务器角色:
    * Leader:领导者, 所有更新操作通过 leader 进行
    * Follower:跟随者, 有投票权, leader挂了之后有权作为竞选者
    * Observer:只能读取数据, 没有投票权, 不能参与竞选 leader 服务器状态:
    * LOOKING
    * FOLLOWING
    * OBSERVING
    * LEADING 集群通讯: id大的向小的发起连接
  • Leader的选举

      选举算法:
    通过FastLeaderElection, tcp协议
    触发时机:
    1) 集群启动
    2) Leader宕机
    成为leader的因素 : zxid 和 myid 思考: 有3个全新节点组成一个集群,依次启动1,2,3, 哪个节点会成为 leader ? 选举过程:
    1) 每个节点状态为 LOOKING
    2) 每一个server发出一个投自己的投票(myid+zxid)
    3) 处理投票:将收到投票和自己投票相比(比较zxid,比较myid),有些节点修改投票,再次发送
    比较zxid的意义:过半数即认为OK, 只要半数中的机器有一个在新的选举中, 即它会成为新leader将数据同步给其他人
    4) 统计投票, 确定
    5) 修改服务器状态
  • 各个节点数据的同步:

      leader选举之后, leader同其他节点进行同步,同步完成, leader才真正变为leader
    leader同超过一半follower同步结束才OK
    follower选举完成后尝试连接leader,带上自己最大的 zxid, 来确定数据同步的过程 * 同步算法(DIFF): 适用于 follower 的最大事务id, 在 min , max 之间
    1. 发送同步请求
    2. 发送同步数据
    3. 一旦过半follower完成同步,leader发送信号结束同步流程,即可以对外服务 * 同步算法(TUNC): 适用于 leader 宕机, 恢复后作为 follower 加入, 其上有已经 proposal 的新事务, 其id > max
    宕机之后如果 TRUNC 之后, 新集群已经有数据修改, 则需要通过 DIFF 将新修改发送给加入节点
    简单说明步骤:
    1) 新节点加入后收到 trunc 命令, 将只存在于新节点上的数据回滚
    2) 确定是否新leader有新的提交,如有进行DIFF, 完成整个过程 * 同步算法(SNAP):全量
    适合宕机多时后恢复, 其id < min , 集群的事务日志文件已经有更新多个了 * 获取同步后的数据 读取前条用 sync 方法进行数据同步, 确保数据为最新
  • 以下为我在思考ZK选举原理过程中产生的一些问题, 有些还未完全获取到正确答案, 暂时提供出来供大家一起讨论

      1. zxid在一个主周期中是否肯定一致连续?

    2. 无 leader 的状态时, 是否可以接受消息更新? 只有leader选举完毕才能再继续对外服务(读写)?
    无 leader 状态不可接受, 需要等待到 leader 选举完毕
    3. 如果某zxid被废弃后, 客户端如何得知? 此种情况不会让客户端得知消息已接收确认的消息 ?
    客户端只有在消息被commit之后才会收到更新成功的确认
    4. 只经过proposal, 没有commit的数据不会返回给客户端?(前leader宕机,可能有些自己写入提交,但是别的节点还未获取的数据)这些数据会被认为是客户端正常提交的数据?
    5. 投票中每个节点都发给其他节点? 投票何时结束? 何时出发统计投票?
    6. 同步: observer 需要如何同步?
    7. 同步是否有可能失败,导致重新选举 leader?
    有可能
    8. 个别follower无法连接leader导致无法完成同步, 重新回到选举状态, 之后如何? 会真正再次进行选举?
    会再次选举
    9. 最大,最小事务id:需要理解存储机制, min 不在快照文件中的最小id, max :事务日志中的最大id, 只要在事务日志中,即都是已经在集群中commit(个别节点上没有)
    10. 修改的proposal 是发给所有节点? 为何 diff 同步还得再发一份 ?

ZK的具体实现

  1. 客户端连接:

     多个地址会随机排序,从前往后继续
    查看类 : org.apache.zookeeper.client.StaticHostProvider
  2. 会话:

     客户端和服务端的一个连接是TCP连接
    
     会话实现类 : SessionImpl
    Ticktime : 会话下次超时时间 会话状态:
    CONNECTING
    CONNECTED
    RECONNECTING
    RECONNECTED
    CLOSED 会话的维护
    * 服务器通过 SessionTracker 维护会话
    * 会话检查和清理都在 Leader 节点处理
    * 通过三个维度管理会话:
    sessionId , session
    失效时间, sessionSet
    sessionId, 失效时间 分桶策略: 用于会话失效检查和清除
    分桶策略的说明:根据失效时间划分不同的session
    把时间按照标准时间单位进行分割
    某会话由于操作(心跳也是一个操作)导致超时时间变化, 从一个桶移到下一个桶
    sessionTracker 中一个线程, 某次检查分桶中还有会话, 则说明超时 会话清理的步骤
    1. 状态设为 CLOSED
    2. 所有节点发送会话关闭
    3. 删除临时节点
    4. 会话列表中移出
    5. 网络断开 会话重连
    CONNECTION_LOSS
    SESSION_EXPIRED
    SESSION_MOVE 待解决:
    清除之后, 还是否可以通过设置 sessionId , 连接上一个session ? 连接时设置 sessionId 如何使用 ?
  3. 数据和存储:

     基本结构:
    ZKDatabase
    存储管理所有会话, datatree 的存储和事务日志
    定期向磁盘写入快照数据
    节点启动恢复内存数据 DataTree
    维护数据/目录/权限
    数据的领域模型 DataNode
    树形中每个节点,包括父节点,子节点,节点数据 事务日志:
    日志文件:
    datalog 或者配置的目录
    vsersion-2 代表日志格式的版本号
    大小64MB
    文件名为后缀16进制格式,其中包含了本日志文件第一个 zxid 日志格式:
    日志文件可以通过工具解析出: LogFormatter
    日志格式内容解析:
    各类会话,事件和内容都存储 日志写入:
    通过 FileTxnLog 实现日志写入, 使用 append 方式
    写入过程:
    1. 确定事务日志文件,确定是否需要扩容(新增文件会用0填满64MB)
    2. 事务序列化
    3. 生成checknum
    4. 写入文件流
    5. fsync, 写入磁盘 数据快照:
    ZK中某个时刻的完整数据,和事务日志是不同的文件
    文件后缀为快照中所包含的最新的zxid
    通过SnapshotFormatter可以查看内容 快照流程:
    1. 确定是否需要快照: 默认 snapCount 100000, 算法避免集群节点同时进行快照
    2. 切换事务日志文件
    3. 创建快照异步线程
    4. 生成快照数据文件
    5. 数据刷入快照文件 事务日志和数据快照的联系和异同:
    快照存储:
    当时内存中的数据模型
    一旦快照存储之后,会新开事务日志文件 事务日志:
    所有 commit 提交的数据都会记录在事务日志中
    事务日志文件 恢复使用:
    取最新的快照文件, 恢复到内存数据结构中
    最新的事务日志中有些数据未反应在快照中, 需要根据事务日志中的记录, 也恢复到数据结构中

Zookeeper学习笔记(中)的更多相关文章

  1. ZooKeeper 学习笔记

    ZooKeeper学习笔记 1.   zookeeper基本概念 zookeeper是一个分布式的,开放源码的分布式应用程序协调服务,是hadoop和Habase的重要组件,是为分布式应用提供一致性服 ...

  2. ZooKeeper学习笔记(二)——内部原理

    zookeeper学习笔记(二)--内部原理 1. zookeeper的节点的类型 总的来说可以分为持久型和短暂型,主要区别如下: 持久:客户端与服务器端断开连接的以后,创建的节点不会被删除: 持久化 ...

  3. ZooKeeper学习笔记(一)——概述

    zookeeper学习笔记(一)--概述 1. 概述 Zookeeper是一个开源的分布式的,为分布式应用提供协调服务的Apache项目.zookeeper从设计模式的角度来理解:是一个基于观察者设计 ...

  4. Zookeeper学习笔记(上)

    Zookeeper学习笔记 本篇主要是一些基本的介绍和API的使用介绍, 有些只是记录了知识点,而没有完全在笔记中详细解释, 需要自行查找资料补充相关概念 主要参考了课程中的内容: Zookeeper ...

  5. ZooKeeper学习笔记一:集群搭建

    作者:Grey 原文地址:ZooKeeper学习笔记一:集群搭建 说明 单机版的zk安装和运行参考:https://zookeeper.apache.org/doc/r3.6.3/zookeeperS ...

  6. ZooKeeper学习笔记三:使用ZooKeeper实现一个简单的配置中心

    作者:Grey 原文地址:ZooKeeper学习笔记三:使用ZooKeeper实现一个简单的配置中心 前置知识 完成ZooKeeper集群搭建以及熟悉ZooKeeperAPI基本使用 需求 很多程序往 ...

  7. ZooKeeper学习笔记四:使用ZooKeeper实现一个简单的分布式锁

    作者:Grey 原文地址: ZooKeeper学习笔记四:使用ZooKeeper实现一个简单的分布式锁 前置知识 完成ZooKeeper集群搭建以及熟悉ZooKeeperAPI基本使用 需求 当多个进 ...

  8. ZooKeeper学习笔记二:API基本使用

    Grey ZooKeeper学习笔记二:API基本使用 准备工作 搭建一个zk集群,参考ZooKeeper学习笔记一:集群搭建. 确保项目可以访问集群的每个节点 新建一个基于jdk1.8的maven项 ...

  9. Zookeeper学习笔记(下)

    这是ZK学习笔记的下篇, 主要希望可以分享一些 ZK 的应用以及其应用原理 我本人的学习告一段落, 不过还遗留了一些ZK相关的任务开发和性能测试的任务, 留待以后完成之后再通过其他文章来进行分享了 Z ...

随机推荐

  1. 十八、RF中selenium2library构造函数中参数解释

    def __init__(self,                  timeout=5.0,                  implicit_wait=0.0,                 ...

  2. python语言优势

    与Java等语言比较起来,最大优点是语法很简洁,很多功能像octave和matlab,能够对数组或矩阵进行高效处理. 比如一个数组求和,这里只要一句话sum(a),Java等语言就需要循环.还有矩阵的 ...

  3. 使用C#分层查询多个表数据

    下面我来给大家叙述一下视野分层加载多张表数据: 首先创建一个StudentExtends类: 在DAL层studentDAL类写如下代码: 在BLL层写如下代码,引用DAL层的LoadStudentI ...

  4. npm link的作用

    语法: 1. 在一个包目录下npm link (把当前的包目录软连接到global folder里面,把二进制文件也软连接到global的bin里面  这个prefix可以用npm config ls ...

  5. GitHub入门(一)GIT配置与Hexo博客搭建

    首先安装配置Git环境,由于本人使用Windows操作系统所以从msysgit.github.io下载msysGit Windows版本,安装.(Mac一般自带Git) 安装的时候一般使用默认选项,其 ...

  6. 大sd卡 裂开了,写保护掉了。重新装好后,被写保护的解决办:

    大sd卡 裂开了,写保护掉了.重新装好后,被写保护的解决办: 1.用烙铁把写保护附近的塑料往外顶一点点,就ok   别太热,也别劲太大.容易过,不能破坏原来的部分. 解决问题. 总结: 写保护,就是检 ...

  7. 学用 TStringGrid [6] - Options

    本例运行效果图: 一般修改 TStringGrid 的 Options 直接在设计时选一下 True 或 False 就行了; 代码中可以像下面操作:   StringGrid1.Options := ...

  8. C# sqlite 无法识别的datetime格式 FromOADate

    再读取不可控数据库datetime字段时,遇到了一个奇葩问题——“无法识别的datetime格式” 搞了半天…… 数据库里看:2017-06-06 10:28:30.000 不做处理查询报错:“无法识 ...

  9. oracle-不完全数据库恢复-被动恢复-RMAN-06025/ORA-01190

    不完全数据库恢复 到目前为止,前面讨论的都是完全恢复数据库,这是recover database\recover tablespace\recover datafile默认的行为特征. 所谓完全恢复指 ...

  10. 【ABAP系列】SAP ABAP DYNP_VALUES_UPDATE 更新屏幕字段的函数及用法

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP DYNP_VA ...