ZooKeeper 是个针对大型分布式系统的高可用、高性能且具有一致性的开源协调服务,被广泛的使用。对于开发人员,ZooKeeper 是一个学习和实践分布式组件的不错的选择。
前言
在业务中使用了 ZooKeeper 作为消息系统,在开发和运维过程中,也遇到一些问题,萌发了阅读源码窥视实现细节的想法。同时我们运维的 ZooKeeper 集群规模和数据规模非常大,也想把运维的经验分享出来供参考去规避风险点和性能调优。
一共分为四章
本章学习的是Zookeeper使命、地位、基础的概念和基本组成模块
ZooKeeper 简介
在大数据和云计算盛行的今天,应用服务由很多个独立的程序组成,这些独立的程序则运行在形形色色,千变万化的一组计算机上,而如何让一个应用中的多个独立的程序协同工作是一件非常困难的事情。而 ZooKeeper 就是一个分布式的,开放源码的分布式应用程序协调服务。它使得应用开发人员可以更多的关注应用本身的逻辑,而不是协同工作上。从系统设计看,ZooKeeper 从文件系统 API 得到启发,提供一组简单的 API,使得开发人员可以实现通用的协作任务,例如选举主节点,管理组内成员的关系,管理元数据等,同时 ZooKeeper 的服务组件运行在一组专用的服务器之上,也保证了高容错性和可扩展性。
ZooKeeper 的使命
Zookeeper主要的系统功能是在分布式系统中协作多个任务。
例如,典型的主-从工作模式中,我们需要主节点和从节点进行协作,在从节点处于空闲状态时会通知主节点可以接受工作,于是主节点就会分配任务给从节点,同时我们只想有一个主节点,而很多进程可能都想成为主节点,这些操作都是要在多个任务中进行协作。
另外,协同并不总是采取像主节点选举或者加锁等同步原语的形式,配置元数据也是一个进程通知其他进程需要做什么的一种常用数据,例如,在一个主-从系统中,从节点需要知道任务已经分配给他们,即便在主节点发生崩溃的情况下,这些信息也需要有效。
在 ZooKeeper 之前,一些系统也可以采用分布式锁管理器或者分布式数据库来实现协作,例如,用数据库,redis 实现分布式锁。
那么 ZooKeeper 改变了什么呢?ZooKeeper 的设计更专注于任务协作,它不提供任何锁的接口或者通用的存储数据的接口,也没有强加任何特殊的同步原语,而是提供一个更加敏捷健壮的分布协作方案,例如在主-从模型中,ZooKeeper 没有为应用实现主节点选举,或者进程存活与否的跟踪功能,但是,ZooKeeper 提供了实现这些任务的工具,对于实现什么样的协同任务,有开发人员自己决定。
分布式系统中关键在于进程通信,其有两种选择:直接通过网络进行信息交换,或者读写某些共享存储。对于 ZooKeeper 实现协作和同步原语本质上是使用共享存储模型,即开发的应用是连接到 ZooKeeper 服务器端的客户端,他们连接到 ZooKeeper 服务器端进行相关的操作,以来影响服务器端存储的共享数据,最终应用间实现协作。
ZooKeeper 不适合的场景
整个 ZooKeeper 的服务器集群管理着应用协作的关键数据,ZooKeeper 不适合用作海量的数据存储,对于需要海量的应用数据的情况,可以使用数据库和分布式文件系统,所以在设计应用时,最佳实践是把应用数据和协同数据独立分开。
ZooKeeper 基础简介
ZooKeeper 数据结构
ZooKeeper 采用类似于文件系统的层级树状结构进行管理 Znode,并且暴露操作 API 接口。
Znode 的节点类型:在新建 znode 节点,需要指定该节点的类型,不同的类型决定了 znode 节点的行为方式,znode 的类型分为持久节点、时节点、有序节点,组合 4 中类型,持久的,临时的,持久有序的,临时有序的。对于持久节点,只能主动调用 delete 来删除,而临时的 znode,在当创建该节点的客户端崩溃或者关闭了与 ZooKeeper 的连接时,这个节点就会被删除。一般持久类型的 znode 为应用保存数据,即使 znode 的创建者不再属于应用系统时,数据会保存下来而不丢失。临时 Znode 仅当创建者的会话有效时这些信息必须有效保存,会话超时或者主动关闭时,临时 znode 会自动消失。有序 Znode 节点是被分配唯一一个单调递增的整数。
ZooKeeper 监视与通知
ZooKeeper 客户端获得服务器的数据或者变化,不是通过轮询的模式,而是基于通知的机制,客户端向 ZooKeeper 服务器端注册需要接收通知的 znode,通过对 znode 设置监视点来接收通知,需要强调的是监视点是一个单次触发的操作。
ZooKeeper 架构
ZooKeeper 服务器端运行于两种模式下:独立模式和仲裁模式。独立服务器只有一个单独的服务器,ZooKeeper 状态无法复制。而在仲裁模式下,具有一组 ZooKeeper 服务器,称为 ZooKeeper 集合,它们之间可以进行状态的复制,并同时服务客户端的请求。不过服务器集合并不会让客户端等待每个服务器完成数据保存后再继续,而是在满足仲裁数目的服务器保存或者同步了状态就会返回给客户端。在解决这一分布式数据一致性,ZooKeeper 采用 ZAB(ZooKeeper Atomic Broadcast)的一致性协议,关于 ZAB 协议后面会详细的介绍。
ZooKeeper 客户端在服务器集群中执行任何请求前必须先与服务器建立会话(session),客户端提交给 ZooKeeper 的所有操作均关联在一个会话上。客户端初始化连接到集合中某个服务器或一个独立的服务器,客户端提供TCP 协议与服务器进行连接并通信,但当会话无法与当前连接的服务器继续通信时,会话就可能转移到另外一个服务器,ZooKeeper 客户端透明地转移一个会话到不同的服务器。需要指明的,会话提供了顺序保障,同一个会话中的请求会以 FIFO(先进先出)顺序执行。
ZooKeeper 应用案例
Apache HBase
HBase 是一个通常与 Hadoop 一起使用的数据存储仓库。在 HBase 中,ZooKeeper 用于选举一个集群内的主节点,以便跟踪可用的服务器,并保持集群的元数据。
Apache Kafka
Kafka 是一个基于发布-订阅模型的消息系统。其中 ZooKeeper 用于检测崩溃,实现主题的发现,并保持主题的生产和消费状态。
Apache Solr
Solr 是一个企业级的搜索平台,它使用 ZooKeeper 来存储集群的元数据,并协作更新这些元数据。