我自己使用过ZooKeeper作为Dubbo的注册中心,在搭建Solr集群的时候,我也使用过ZooKeeper作为Solr集群的管理工具。前几天在总结项目经验的时候突然问自己什么是ZooKeeper?想了半天,脑海里只能浮现出这么几个词:Zookeeper可以作为注册中心。Zookeeper是Hadoop生态系统的成员。在搭建Zookeeper集群时,最好使用奇数个服务器。可见,我对Zookeeper的了解只是停留在表面。因此,希望通过这篇文章,让大家对ZooKeeper有更详细的了解。如果您还没有学习过ZooKeeper,那么本文将是您踏入ZooKeeper大门的敲门砖;如果你已经接触过ZooKeeper,那么本文将带你回顾ZooKeeper的一些基本概念。最后,本文只涉及ZooKeeper的一些概念,不涉及ZooKeeper的使用和ZooKeeper集群的搭建。网上有文章介绍ZooKeeper的使用和搭建ZooKeeper集群。需要的话可以自己查。什么是ZooKeeperZooKeeper的由来以下内容节选自《从 Paxos 到 ZooKeeper 》第4章第一节的一段,推荐阅读:Zookeeper起源于雅虎研究院的一个研究组。当时,研究人员发现雅虎内部的很多大型系统基本上都需要依赖类似的系统进行分布式协调,但这些系统往往存在分布式单点问题。因此,雅虎的开发者试图开发一个没有单点问题的通用分布式协调框架,让开发者可以集中精力处理业务逻辑。关于“ZooKeeper”项目的名称,其实还有一段有趣的轶事。在项目初期,考虑到很多内部项目都是以动物命名的(比如著名的Pig项目),雅虎的工程师希望给这个项目起一个动物的名字。时任研究所首席科学家拉格·拉玛克里希南(RaghuRamakrishnan)开玩笑说:“再这样下去,我们的地方就要变成动物园了!”将这些组件放在一起,雅虎的整个分布式系统看起来就像一个大动物园。而Zookeeper只是用来协调分布式环境的,所以Zookeeper的名字就这样诞生了。ZooKeeper概述ZooKeeper是一个开源的分布式协调服务,ZooKeeper框架最初建立在“Yahoo!”之上。以简单而强大的方式访问他们的应用程序。后来,ApacheZooKeeper成为Hadoop、HBase和其他分布式框架使用的组织服务的标准。例如,ApacheHBase使用ZooKeeper来跟踪分布式数据的状态。ZooKeeper的设计目标是将那些复杂易错的分布式一致性服务封装起来,形成一个高效可靠的原语集,为用户提供一系列简单易用的接口。原语:操作系统或计算机网络术语类别。它由几条指令组成,用于完成一定的功能。它是不可分割的,即原语的执行必须是连续的,在执行过程中不允许被打断。ZooKeeper是典型的分布式数据一致性解决方案。分布式应用可以基于ZooKeeper实现数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分发。队列等功能。ZooKeeper最常见的使用场景之一是充当服务生产者和服务消费者的注册中心。服务生产者向ZooKeeper中心注册自己提供的服务,服务消费者在调用服务时首先在ZooKeeper中搜索服务,获取服务生产者的详细信息,然后调用服务生产者的内容和数据。如下图所示,ZooKeeper在Dubbo架构中扮演着注册中心的角色。Dubbo架构图结合个人使用浅谈ZooKeeper在我自己的项目中,ZooKeeper主要作为Dubbo的注册中心(Dubbo官方推荐使用ZooKeeper注册中心)。另外,在搭建Solr集群的时候,我使用ZooKeeper作为Solr集群的管理工具。此时ZooKeeper主要提供以下功能:集群管理:容错、负载均衡。集中管理配置文件。集群的入口。个人认为在使用ZooKeeper时,最好使用集群版的ZooKeeper,不要使用单机版。官网给出的架构图描述了一个集群版的ZooKeeper。通常3台服务器可以组成一个ZooKeeper集群。为什么最好使用奇数个服务器组成ZooKeeper集群?我们知道ZooKeeper中的Leader选举算法采用的是Zab协议。Zab的核心思想是,当大多数服务器写入成功时,任务数据写入成功:如果有3台服务器,最多允许1台服务器挂掉。如果有4台Server,则最多也允许挂掉1台Server。由于有3台或4台服务器,最多允许1台服务器挂掉,所以它们的可靠性是一样的。所以只要选择奇数个ZooKeeperServers,这里我们选择3个Servers。关于ZooKeeper的一些重要概念重要概念总结了一些关于ZooKeeper的重要概念:ZooKeeper本身就是一个分布式程序(只要有一半以上的节点存活,ZooKeeper就可以正常服务)。为了保证高可用,ZooKeeper最好以集群的形式部署,这样只要集群中的大部分机器可用(可以容忍一定的机器故障),那么ZooKeeper本身还是可用的。ZooKeeper将数据保存在内存中,这确保了高吞吐量和低延迟(但内存限制了可存储的容量,这是保持Znode中存储的数据量较小的进一步原因)。ZooKeeper是高性能的。在“读”多于“写”的应用程序中尤其高性能,因为“写”导致所有服务器间状态同步。(“读”多于“写”是协调服务的典型场景。)ZooKeeper有临时节点的概念。只要创建临时节点的客户端会话保持活动状态,临时节点就会持续存在。当会话结束时,临时节点将被删除。持久节点是指ZNode一旦创建,除非主动移除ZNode,否则ZNode会一直保存在Zookeeper上。ZooKeeper底层实际上只提供两个功能:①管理(存储、读取)用户程序提交的数据;②为用户程序提交数据节点监控服务。下面总结一下Session、Znode、Version、Watcher、ACL的概念,在第4章第1节和第7章第8节中都有提到,有兴趣的可以看看!会话(Session)Session是指ZooKeeper服务端和客户端的会话。在ZooKeeper中,客户端连接是指客户端和服务器之间的TCP长连接。客户端启动时,会先与服务器端建立TCP连接。从第一个连接的建立开始,客户端会话的生命周期也就开始了。通过这个连接,客户端可以通过心跳检测与服务器保持有效的会话,也可以向Zookeeper服务器发送请求并接收响应,也可以通过这个连接接收来自服务器的Watch事件通知。Session的sessionTimeout值用于设置客户端会话的超时时间。当客户端由于服务器压力过大、网络故障或客户端主动断开连接等各种原因断开连接时,只要在sessionTimeout指定的时间内能够重新连接到集群中的任意一台服务器,则之前的创建的会话仍然有效。在为客户端创建会话之前,服务器首先为每个客户端分配一个sessionID。由于sessionID是一个Zookeeper会话的重要标识,所以很多会话相关的运行机制都是基于这个sessionID。因此无论哪个服务器为客户端分配sessionID,都必须是全局唯一的。当Znode谈到分布式时,我们通常所说的“节点”指的是组成集群的每一台机器。但是,在ZooKeeper中,“节点”分为两类:第一类也是指组成集群的机器,我们称之为机器节点。第二类是指数据模型中的数据单元,我们称之为数据节点——ZNode。ZooKeeper将所有数据存储在内存中。数据模型是一棵树(ZnodeTree),用斜杠(/)分隔的路径就是一个Znode,比如/foo/path1。每个主机都会保存自己的数据内容,同时也会保存一系列的属性信息。在Zookeeper中,Node可以分为两类:持久节点和临时节点。所谓持久节点,就是ZNode一旦创建,除非主动移除ZNode,否则ZNode会一直保存在ZooKeeper上。临时节点不同。它的生命周期与客户端会话绑定。一旦客户端会话失败,客户端创建的所有临时节点将被移除。此外,ZooKeeper还允许用户为每个节点添加一个特殊的属性:SEQUENTIAL。一旦一个节点被标记了这个属性,当这个节点被创建时,ZooKeeper会自动在它的节点名的末尾附加一个整数。这个整数是父节点维护的自增数。前面我们提到,Zookeeper的每一个ZNode都会存储数据,而对应于每一个ZNode,Zookeeper都会为它维护一个名为Stat的数据结构。Stat中记录了这个ZNode的三个数据版本,分别是:version(当前ZNode版本)cversion(当前ZNode子节点版本)aversion(当前ZNodeACL版本)WatcherWatcher(事件监听器),这是ZooKeeper中一个很重要的特性。ZooKeeper允许用户在指定的节点上注册一些Watcher,当一些特定的事件被触发时,ZooKeeper服务器会通知对事件感兴趣的客户端。这种机制是ZooKeeper实现分布式协调服务的一个重要特性。ACLZooKeeper使用ACL(AccessControlLists)策略进行权限控制,类似于UNIX文件系统的权限控制。ZooKeeper定义了5种权限,如下图所示:特别需要注意的是,CREATE和DELETE这两种权限是对子节点的权限控制。ZooKeeper特性ZooKeeper有哪些特性?具体如下:顺序一致性:从同一个客户端发起的事务请求,最终会按照严格的顺序应用到ZooKeeper中。原子性:所有事务请求的处理结果在整个集群的所有机器上都是一致的应用,即要么整个集群的所有机器都成功应用了某个事务,要么都没有应用。单一系统镜像:无论客户端连接到哪个ZooKeeper服务器,它看到的服务器端数据模型都是一致的。可靠性:应用更改请求后,更改的结果将一直保留,直到被下一个更改覆盖。ZooKeeper设计目标简单的数据模型ZooKeeper允许分布式进程通过共享的分层命名空间相互协调,类似于标准文件系统。命名空间由ZooKeeper中称为Znodes的数据寄存器组成,这些类似于文件和目录。与为存储而设计的典型文件系统不同,ZooKeeper数据保存在内存中,这意味着ZooKeeper可以实现高吞吐量和低延迟。为了保证高可用,ZooKeeper最好以集群的形式部署,这样只要集群中的大部分机器可用(可以容忍一定的机器故障),那么ZooKeeper本身还是可用的。客户端在使用ZooKeeper时,需要知道集群机器列表,通过与集群中的某台机器建立TCP连接来使用服务。客户端使用这个TCP连接发送请求,获取结果,获取监听事件,发送心跳包。如果连接异常断开,客户端可以连接到另一台机器。ZooKeeper官方提供的架构图:上图中的每个Server代表一个安装了ZooKeeper服务的服务器。组成ZooKeeper服务的服务器在内存中维护当前服务器状态,每个服务器保持相互通信。集群之间通过Zab协议(ZookeeperAtomicBroadcast)保持数据一致性。顺序访问对于来自客户端的每个更新请求,ZooKeeper分配一个全局唯一的递增编号。这个数字反映了所有事务操作的顺序,应用程序可以使用ZooKeeper的这个特性来实现更高级别的同步原语。这个数字也称为时间戳—zxid(ZooKeeper事务ID)。高性能ZooKeeper是高性能的。在“读”多于“写”的应用程序中尤其高性能,因为“写”导致所有服务器间状态同步。(“读”多于“写”是协调服务的典型场景。)ZooKeeper集群角色引入最典型的集群模式:Master/Slave模式(主备模式)。在这种模式下,通常Master服务器作为主服务器提供写服务,其他Slave服务器通过异步复制从Master服务器获取最新数据提供读服务。但是,ZooKeeper没有选择传统的Master/Slave概念,而是引入了Leader、Follower和Observer三种角色。如下图所示:ZooKeeper集群中的所有机器通过Leader选举过程选出一台名为“Leader”的机器。Leader可以同时为客户端提供写服务和读服务。除了Leader,Follower和Observer都只能提供读服务。Follower和Observer唯一的区别是Observer机器不参与Leader选举过程,也不参与写操作的“超过一半写入成功”策略,因此Observer机器可以提高读集群的性能而不影响写入性能。ZooKeeper&ZAB协议&Paxos算法ZAB协议&Paxos算法Paxos算法可以说是ZooKeeper的灵魂。但是ZooKeeper并没有完全采用Paxos算法,而是使用ZAB协议作为核心算法来保证数据的一致性。另外,在ZooKeeper的官方文档中也指出,ZAB协议并不是像Paxos算法那样的通用分布式共识算法,而是一种专门为ZooKeeper设计的崩溃可恢复的原子消息广播算法。ZAB协议简介ZAB(ZooKeeperAtomicBroadcast)协议是专门为分布式协调服务ZooKeeper设计的支持崩溃恢复的原子广播协议。在ZooKeeper中,主要依靠ZAB协议实现分布式数据一致性。基于该协议,ZooKeeper实现了主备模式的系统架构,以维护集群中副本之间的数据一致性。ZAB协议的两种基本模式ZAB协议包括崩溃恢复和消息广播两种基本模式。当整个服务框架在启动过程中,或者Leader服务器出现网络中断、崩溃退出、重启等异常情况时,ZAB协议会进入recovery模式,选举出新的Leader服务器。Whenanewleaderserveriselectedandmorethanhalfofthemachinesintheclusterhavecompletedstatesynchronizationwiththeleaderserver,theZABprotocolwillexittherecoverymode.其中,所谓状态同步是指数据同步,用于保证集群中一半以上的机器能够保持Leader服务器的数据状态一致。当集群中超过半数的Follower服务器与Leader服务器完成状态同步后,整个服务框架就可以进入消息广播模式。当一个同样遵守ZAB协议的服务器启动并加入集群时,如果集群中已经有一个负责消息广播的Leader服务器。那么新加入的服务器就会有意识地进入数据恢复模式:找到Leader所在的服务器,与其同步数据,然后一起参与消息广播过程。上面介绍中提到,ZooKeeper的设计是只允许一个Leader服务器处理事务请求。Leader服务器收到客户端的交易请求后,会生成相应的交易提议,并发起一轮广播协议。而如果集群中的其他机器收到了客户端的交易请求,那么这些非Leader服务器会先将交易请求转发给Leader服务器。关于ZAB协议&Paxos算法,要讲和理解的东西太多了。推荐阅读以下两篇文章:图解Paxos共识协议:http://blog.xiaohansong.com/2016/09/30/Paxos/ZookeeperZAB协议解析:http://blog.xiaohansong.com/2016/08/25/zab/关于如何使用ZooKeeper实现分布式锁,可以查看以下文章:ZookeeperZAB协议分析:https://blog.csdn.net/qiangcuo6087/article/details/79067136看完这篇文章总结,你一定已经从以下七点了解了ZooKeeper:ZooKeeper的由来什么是ZooKeeper?ZooKeeper的一些重要概念(Session、Znode、version、Watcher、ACL)ZooKeeper特性ZooKeeper设计目标ZooKeeper集群角色介绍(Leader、Follower和Observer三种角色)ZooKeeper&ZAB协议&Paxos算法参考文章:?https:///cwiki.apache.org/confluence/display/ZOOKEEPER/ProjectDescriptionhttps://cwiki.apache.org/confluence/display/ZOOKEEPER/Indexhttps://www.cnblogs.com/raphael5200/p/5285583.htmlhttps://zhuanlan.zhihu.com/p/30024403
