一、ZooKeeper是什么?
ZooKeeper是一个高性能的分布式协调服务。
那么什么又是分布式协调服务呢?
背景:互联网的快速发展以及对系统性能要求的不断提高,使计算机系统由集中式逐渐衍变成分布式。分布式系统的出现,大幅度提高了系统的整体处理速度、降低了对单台服务器硬件的需求、减少了由于单点问题导致的系统不可用的情况。
如图所示,同样一个系统A,流量较小时,单台服务器能够满足需求。随着流量的增大,出现了分布式系统后,由服务器1、2、3组成的分布式系统共同均衡负载。同时不可避免的要面对分布式系统所带来的难题与挑战:如何处理这3个节点之间的网络可能带来的通信异常以及网络分区?如何处理其中某个节点宕机故障?如何去有效协调这3个节点之间的消息通信,来保证系统的正常运行?更细的方面比如如何保证分布式事务处理等等。
针对这种情况,Google Chubby提供了解决分布式协作、元数据存储等所使用的分布式锁服务,应用在了GFS、Big Table等分布式服务中。由于Chubby未开源,根据Google的论文,ZooKeeper诞生了。ZooKeeper起初是Hadoop的子项目,现在已经成为了Apache顶级项目。ZooKeeper为分布式应用提供了可靠的、高性能的协调服务,可以保证分布式一致性特性。
二、ZooKeeper基本特性有哪些?
ZooKeeper提供了一个基于内存的、树形结构的数据模型。该数据模型类似文件系统,由一系列称之为znode的节点层级构成(如下图所示)。
/**
* TIPS:ZooKeeper数据模型以及节点znode的理解
* 树形结构,类似文件系统
* 数据全部在内存中,访问速度快
* 通过路径(path)完成对对节点的访问
* 路径元素之间由/分隔,子节点依赖父节点,每个节点由该路径唯一标识
* 默认数据包含/zookeeper根节点,不要创建该节点信息
* 节点名称为Unicode字符组成
*/
通过该数据模型,ZooKeeper能够很好的完成分布式系统中的协调功能,包括(不局限于):数据发布/订阅、集群管理、Master选举、分布式锁、负载均衡、命名服务、分布式协调/通知等。这些功能的实现离不开ZooKeeper一些的基本特性:
1、数据一致性
ZooKeeper能够保证数据的最终一致性,这也是ZooKeeper最重要的特性。所支持的所有功能必须在该特性的支持下,才能正常工作。也就是说,在一定时间内,ZooKeeper能够保证用户看到的数据是最终写入的数据,且每个人看到的视图是一致的。
2、watch回调
ZooKeeper能够提供对数据节点状态的监听回调。数据节点发生变化后,ZooKeeper会向监听该节点的客户端发送对应的事件通知。这样客户端就可以知道该节点发生了什么变化,进而完成下一步操作。该特性可以支持数据发布/订阅、负载均衡、分布式协调/通知、集群管理、Leader选举、服务注册与发现等等。
3、临时节点
ZooKeeper能够注册和会话生命周期一致的节点。注册该节点的会话失效后,该节点会被移除,从而达到会话在我在,会话不在我不在的效果。该特性可以支持负载均衡、Leader选举、分布式锁、服务注册与发现等等。
4、顺序节点
ZooKeeper提供顺序节点,能够保证顺序节点的顺序性。ZooKeeper会为顺序节点维护一份时序,以保证按照时间先后顺序有序。该特性可以支持命名服务等功能。
三、Zookeeper能够保证什么?
由于数据模型简单且全部在内存中,ZooKeeper速度非常快。它的目标是成为构建复杂服务的基础,为此它提供了一系列保证:
1、顺序一致性
同一客户端的更新将会顺序的执行。
2、原子性
事务操作只有成功或者失败,不存在某些机器更新成功而另一部分未更新的情况。
/**
* TIPS: ZooKeeper中的事务
* 对节点的写操作:包括创建(create)、删除(delete)、更新(setData)、设置权限(setACL)、批量操作(multi)
* 服务端一些验证以及内部操作:包括数据版本校验(check)、session创建(createSession)、session关闭(closeSession)、错误(error,一些异常等)
*/
3、单一视图
同一个客户端无论连接到哪个服务器上,都只会看到同一视图。也就是说,同一客户端无论什么时候连接到哪个服务器上,都不会看到比自己之前看到的更早的版本数据。
4、可靠性
一旦更新成功,将会持久化,直至再次被更新覆盖。
5、实时性
这里所说的实时性指的是在一定时间内,能够确保客户端看到最终的数据状态。
四、ZooKeeper的应用场景有哪些?
利用ZooKeeper的特性,能够很好地协调分布式应用。下面主要介绍下在分布式系统中,ZooKeeper的一些使用场景。
1、Master选举
很多分布式系统是Master/Slave结构,Master提供调度、协调以及一些重要的决策功能,由Slave完成实际任务的执行。如何确定哪台机器是Master且保证整个分布式系统中的Slave节点与Master节点角色正常转化呢?ZooKeeper能够很轻松来协助解决这一场景。
2、数据发布/订阅
发布者发布信息,订阅者可以接收相关信息,也可以取消订阅。在数据发布/订阅场景下,发布者可以将数据发布到ZooKeeper的节点上,订阅者可以利用Watch特性进行数据订阅。当数据节点发生变化时,ZooKeeper会通知所有订阅者相关的变化,从而保证数据的发布与订阅功能,实现数据的动态获取。
3、负载均衡
当系统中存在多台计算机提供相同的服务时,如何根据各个服务器当前的网络连接、机器负载、CPU等资源使用情况,来合理进行负载均衡,以达到最小化响应时长、优化资源利用、保证系统的高可用性等。可以利用ZooKeeper的临时节点,将负载信息注册到该节点上。根据各个机器的负载以及自定义负载均衡算法,实现动态负载均衡。
4、命名服务
分布式系统内,命名服务是最基本的服务之一。被命名的实体可以是集群中的机器、提供服务地址或者远程对象等。例如,分布式服务框架中的服务地址列表,可以利用ZooKeeper实现的命名服务注册到ZooKeeper上,客户端可以根据指定的服务名称来获取相关信息,实现对资源的定位和使用。利用ZooKeeper的顺序节点特性,能够分配全局唯一id,轻松实现命名服务。
5、分布式锁
分布式系统需要考虑同步访问共享资源问题。对于共享资源,常用互斥手段来保证对共享资源的正常访问与修改,防止系统间的互相干扰。对于非分布式系统来说,常采用锁机制。在分布式系统中,可以使用分布式锁来保证一致性。ZooKeeper的节点能够保证已存在的情况下,其他人不能再进行创建。可以利用该特点,实现锁的获取与释放。
6、服务注册与发现
当服务越来越多,各个服务的服务器也不止一台,如何保证服务的正常提供与调用呢?利用ZooKeeper能够实现这样一个对各个服务的整合与路由的平台。服务启动可以向ZooKeeper注册自己的相关信息,由该平台进行统一管理。当服务下线或异常时,该平台能够及时获知状态,其他服务进行调用时可根据自定义策略自动路由到其他正常服务。从而实现服务的注册与发现。
当然,ZooKeeper还有很多应用场景,在之后的文章中,会根据各个应用场景分别介绍如何ZooKeeper来实现这些功能。
五、参考资料
1、zookeeper整体概述:http://zookeeper.apache.org/doc/current/zookeeperOver.html
2、倪超 . 从PAXOS到ZOOKEEPER分布式一致性原理与实践