一、什么是zookeeper
ZooKeeper是一个分布式的,开放源码应用程序协同服务,由雅虎创建,是Google Chubby的开源实现。
ZooKeeper的设计目标是将那些复杂且容易出错分布式一致性服务封装起来,构成一个高效可靠的原语集并以系列简单易用的。
二、zookeeper的应用场景
典型应用场景:
- 配置管理
- 集群管理
- 队列管理
- 分布式锁
- 数据发布/订阅
- 负载均衡
- 命名服务
- Master选举
- 名字服务
三、Zookeeper实现Master-Worker协同
3.1、master-work接口
master-work是一个广泛使用的分布式架构。master负责监控worker的状态,并为worker分配任务。
- 在任何时刻,系统中最多只能有一个master,不可以出现两个master的情况,多个master共存会导致脑裂。
- 系统中除了处于active状态的master还有一个bakcupmaster,如果 activermaster失败了,backupmaster可 以很快的进入active状态。
- master实时监控worker的状态,能够及时收到worker成员变化的通知。master在收到worker成员变化的时候,通常重新进行任务的分配。
3.2、如何使用Zookeeper实现master-salve
- 使用一个临时节点/master表示master,master在行使master的职能之前,首先要创建这个znode。如果能 创建成功,进入active状态,开始行使master职能。否则的话,进入backup状态,使用watch机制监控/master。假设系统中有一个active master和一个backup master。如果active master失败,它创建的/master就会被Zookeeper自动删除。这时backup master就会收到通知,过再次创建/master节点成为新的active master。
- worker通过在/workers下面创建临时节点来加入集群。
- 处于active状态的master会通过机制监控/workers下面znode列表来实时获取worker成员的变化
四、Zookeeper数据模型
ZooKeeper的数据模型是层次。层次模型常见于文件层次模型常见于文件 层次模型常见于文件系统 。层次模型和key -value模型是两种主流的数据模型。ZooKeeper使用文件系统模型主要基于以下两点考虑:
- 文件系统的树形结构便于表达数据之间层文件系统的树形结构便于表达数据之间层次关系
- 文件系统的树形结构便于为不同应用分配文件系统的树形结构便于为不同应用分配独立的命名空间 (namespace)
ZooKeeper的层次模型称作datatree。datatree的每个节点叫作znode。不同于文件系统,每个节点都可以保存数据。每个节点都有一版本每个节点都有一版本每个节点都有一版本(version)。版本从0开始计数。
五、Zookeeper总体架构
应用使用ZooKeeper客户端库连接ZooKeeper服务。ZooKeeper客户端负责和ZooKeeper集群的交互。ZooKeeper集群可以有两种模式:standalone 模式和quorum模式。处于standalone模式的
ZooKeeper集群还有一个独立运行的ZooKeeper节点。处于quorum模式的ZooKeeper集群包含多
个ZooKeeper节点。
5.1、session
ZooKeeper客户端库和ZooKeeper集群中的节点创建一个session。客户端可以主动关闭session。另外如果ZooKeeper节点没有在session关联的timeout时间内收到客户端的数据话,ZooKeeper节点也会关闭 session。另外ZooKeeper客户端库如果发现连接的ZooKeeper出错,会自动的和其他ZooKeeper节点建立连接。
5.2、Quorum模式
处于Quorum模式的ZooKeeper集群包含多个ZooKeeper节点。下图的ZooKeeper集群有3个节点 ,其中节点1是leader节点,节点2和节点3是follower节点。leader节点可以处理读写请求 ,follower只可以处理读请求。follower在接到写请求时会把转发给leader来处理来处理。
5.2、数据的一致性
可线性化(Linearizable)写入:先到达leader的写请求会被先处理。
客户端FIFO顺序:来自给定客户端的请求按照发送执行
六、Zookeeper开发
6.1、Zookeeper的异常处理
所有同步执行的API 方法都有可能抛出以下两个异常:
- KeeperException: 表示ZooKeeper服务端出错。KeeperException 的子类ConnectionLossException 表示客户端和当前连接的ZooKeeper节点断开了连接。网络分区和ZooKeeper 节点失败都会导致这个异常出现。发生此异常的时机可能是在ZooKeeper节点处理客户端请求之前,也可能是在ZooKeeper 节点处理客户端请求之后。出现ConnectionLossException 异常之后,客户端会进行自动重新连接,但是我们必须要检查我们
以前的客户端请求是否被成功执行。 - InterruptedException:表示方法被中断了。我们可以使用Thread.interrupt()来中断API 的执行。
6.2、Zookeeper的监听机制watch
watch提供一个让客户端获取最新数据的机制。如果没有watch机制,客户端需要不断的轮询ZooKeeper 来查看是否有数据更新,这在分布式环境中是非常耗时的。客户端可以在读取数据的时候设置一个watcher,这样在数据更新时,客户端就会收到通知。
6.3、Zookeeper的条件更新
设想用znode/c实现一个counter,使用set命令来实现自增1操作。条件更新场景:
- 客户端1把/c更新到版本1,实现/c的自增1 。
- 客户端2把/c更新到版本2,实现/c的自增1 。
- 客户端1不知道/c已经被客户端2更新过了,还用过时的版本1 是去更新/c,更新失败。如果客户端1使用的是无条件更新,/c 就会更新为2,没有实现自增1 。
使用条件更新可以避免对数据基于过期的数据进行数据更新操作。
七、总结
主要介绍基本zookeeper架构,以及zookeeper的应用范围及使用,后续将介绍zookeeper的运维及进阶