以前在做别的项目时用过zk,但没有过多深入的学习,本着通俗易懂、简单方便学习成本低的方式,建议大家耐心看完,如果文章中有不清楚的地方,可发私信进步探讨!

学习zk共分为二部分,第一部分主要以理论为主。讲解架构原理、数据结构等。 第二部分主要以操作为主。集群的搭建、API的操作,zk负载均衡、分布式锁的实现

本篇读完预计6分钟

一.Zookeeper 简介

1.简介(重点)

  zooKeeper是Hadoop的开源子项目(Google Chubby的开源实现),它是一个针对大型分布式系统的可靠协调系统。

提供的功能包括:统一命名服务、配置管理、分布式锁、集群节点状态协调(负载均衡/主从协调)

    统一命名服务:在zk上注册多个临时服务A,当有某个服务A出现故障时,会自动从zk中删除,停止对外提供服务,

    配置管理:当有配置文件发生变化时,可以通过设置事件监听的方式,通知client端进行配置的更新

    分布式锁:当多个应用服务同时访问1个共享资源时,应用服务应向zk注册自己临时有序的节点信息,当有client要访问共享资源时,先获取所有的应用服务注册信息,然后规定算法(例最小),让client端与自己的信息匹配时区取锁进行访问,访问结束时释放锁,重新注册,以便下次访问。

  集群的负载均衡:应用服务启动时向zk注册本机节点的配置信息,并在节点设置计数器,当有client连接时+1,断开时-1,每次当有client连接时会获取计数器最小的客户端进行访问

  其实zk本身并不能提供以上的服务协调,它只能帮我们在节点上存储一些简单的数据,当这些数据发生变化的时候通过异步的方式通知我们,我们再根据这些数据的状态进行相应的处理,其实现模式类似于观察者模式。

  zk本质的功能是:1.替客户端保管数据  2.为客户提供数据的监听服务

二.zookeeper 的数据模型

  其实zk中的节点上维护的数据模型,类似于我们windows 操作系统中盘符的路径:C:/Program Files/java ,只不过这种路径的节点可以存储数据,还具有原子性等一些特点。

  zk本身维护了一个基于内存的数据库,用来存储节点的数据信息,并且读的速度要比写的速度更快,这个数据结构是以树状的结构将数据进行存储的。

 1 数据模型 

  zookeeper 提供一种类似目录树结构的数据模型,每个节点(znode)具有唯一的路径标识,而路径是由斜线分隔开的路径名序列组成,和标准的文件系统非常类似,例

    

.znode 节点(重点)

  每一个节点称为znode,通过路径来访问

  每一个znode维护着:数据、stat数据结构(ACL、时间戳及版本号)

  znode维护的数据主要是用于存储协调的数据,如状态、配置、位置等信息,每个节点存储的数据量很小,KB级别

  znode的数据更新后,版本号等控制信息也会更新(增加)

  znode还具有原子性操作的特点:写--全部替换,读--全部(每个 znode 的数据将被原子性地读写,读操作会读取与 znode相关的所有数据,写操作会一次性替换所有数据.)

  znode有永久节点和临时节点之分:临时节点指创建它的session一结束,该节点即被zookeeper删除;(非常重要)

  另:zookeeper 并没有被设计为常规的数据库或者大数据存储, 相反的是,它用来管理调度数据,比如分布式应用中的配置文件信息、状态信息、汇集位置等等。这些数据的共同特性就是它们都是很小的数据,通常以 KB 为大小单位。 zooKeeper 的服务器和客户端都被设计为严格检查并限制每个 znode 的数据大小至多 1M。

.znode 节点的4种类型(重点)

  PERSISTENT:永久节点

  EPHEMERAL:临时节点

  PERSISTENT_SEQUENTIAL:永久节点、序列化

  EPHEMERAL_SEQUENTIAL:临时节点、序列化

二.Zookeeper 的架构和原理

  1 .服务器中的角色定义

    启动 zookeeper 服务器集群环境后,多个 Zookeeper 服务器在工作前会选举出一个 Leader。选举出 leader 前,所有 server 不区分角色,都需要平等参与投票(observer 除外,不参与投票);选主过程完成后,存在以下几种角色:

    leader   :  领导者,可以接受 client 请求,也接收其他 server 转发的写请求,负责更新系统状态。

    follower  : 可以接收 client 请求,如果是写请求将转发给 leader 来更新系统状态。

    observer 同 follower,唯一区别就是不参与选主过程。

  2.系统架构(了解)

    

    zookeeper 分为服务器端(server)和客户端(client),客户端可以连接到整个 zooKeeper服务所提供的任意zk服务器上,访问过程是当有客户端(client)访问服务端(leader服务器)时,leader服务器返回1个可访问的地址给客户端,然后客户端通过这个地址访问到zk服务器(follower)上。客户端使用并维护一个 TCP 连接,通过这个连接发送请求、接受响应、获取观察的事件以及发送心跳。如果这个 TCP 连接中断,客户端将自动尝试连接到另外的 zooKeeper 服务器。客户端第一次连接到 zooKeeper 服务时,接受这个连接的 zooKeeper 服务器会为这个客户端建立一个会话。当这个客户端连接到另外的服务器时,这个会话会被新的服务器重新建立。

  3.Session 机制原理(了解)

    在client 连接 server 成功后, server 赋予该 client 一个 sessionid,client 需要不断发送心跳维持 session 有效,在 session 有效期内,可以使用 Zookeeper 提供的 API 进行操作。如果因为某些原因导致 client 无法正常发送心跳,在超时时长后, server会判断该 client 的 session 失效,此时 client 发送的任何操作都会被拒绝,并触发ExpiredException (失效异常),此时 KeeperState 处于 Expired 状态。

  但 client 有自动重连 server 的机制, 如果 client 的心跳无法正常连接 server,会在 session 超时前尝试连接其他 server,连接成功后可以继续操作。 如果 client 取消当前连接并连接其他 server,已存在的 watches 会丢失,取而代之的是client 会生成一个特殊 WatchEvent 告诉本地 watcher 连接已经丢失,该 WatchEvent 是:EventType.None, KeeperState.DisConnected。 本地 watcher 接收到该 WatchEvent 后会怎样?

.Watcher 监听事件(重点)

  zk对Node节点的增、删、改、查都可触发监听

  Watch事件是一次性触发器,只有被Watch 监听的数据发生变化时才被触发,通过异步的方式通知该client端(观察者)。

  Watch是一次性触发的并且在获取Watch事件和设置新watch事件之间有延迟所以不能可靠的观察到节点的每一次变化,但这个变化是毫秒级的,基本上不影响

 客户端监视一个节点,总是先获取Watch事件,再发现节点的数据变化,Watch事件的顺序对应于zk服务所见的数据更新的顺序。

 如果你还不是很清楚,看第二部分API操作

  ----------------------------------------------------------------------

  创建监听的三个地方:

    判断该节点是否存在时 : exits(path,watcher);

    监听的事件是:该节点是否存在/删除/数据是否发生改变

    获取某节点的子节点时 : getChild(pathc,watcher);

    监听的事件是:该节点下是否有子节点创建/删除

    获取该节点的数据时  : getData(pathc,watcher);

    监听的事件是:该节点下的数据发生改变时

什么是ZooKeeper(一)(通俗易懂)的更多相关文章

  1. ZooKeeper的API操作(二)(通俗易懂)

    所需要6个jar包,都是解压zookeeper的tar包后里面的. zookeeper-3.4.10.jar    jline-0.094.jar    log4j-1.2.16.jar netty- ...

  2. Zookeeper的基本概念

    Reference:  http://mp.weixin.qq.com/s?src=3&timestamp=1477979201&ver=1&signature=bBZqNrN ...

  3. IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列

    1.引言 消息是互联网信息的一种表现形式,是人利用计算机进行信息传递的有效载体,比如即时通讯网坛友最熟悉的即时通讯消息就是其具体的表现形式之一. 消息从发送者到接收者的典型传递方式有两种: 1)一种我 ...

  4. zookeeper 学习 状态机复制的共识算法

    https://www.youtube.com/watch?v=BhosKsE8up8 state machine replication 的 共识(consensus) 算法 根据CAP理论,一个分 ...

  5. 服务注册中心Eureka vs Zookeeper vs Consul

    前言 在现在云计算和大数据快速发展的今天,业务快速发展和变化.我们以前的单一应用难以应对这种快速的变化, 因此我们需要将以前单一的大应用不断进行差分,分成若干微小的应用或者服务,这就是微服务的思想.但 ...

  6. 全网最通俗易懂的Kafka入门!

    前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 在这篇之前已经写过两篇基础文章了,强烈建议先去阅读: ...

  7. 【转帖】全网最通俗易懂的Kafka入门

    全网最通俗易懂的Kafka入门 http://www.itpub.net/2019/12/04/4597/ 前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://g ...

  8. Zookeeper——分布式一致性协议及Zookeeper Leader选举原理

    文章目录 一.引言 二.从ACID到CAP/BASE 三.分布式一致性协议 1. 2PC和3PC 2PC 发起事务请求 事务提交/回滚 3PC canCommit preCommit doCommit ...

  9. 大数据学习(21)—— ZooKeeper原理

    这一篇我们对zookeeper的主要原理做一个简单介绍.zookeeper的核心原理是zookeeper atomic broadcast(ZAB协议),它来源于paxos协议.这里用通俗易懂的话,介 ...

随机推荐

  1. 转载:futex同步机制详解

    在编译2.6内核的时候,你会在编译选项中看到[*] Enable futex support这一项,上网查,有的资料会告诉你"不选这个内核不一定能正确的运行使用glibc的程序", ...

  2. CNI插件编写框架分析

    概述 在<CNI, From A Developer's Perspective>一文中,我们已经对CNI有了较为深入的了解.我们知道,容器网络功能的实现最终是通过CNI插件来完成的.每个 ...

  3. str文档

    文档 class str(object): """ str(object='') -> str str(bytes_or_buffer[, encoding[, e ...

  4. dos常用命令【总结】

    win7下有很多有用的dos命令,现在总结如下: 延伸:Linux常用命令[总结] 命令 作用 其他 ping 检查和另一台主机的连通性  ping  127.0.0.1   telnet 检查连通性 ...

  5. jQuery -&gt; 使用andSelf()来包括之前的选择集

    版权声明:本文为博主原创文章.转载请注明出处 https://blog.csdn.net/FeeLang/article/details/26254793 当我们使用Destructive Metho ...

  6. 360UI 界面框架 即QUI框架与EXT比较

    EXTJS框架是非常全面和成熟的,这是因为它发展的年头久远,并且有全世界的EXTJS爱好者为其出谋献策,它的组件库尤其是DataGrid组件无人能出其右.我在最初也考虑过使用EXTJS来做项目,学习了 ...

  7. JAVA中重写equals()方法为什么要重写hashcode()方法?

    object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true:注意:当此方法 ...

  8. MySql—模糊查询

    实例: SQL模糊查询,使用like比较关键字,加上SQL里的通配符,请参考以下:  1.LIKE 'Mc%' 将搜索以字母 Mc 开头的所有字符串(如 McBadden).  2.LIKE '%in ...

  9. XDU 1022 (数论筛法+前缀和)

    解法一:数论筛法+前缀和 //其实题目中f[n]的值可理解为存在多少个整数对使a*b<=n #include<cstdio> #define N 1007 #define maxn ...

  10. bash 获取时间段内的日志内容

    需求,获取时段内的/var/log/messages文件内出现错误的消息,支持多行的消息,支持天,小时分钟,秒级的区间,可以修改监控的日志对象 #!/bin/bash if [ $# != 1 ] ; ...