Zookeeper学习笔记(一)基本信息

mac2023-05-27  29

分布式系统

众所周知通常分布式架构都是中心化的设计,就是一个主控机连接多个处理节点。 问题可以从这里考虑,当主控机失效时,整个系统则就无法访问了,所以保证系统的高可用性是非常关键之处,也就是要保证主控机的高可用性。分布式锁就是一个 解决该问题的较好方案,多主控机抢一把锁。在这里我们就涉及到了我们的重点Zookeeper。

分布式协调技术 主要用来解决分布式环境当中多个进程之间的同步控制,让他们有序的去访问某种临界资源,防止造成"脏数据"的后果。

在这个分布式系统中如何对进程进行调度,我假设在第一台机器上挂载了一个资源,然后这三个物理分布的进程都要竞争这个资源,但我们又不希望他们同时进行访问,这时候我们就需要一个协调器,来让他们有序的来访问这个资源。这个协调器就是我们经常提到的那个锁。

分布式锁的实现

目前,在分布式协调技术方面做得比较好的就是Google的Chubby还有Apache的ZooKeeper他们都是分布式锁的实现者。有人会问 既然有了Chubby为什么还要弄一个ZooKeeper,难道Chubby做得不够好吗?不是这样的,主要是Chbby是非开源的,Google自家 用。后来雅虎模仿Chubby开发出了ZooKeeper,也实现了类似的分布式锁的功能,并且将ZooKeeper作为一种开源的程序捐献给了 Apache,那么这样就可以使用ZooKeeper所提供锁服务。

ZooKeeper概述

ZooKeeper是一种为分布式应用所设计的高可用、高性能且一致的开源协调服务,它提供了一项基本服务:分布式锁服务。由于ZooKeeper的开源特性,后来我们的开发者在分布式锁的基础上,摸索了出了其他的使用方法:配置维护、组服务、分布式消息队列、分布式通知/协调等。

ZooKeeper在一致性、可用性、容错性的保证,也是ZooKeeper的成功之处,它获得的一切成功都与它采用的协议——Zab协议是密不可分的。

Zookeeper 作为一个分布式的服务框架,主要用来解决分布式集群中应用系统的一致性问题,它能提供基于类似于文件系统的目录节点树方式的数据存储,但Zookeeper 并不是用来专门存储数据的,它的作用主要是用来维护和监控你存储的数据的状态变化。通过监控这些数据状态的变化,从而可以达到基于数据的集群管理

干什么事存什么数据,ZooKeeper所实现的一切功能,都是由ZK节点的性质和该节点所关联的数据实现的

例如:   ① 集群管理:利用临时节点特性,节点关联的是机器的主机名、IP地址等相关信息,集群单点故障也属于该范畴。   ② 统一命名:主要利用节点的唯一性和目录节点树结构。   ③ 配置管理:节点关联的是配置信息。   ④ 分布式锁:节点关联的是要竞争的资源。

Zookeeper数据模型Znode

ZooKeeper拥有一个层次的命名空间,这个和标准的文件系统非常相似,如下图所示。

引用方式 Zonde通过路径引用。路径必须是绝对的。除此以外,他们必须是唯一的,因此这些路径不能改变。在ZooKeeper中,路径由Unicode字符串组成,并且有一些限制。字符串"/zookeeper"用以保存管理信息,比如关键配额信息。

Znode结构 每个Znode由3部分组成:

stat: 此为状态信息,描述该Znode的版本,权限等信息data: 与该Znode关联的数据childre:该Znode下的子节点

Zookeeper用来管理调度数据,比如分布式应用中的配置文件信息、状态信息、汇集位置等等。这些数据的共同特性就是它们都是很小的数据,通常以KB为大小单位。ZooKeeper的服务器和客户端都被设计为严格检查并限制每个Znode的数据大小至多1M,但常规使用中应该远小于此值。

数据访问 ZooKeeper中的每个节点存储的数据要被原子性的操作。每一个节点都拥有自己的ACL(访问控制列表),这个列表规定了用户的权限,即限定了特定用户对目标节点可以执行的操作。

节点类型 ZooKeeper中的节点有两种,分别为临时节点和永久节点。

临时节点:该节点的生命周期依赖于创建它们的会话。一旦会话(Session)结束,临时节点将被自动删除,但他们对所有的客户端还是可见的。另外,ZooKeeper的临时节点不允许拥有子节点。永久节点:该节点的生命周期不依赖于会话,并且只有在客户端显示执行删除操作的时候,他们才能被删除。

监视器 当节点状态发生改变时(Znode的增、删、改)将会触发watch所对应的操作。当watch被触发时,ZooKeeper将会向客户端发送且仅发送一条通知,因为watch只能被触发一次,这样可以减少网络流量。

Zookeeper服务中操作

在Zookeeper中有9个基本操作 更新ZooKeeper操作是有限制的。delete或setData必须明确要更新的Znode的版本号,我们可以调用exists找到。如果版本号不匹配,更新将会失败。

更新ZooKeeper操作是非阻塞式的。因此客户端如果失去了一个更新(由于另一个进程在同时更新这个Znode),他可以在不阻塞其他进程执行的情况下,选择重新尝试或进行其他操作。

Watch触发器

watch 概述 ZooKeeper可以为所有的读操作设置watch,这些读操作包括:exists()、getChildren()及getData()。watch事件是一次性的触发器。 watch事件将被异步地发送给客户端,并且ZooKeeper为watch机制提供了有序的一致性保证。

watch 类型

数据watch(data watches):getData和exists负责设置数据watch孩子watch(child watches):getChildren负责设置孩子watch

ZooKeeper应用

分布式锁应用场景 在分布式锁服务中,有一种最典型应用场景,就是通过对集群进行Master选举,来解决分布式系统中的单点故障。

通常分布式系统采用主从模式,就是一个主控机连接多个处理节点。主节点负责分发任务,从节点负责处理任务,当我们的主节点发生故障时,那么整个系统就都瘫痪了,那么我们把这种故障叫作单点故障。

传统解决方案 传统方式是采用一个备用节点,这个备用节点定期给当前主节点发送ping包,主节点收到ping包以后向备用节点发送回复Ack,当备用节点收到回复的时候就会认为当前主节点还活着,让他继续提供服务。 当主节点挂了,这时候备用节点收不到回复了,然后他就认为主节点挂了接替他成为主节点如图所示: 但是这种方式就是有一个隐患,就是网络问题,来看一网络问题会造成什么后果 由于网络原因,备用节点没有收到主节点的ack回复,这时备用节点启动Master实例,现在系统中就存在两个Master,一部分从节点将它所做的报给主节点,一部分报给备用节点。

ZooKeeper解决方案 如果"主节点-A"挂了,这时候他所注册的节点将被自动删除,ZooKeeper会自动感知节点的变化,然后再次发出选举,这时候"主节点-B"将在选举中获胜,替代"主节点-A"成为主节点。

如果主节点恢复了,他会再次向ZooKeeper注册一个节点,这时候他注册的节点将会是"master-00003",ZooKeeper会感知节点的变化再次发动选举,这时候"主节点-B"在选举中会再次获胜继续担任"主节点","主节点-A"会担任备用节点。

ZooKeeper应用场景

数据发布与订阅

发布与订阅即所谓的配置管理,顾名思义就是将数据发布到ZK节点上,供订阅者动态获取数据,实现配置信息的集中式管理和动态更新。例如全局的配置信息,地址列表等就非常适合使用。

应用举例 在集群服务中,我们可能遇到应用使用同一配置文件的情况,如果每台机器维护一个配置文件,那么,当配置文件发生改变时,就需要去修改每台的配置。ZooKeeper可以将配置文件存储在节点数据中,如果信息发生了变化,每台机器就会收到ZooKeeper的通知。 将所需要的配置信息放到/Configuration 节点上,集群中所有机器一启动就会通过Client对/Configuration这个节点进行监控【zk.exist("/Configuration″,true)】,并且实现Watcher回调方法process(),那么在zookeeper上/Configuration节点下数据发生变化的时候,每个机器都会收到通知,Watcher回调方法将会被执行,那么应用再取下数据即可【zk.getData("/Configuration″,false,null)】。

统一命名服务(Name Service)

在分布式系统中,通过使用命名服务,客户端应用能够根据指定的名字来获取资源服务的地址,提供者等信息。被命名的实体通常可以是集群中的机器,提供的服务地址,进程对象等等,这些我们都可以统称他们为名字(Name)。其中较为常见的就是一些分布式服务框架中的服务地址列表。

应用举例 在Dubbo实现中: 服务提供者在启动的时候,向ZK上的指定节点/dubbo/ s e r v i c e N a m e / p r o v i d e r s 目 录 下 写 入 自 己 的 U R L 地 址 , 这 个 操 作 就 完 成 了 服 务 的 发 布 。 服 务 消 费 者 启 动 的 时 候 , 订 阅 / d u b b o / {serviceName}/providers目录下写入自己的URL地址,这个操作就完成了服务的发布。 服务消费者启 动的时候,订阅/dubbo/ serviceName/providersURL/dubbo/{serviceName}/providers目录下的提供者URL地址, 并向/dubbo/${serviceName} /consumers目录下写入自己的URL地址。

分布通知/协调(Distribution of notification/coordination)

ZooKeeper中特有watcher注册与异步通知机制,能够很好的实现分布式环境下不同系统之间的通知与协调,实现对数据变更的实时处理。使用方法通常是不同系统都对ZK上同一个znode进行注册,监听znode的变化(包括znode本身内容及子节点的),其中一个系统update了znode,那么另一个系统能够收到通知,并作出相应处理。

应用 ① 另一种心跳检测机制:检测系统和被检测系统之间并不直接关联起来,而是通过ZK上某个节点关联,大大减少系统耦合。 ② 另一种系统调度模式:某系统由控制台和推送系统两部分组成,控制台的职责是控制推送系统进行相应的推送工作。管理人员在控制台作的一些操作,实际上是修改了ZK上某些节点的状态,而ZK就把这些变化通知给他们注册Watcher的客户端,即推送系统,于是,作出相应的推送任务。 ③ 另一种工作汇报模式:一些类似于任务分发系统,子任务启动后,到ZK来注册一个临时节点,并且定时将自己的进度进行汇报(将进度写回这个临时节点),这样任务管理者就能够实时知道任务进度。

分布式锁

分布式锁,这个主要得益于ZooKeeper为我们保证了数据的强一致性,即用户只要完全相信每时每刻,zk集群中任意节点(一个zk server)上的相同znode的数据是一定是相同的。锁服务可以分为两类,一个是保持独占,另一个是控制时序。

最新回复(0)