赞
踩
ZooKeeper字面意思就是动物园管理者。它最早起源于雅虎研究院的一个研究小组,而在雅虎里,许多分布式组件项目都是以动物的名字来命名的。因为各个以动物命名的分布式组件放在一起,雅虎的整个分布式系统看起来就像是一个动物园,而ZooKeeper正好用来进行分布式环境的协调,故ZooKeeper这个名称还是起得很好的。在当时,雅虎内部的许多大型系统都需要依赖一个类似的系统来进行分布式协调,但是这些系统往往都存在分布式单点问题,也就是这个用来协调的系统自己坏掉了,那很多依赖它的系统就乱了。所以雅虎的开发人员就想着要开发一个通用的无单点问题的分布式协调框架,这样才能让开发人员把更多的精力放在业务逻辑上。
ZooKeeper是一个分布式数据一致性解决方案,分布式应用程序可以基于ZooKeeper实现诸如数据的发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等功能。
ZooKeeper的一个最常用的使用场景就是作为服务生产者和服务消费者的注册中心,提供发布订阅功能。服务生产者将自己提供的服务注册到ZooKeeper上,其实也就是在ZooKeeper上创立一个节点而已。服务的消费者在进行调用的时候,会先到ZooKeeper中去查找服务,拿到服务生产者的详细信息后,再去调用服务生产者的数据内容。在Dubbo这个牛逼的框架里,ZooKeeper就担任了它的注册中心这一关键的服务。
其实并不是,现在你用一台廉价的个人PC机就能搭建一个单机版的ZooKeeper啦。或者搭建一个伪集群模式的ZooKeeper,伪集群模式其实就是IP地址还是相同的,只是端口号不同罢了。当然,想要搭建集群模式的ZooKeeper,也还是很简单的,三台电脑就足够了。
这里要说一点,搭建ZooKeeper集群最好使用奇数台服务器,并不是越多越好,当然你有钱没处花,资源太多就另说了。就比如说,搭建以4台服务器构成的ZooKeeper集群和以3台服务器构成的ZooKeeper集群的效果是一样的。为什么呢?不应该多多益善么?这里就得讲讲ZooKeeper的容错机制了。即一个ZooKeeper集群要能够正常地对外提供服务,集群里就必须得有过半的机器能够正常工作。这样一讲,你把3台机器和4台机器往里一套,会发现效果是一样的。因为过半的意思是大于一半,注意,不是大于等于。当你集群是3台机器的时候,允许你宕掉一台机器。当你集群是4台机器的时候,也只允许你宕掉一台机器。也就是说3台机器和4台机器的容错能力是一样的,从资源、金钱的角度考虑,那肯定选择通过3台机器构建集群。同样肯定选择5台机器构建集群而不是选择6台。总之,现在每个人想搭个ZooKeeper集群来玩玩还是很简单的,大不了单机模式呗。
ZooKeeper本身就是一个分布式的系统程序,只要超过一半的节点存活,ZooKeeper就能正常的进行服务。注意,在ZooKeeper中,过半这个说法很重要,算是ZooKeeper里的精髓。
ZooKeeper中的数据内容保存在内存数据库里,所以ZooKeeper能保证高的吞吐量和低延迟。但是,正因为是内存数据库,所以注定了存储容量不会太大。这也限制了ZNode节点能存储的数据量不会太大。
在读多于写的应用场景中,ZooKeeper是尤其地高性能的。为什么呢?因为在ZooKeeper中,写会导致ZooKeeper集群里服务器之间的状态同步。因为对外提供服务的时候,ZooKeeper集群里每台服务器都是一样的,你总不能我读一台服务器拿到的数据是5,读另一台服务器拿到的数据是50,这样就乱套了。故当你有一个写的请求,比如把i这个数据写成66。那么,整个ZooKeeper集群就会进行数据同步,这样,你从哪个服务器拿到的i都会是66。当然,进行数据同步这种比较啰嗦的流程,当然会降低一些服务器的性能。
ZooKeeper有临时节点的概念。若创建临时节点的客户端会话一直存活,临时节点就会一直存在。但当会话终止时,这个临时节点就会被删除。而对于持久节点,指的是一旦持久节点这个ZNode被创建了,除非主动进行这个ZNode节点的移除操作,否则该节点将会一直保存在ZooKeeper上。
在ZooKeeper中,节点分为两类。第一类是指构成集群的机器,称为机器节点。而第二类是指数据模型中的数据单元,称为数据节点——ZNode。ZooKeeper将所有数据都存储在内存里,数据模型是一颗树(ZNodeTree)。就有点像类Unix系统里的File System。由/进行分割的路径,就是一个ZNode,比如/service/service1。每个ZNode里会保存自己的数据内容,还会保存一些属性信息。此外,ZooKeeper还允许用户为每一个节点添加一个特殊且很有用的属性:SEQUENTIAL。在创建节点的时候若标记了这个属性,那么创建时ZooKeeper会自动在其节点名后面添加一个整型数字,这个整型数字是一个由父节点维护的自增数字。
在ZooKeeper中,对于每个ZNode,ZooKeeper都会为其维护一个叫做Stat的数据结构,Stat中记录了这个ZNode的三个数据版本,分别是version(当前ZNode的版本)、cversion(当前ZNode子节点的版本)和aversion(当前ZNode的ACL版本)。那这个版本用来干嘛的,其实是用来保证对ZNode数据节点的更新操作是原子性的,这里用到了CAS操作,即若当前版本和期望的版本不相符,则更新失败。只有当前版本和期望的版本一致时,才能更新成功,更新成功后版本号加1。这里要注意的是,更新前后,数据内容不管是不是相同,版本号都要加1。即更新前,数据内容是3,版本号是1。更新后,数据内容可能还是3,但是版本号一定是2。
Watcher就是ZooKeeper里的事件监听器。ZooKeeper允许用户在指定节点上注册一些Watcher,这样当一些特定的事件触发时,感兴趣的客户端能收到服务端的事件通知,该机制很重要。其实就是回调呗,某事件发生后,比如该节点被删除了,就通知客户端,然后客户端就能根据需求进行自己的处理。
ACL其实就是权限控制列表,ZooKeeper中定义了5种权限。CREATE:创建字节点的权限。READ:获取节点数据和字节点列表的权限。WRITE:更新节点数据的权限。DELETE:删除字节点的权限。ADMIN:设置字节点ACL的权限。注意,CREATE和DELETE这两种权限都是针对子节点的权限控制。
ZooKeeper中的角色分为三大类。Leader、Learner(又分为Follower和Observer)以及Client。
Leader是事务请求的唯一调度和处理者,保证集群事务处理的顺序性。
而Follower呢,处理客户端非事务请求,转发事务请求给Leader服务器;参与事务请求Proposal的投票;参与Leader选举。而Observer不参与Leader选举,也不参与事务请求Proposal的投票,只是用来提升集群的读性能,并且不影响集群的写性能。
Client就不用说了,请求的发起者。
Leader选举过程以后有机会再谈谈吧。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。