什么是ZooKeeper(一)(通俗易懂)
以前在做别的项目时用过zk,但没有过多深入的学习,本着通俗易懂、简单方便学习成本低的方式,建议大家耐心看完,如果文章中有不清楚的地方,可发私信进步探讨!
学习zk共分为二部分,第一部分主要以理论为主。讲解架构原理、数据结构等。 第二部分主要以操作API为主。包含集群的搭建、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)具有唯一的路径标识,而路径是由斜线分隔开的路径名序列组成,和标准的文件系统非常类似,例
2 .znode 节点(重点)
每一个节点称为znode,通过路径来访问
每一个znode维护着:数据、stat数据结构(ACL、时间戳及版本号)
znode维护的数据主要是用于存储协调的数据,如状态、配置、位置等信息,每个节点存储的数据量很小,KB级别
znode的数据更新后,版本号等控制信息也会更新(增加)
znode还具有原子性操作的特点:写--全部替换,读--全部(每个 znode 的数据将被原子性地读写,读操作会读取与 znode相关的所有数据,写操作会一次性替换所有数据.)
znode有永久节点和临时节点之分:临时节点指创建它的session一结束,该节点即被zookeeper删除;(非常重要)
另:zookeeper 并没有被设计为常规的数据库或者大数据存储, 相反的是,它用来管理调度数据,比如分布式应用中的配置文件信息、状态信息、汇集位置等等。这些数据的共同特性就是它们都是很小的数据,通常以 KB 为大小单位。 zooKeeper 的服务器和客户端都被设计为严格检查并限制每个 znode 的数据大小至多 1M。
3 .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);
监听的事件是:该节点下的数据发生改变时