从年后拿到这本书开始阅读,到准备系统分析师考试之前,终于读完了一遍,对Zookeeper有了一个全面的认识,整本书从理论到应用再到细节的阐述,内容安排从逻辑性和实用性上都是很优秀的,对全面认识Zookeeper很有帮助,建议大家阅读。本人看书秉承先把书看薄,再把书讲厚的原理,一般喜欢在看的过程中用笔在纸上勾勾画画,加点注释增强理解,看完后会从整体知识结构上整理出我的理解,不求详细,但求关键知识点的串联,最后通过整理的知识点想象自己给别人讲解一遍,对照书中目录,看是否也能像作者面面俱到,调理清晰,对哪块知识点不明确再翻书复读,以求透彻理解掌握。以下是我整理的关于此书的笔记,以飨读者:

(一)分布式基础知识
  1. 分布式的特点:分布性、对等性、并发性、缺乏全局时钟、故障总会发生
  2. 分布式环境下的各种问题:通讯异常、网络分区、成功失败超时三态、节点故障
  3. 从ACID到BASE的变化
  4. 一致性协议:
  • 2pc(请求处理-->提交确认)与3pc(事务处理能力询问-->处理后待提交-->提交确认)的特点及优缺点比较
  • Paxos协议的原理及在Chubby、Hypertable上的实践。
(二)Zookeeper可以保证的分布式一致性特性:
  1. 顺序一致性:同一个客户端发起的事务请求,严格按其顺序处理
  2. 原子性:事务请求处理的原子性
  3. 单一视图:无论客户端连接到哪个服务器,看到的数据模型是一致的
  4. 可靠性:对事务的处理完成并反馈后,状态会一致保留直到被其他事务改变
  5. 实时性:一定时间段内,客户端最终一定能从服务器上读取到最新的数据状态
(三)Zookeeper中的核心概念/特性:
  1. 全部存储在内存中的树形数据节点ZNode,分为持久(顺序)型与临时(顺序)节点(生命周期与客户端会话绑定),每个ZNode只能由一台服务器创建,且节点的sequential自增数字保障兄弟节点按顺序无重复
  2. 三种集群角色
    • Leader:处理事务请求并保证事务请求的顺序性(事务指能够改变Zookeeper服务状态的操作,一般包括数据节点的创建删除与内容更新、客户端会话创建与失效。每一个事务有全局唯一的ZXID);集群内部各服务器的调度
    • Follower:处理客户端非事务请求、转发事务请求给Leader、参与事务请求Proposal投票、参与Leader选举投票
    • Observer:只处理非事务服务,不参与任何形式的投票
  3. Stat数据结构维护当前ZNode的三个数据版本:当前版本version、当前子节点版本cversion、ACL版本aversion
  4. 客户端与服务端TCP长连接的会话Session管理,分桶管理策略通过设定固定周期的超时检查,批量清理超时会话。客户端利用API可对数据节点进行如下操作:创建会话、创建节点、删除节点、读取数据、更新数据、检测节点是否存在、权限控制。常用开源的两款zookeeper客户端:ZkClient、Curator。
  5. Watcher事件监听:客户端通过监听特点节点上的特定事件,实现分布式协调服务
  6. ACL:类似于UNIX文件系统的权限控制,包括增、删、读、写、admin设置等五种权限
  7. Jute为序列化组件
  8. Zookeeper将所有节点的路径、数据内容、ACL等信息组成DataTree全部存储在内存中,其底层数据结构是ConcurrentHashMap,其key是数据节点的path,而value则是真正的数据内容DataNode。通过ZKDatabase管理所有会话、DataTree存储和事务日志,并定时dump快照到磁盘,同时也方便在启动时从磁盘上的事务日志和快照数据文件恢复成一个完整的内存数据库

说明:ZXID是一个64位的数字,其中低32位针对客户端每一个事务请求,Leader服务器在产生一个新的事务proposal时进行+1,高32位代表本轮Leader周期的epoch标号,当新选举一个Leader后会对此epoch+1以区分出Leader周期的变化。集群中拥有XZID最大的proposal的机器会成为Leader,因为它一定具有所有已经提交的提案。

 
(四)Zookeeper的核心协议ZAB:
  1. 主备模型架构保证同一时刻只有一个主进程处理事务请求并广播状态,并能保证全局的变更系列被顺序应用;
  2. 所有事务请求必须由一个全局唯一的服务器Leader来协调处理,其他事务请求按照类似两阶段提交的过程向Follower服务器发送proposal提议;
  3. ZAB协议包括两种基本模式:崩溃恢复和消息广播
    • 崩溃恢复:当服务启动、Leader网络中断或退出、重启等进去恢复模式,选举产生Leader并在过半的机器从该Leader中国完成了数据同步后退出此模式进行消息广播模式并提供服务,因此只要集群中存在过半的服务器能够彼此进行正常通信,就可以选举出新的Leader并再次进入消息广播模式;
    • 消息广播:Leader为每个事物请求生成ZXID的事务proposal广播给Follower,Follower接收到后以事务日志的形式写入本地磁盘并ACK响应,当Leader接收到过半Follower的ACK后,广播一个commit消息给所有的Follower通知事务提交,同时自身提交,Follower接到commit后也完成提交从而完成这个事务处理。
 
(五)ZAB协议与Paxos算法的区别于联系:
  • 联系:都有Leader、Follower、epoch值;
  • 区别:
    • Paxos在新选举的主进程中会进行两阶段的工作,第一阶段读阶段主进程通过和其他进程的通信来收集上一个主进程的提案并提交;第二阶段为写阶段即新主进程开始提出自己的提案;
    • ZAB协议在读阶段之后额外引入一个同步阶段,在此阶段中新的Leader会确保存在过半的Follower已经提交了之前Leader周期中所有的事务proposal,从而保证在新Leader提交proposal之前,所有的Follower都完成了对之前所有事务proposal的提交。同步阶段完成后再进入写阶段。
 
(六)ZooKeeper典型8大应用场景及对应的特性:
  1. 数据发布订阅:对统一配置信息等数据可以通过在Zookeeper创建一个数据节点并让客户端进行监听,主要利用了Zookeeper的Watcher监听特性;
  2. 负载均衡:创建一个节点,负载应用把自己的服务地址写到此节点下,如果此应用挂掉,则此子节点消失
  3. 命名服务:利用Zookeeper创建顺序无重复子节点的特性;
  4. 分布式协调/通知:不同客户端都对Zookeeper上的同一个数据节点进行watcher注册,监听数据节点的变化,当发生变化所有订阅的客户端接收到通知并进行处理;
  5. 集群管理:利用了watcher监听与临时节点在会话失效自动清除的特性。同时,各服务器可以讲运行状态信息写入到临时节点中进而有助于Leader收集负载信息;
  6. Master选举:所有客户端创建同一个path的数据节点,只有一个能成功,即为Master;
  7. 分布式锁:创建临时节点,谁成功即获得锁。另外,根据创建时不同的类型-序号,根据一定的规则可以模拟出共享锁、读写锁等;
  8. 分布式队列:每个客户端在指定节点下创建临时节点,然后获取该指定节点下的所有子节点并判断自己是否是序号最小的节点,如果是则可以进行处理,如果不是则进入等待并监听比自己序号小的最后一个节点,待接到watcher通知后,重复检查。
(七)细节信息:
  1. 单机版服务器启动流程图:
  2. 集群版启动流程图:
  3. Zookeeper服务端对于会话创建的处理,大致分为请求接受、会话创建、预处理、事务处理、事务应用和会话响应6大环节,如图:
 

我读《从Paxos到zookeeper分布式一致性原理与实践》的更多相关文章

  1. 我读《通过Go来处理每分钟达百万的数据请求》

    我读<通过Go来处理每分钟达百万的数据请求> 原文 原文作者为Malwarebytes公司的首席架构师Marcio Castilho http://marcio.io/2015/07/ha ...

  2. [译]使用golang每分钟处理百万请求

    [译]使用golang每分钟处理百万请求 在Malwarebytes,我们正在经历惊人的增长,自从我在1年前加入硅谷的这家公司以来,我的主要职责是为多个系统做架构和开发,为这家安全公司的快速发展以及百 ...

  3. java它们的定义jar套餐读Excel(这包括2003和2007)数据,和实例

    使用java它们的定义jar套餐读excel数据支持excel2007和excel2003 在http://download.csdn.net/detail/u010792467/8079355下载所 ...

  4. 省市县从数据库读出来的list数据转换成json格式的数据

    一,数据源 1.1,数据库查出来的数据是 两张表先各自左外连接,然后在相互左外连接查找省市县的数据(业务需求必须这样做,省市去的是第一张表,而市县取的是第二张表,两张表中间通过市的名字连接)见这个博文 ...

  5. Golang 任务队列策略 -- 读《JOB QUEUES IN GO》

    Golang 在异步处理上有着上佳的表现.因为 goroutines 和 channels 是非常容易使用且有效的异步处理手段.下面我们一起来看一看 Golang 的简易任务队列 一种"非任 ...

  6. 我们如何用Go来处理每分钟100万复杂请求的场景

    在Malwarebytes我们经历了显著的增长,自从我一年前加入了硅谷的公司,一个主要的职责成了设计架构和开发一些系统来支持一个快速增长的信息安全公司和所有需要的设施来支持一个每天百万用户使用的产品. ...

  7. 分库分表(3) ---SpringBoot + ShardingSphere 实现读写分离

    分库分表(3)---ShardingSphere实现读写分离 有关ShardingSphere概念前面写了两篇博客: 1.分库分表(1) --- 理论 2. 分库分表(2) --- ShardingS ...

  8. Geek/Git中文怎么读

    Geek怎么读 英[gi:k] = gay客 = 给客 Git怎么读 英[gɪt] = gay 特 = 给特 Flux怎么读 英[flʌks] = 佛拉克斯 Redux怎么读 英[ri:'dʌks] ...

  9. 如何读懂Web服务的系统架构图

    Web服务的一个重要特点就是流量大.数据多,仅靠一台服务器肯定难以支撑大规模的服务. 所以我们经常会看到诸如以下的一些术语,教人好生不懂: *:系统架构.物理架构.Web服务基础设施 *:应用服务器 ...

  10. [高性能MYSQL 读后随笔] 关于事务的隔离级别(一)

    一.锁的种类 MySQL中锁的种类很多,有常见的表锁和行锁,也有新加入的Metadata Lock等等,表锁是对一整张表加锁,虽然可分为读锁和写锁,但毕竟是锁住整张表,会导致并发能力下降,一般是做dd ...

随机推荐

  1. 10055 - Hashmat the Brave Warrior & 各数据类型所占字节数 (C语言)

    Problem A Hashmat the brave warrior Input: standard input Output: standard output Hashmat is a brave ...

  2. nexus yum 私服集成

      nexus 集成了 yum 私服使用起来还是比较简单的 配置 yum proxy 实际使用我们可能需要配置centos 以及epel 的源 centos可以用http://mirror.cento ...

  3. oracle Union 中 ORA-12704:字符集不匹配问题的解决 .

    在使用Union all连接时,若A集合中某列为nvarchar2或nvarchar类型,而B集合中无此列,用‘ ’ 来代替是会报字符集不匹配,解决方法有两种,见下面的示例 例: select '中国 ...

  4. Spring4源码解析:BeanDefinition架构及实现

    一.架构图 首先共同看下总体的 Java Class Diagrams 图: 二.具体类实现 2.1 AttributeAccessor 接口定义了一个通用的可对任意对象获取.修改等操作元数据的附加契 ...

  5. TortoiseSVN比较工具设置为BeyondCompare 4

    打开TortoiseSVN的Setting,选择左边的Diff Viewer 设置如下: "D:\Program Files\Beyond Compare 4\BComp.exe" ...

  6. SQL优化之索引分析

    索引的重要性 数据库性能优化中索引绝对是一个重量级的因素,可以说,索引使用不当,其它优化措施将毫无意义. 聚簇索引(Clustered Index)和非聚簇索引 (Non- Clustered Ind ...

  7. WCF 快速入门

    定义服务契约 构建HelloWCF应用的第一步是创建服务契约.契约式是表示消息应用外形的主要方式.对于外形,是指服务暴露的操作,使用的消息 schema和每个操作实现的消息交换模式(MEP).总之,契 ...

  8. 管道和FIFO 二

    前面我们学习了一下进程,我们知道多,进程间的地址空间相对独立.进程与进程间不能像线程间通过全局变量通信. 如果想进程间通信,就需要其他机制.          常用的进程间通信方式有这几种   A.传 ...

  9. android单元测试 activity跳转 以及 input 输入后 测试

    Android junit实现多个Activity跳转测试 分类: Android Junit测试2011-11-14 16:49 1601人阅读 评论(2) 收藏 举报 androidjunitla ...

  10. python 多态、多继承、函数重写、迭代器

    用于类的函数 issubclass(cls,class_or_tuple) 判断一个类是否继承自其他的类,如果此类cls是class或tuole中的一个派生(子类)则返回True,否则返回False ...