Zookeeper入门

内容不涉及算法相关内容,paxos算法,zab协议等网络上已经有很多优秀的文章,这里就不献丑了
ZooKeeper

什么是Zookeeper

ZooKeeper是分布式应用程序的分布式协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、集群管理等

为什么需要zookeeper

随着业务发展,单机系统处理能力达到上限,就需要对系统进行扩展,假设我们需要将数据库扩展为主从结构,客户端需要知道数据库节点中主节点的位置,而当主节点发生故障时我们需要将从节点设置为新的主节点,就像redis一样,类似的场景有很多; 而在分布式系统中,需要协调的信息很多,比如某个服务的地址,状态,服务的名称,或是集群间状态同步等等......

若不使用zookeeper:

解决办法也简单,比如使用一个map来存储相关的信息,需要访问的时候从内存中取出即可,但由于信息可能需要在不同机器的进程中共享,还需要编写socket通讯,另一方面这样的方式存在单点故障,如果存储信息的服务器宕机,整个系统全部瘫痪;

为了解决单点故障,需要将这个存储信息的服务设计为分布式的;但是这又产生了新的问题,数据如何在分布式系统中保持一致?

这就需要一致性算法Paxos来保证,而由于Paxos存在活锁问题zookeeper使用ZAB协议来同步数据,并保证了一致性;

zookeeper为我们实现了上述的数据存储,分布式服务,高可用性等基础功能,利用zookeeper可以很方便的协调分布式应用程序;

使用场景

zookeeper的使用场景比较多,以下例举其最常用的场景

服务注册/订阅

在分布式服务中,通常都需要使用统一的命名,即将一些复杂不方便记忆,容易出错的信息对应到一个唯一的简洁的名称,zookeeper可以很容易实现名称的唯一性,并在这个唯一的名称下存储一些数据;在访问提供方启动后将信息放到zookeeper中,客户端通过相同的服务名称从zookeeper订阅需要的服务名称,从而获取服务提供方的信息

配置管理(Configuration Management)

在分布式系统中经常有某些服务的调用非常频繁,由于单点压力大所以将其部署为集群,当需要对这个服务的配置进行修改时,以往需要逐个修改,效率低且容易出错,得益于zookeeper提供的watch(监视)机制可以实现集中式配置管理,当配置发生变化zookeeper可以通知所有节点,这样节点就可以访问zookeeper获取并应用最新的配置;

组管理(Group Management)

当需要自己搭建主从结构时,需要能够选举出master,同时当slave上线或是下线时master能够立即感知(利用临时顺序节点,选取最小作为master);当master宕机后,slave要选出新的master,并通知其他slave(利用watch机制实现)

分布式锁(Distribution Lock)

在同一台机器实现互斥锁是比较简单的,因为线程或进程之间可以直接利用内存或文件进行状态的同步,但是在分布式环境中,进程运行在不同的计算节点上,无法像单机那样直接通过内存同步,利用zookeeper的watch,多个进程可以监视同一个数据(代表锁),当数据状态发生变化时进程可以知道当前锁的状态;

zookeeper的特性

高可用

ZooKeeper已实现主从复制。像它协调的分布式进程一样,ZooKeeper本身也可以在一组主机上进行主从复制。从而避免单点故障并提高性能;

组成ZooKeeper集群的服务器都彼此了解。它们共同维护内存中的数据,以及持久存储中的事务日志和快照。只要及群众大多数服务器可用,ZooKeeper服务将可用。

客户端连接到单个ZooKeeper服务器。客户端维护一个TCP连接,通过它发送请求,获取响应,获取监视事件并发送心跳检测。如果与服务器的TCP连接断开,客户端将连接到其他服务器。

高性能

在“读取为主”的工作负载中,zookeeper非常快。ZooKeeper应用程序可在数千台计算机上运行,并且在读取比写入更为常见的情况下,其性能最佳,比率约为10:1。

提供的保证

  • 顺序一致性-来自客户端的更新将按照其发送顺序进行处理。
  • 原子性-更新成功或失败。不会产生部分结果。
  • 单个数据视图-无论客户端连接到哪个服务器,客户端都将看到相同的数据视图。也就是说,即使客户端故障转移到具有相同会话的其他服务器,客户端也永远不会看到系统的较旧数据。(一致性体现)
  • 可靠性-数据被更新后,此更新将一直持续到客户端重新覆盖更新为止,否则将永久生效
  • 及时性-确保系统的客户看到的数据在特定时间范围内是最新的。(最终一致性)

zookeeper的相关概念

1.节点znode

Zookeeper会保存任务的分配、完成情况,等共享信息,那么ZooKeeper是如何保存的呢?在 ZooKeeper中,这些信息被保存在一个个数据节点上,这些节点被称为znode。它采用了类似文件系统 的层级树状结构进行管理。见下图示例:

image-20200606124840346

根节点/包含4个子节点,其中三个拥有下一级节点。有的叶子节点存储了信息。 节点上没有存储数据,也有着重要的含义。比如在主从模式中,当/master节点没有数据时,代表分布式应用的主节点还没有选举出来。

znode节点存储的数据为字节数组bytes。存储数据的格式zookeeper不做限制,也不提供解析,需要应用自 己实现。

持久节点

持久节点只能通过delete删除。zookeeper会将操作以日志的形式写入到磁盘,当日志变大时,会将所有znodes当前状态的快照写入文件系统,并生成新的事务日志文件;当zookeeper启动时将从日志恢复数据;

临时节点

临时节点在创建该节点的客户端崩溃或关闭时,自动被删除。在当前版本,由于临时znode会因为创建者会话过期被删 除,所以不允许临时节点拥有子节点。

前面 例子中的/master应该使用临时节点,这样当主节点失效或者退出时,该znode被删除,其他节点 知道主节点崩溃了,开始进行选举的逻辑。另外/works/worker-1也应该是临时节点,在此从节点 失效的时候,该临时节点自动删除。

节点版本

Znodes还维护一个数据结构,其中包括用于数据更改,ACL(访问控制列表)更改和时间戳的版本号,znode的数据每次更改时,版本号都会增加。例如,每当客户端检索数据时,会接收数据的版本。当客户端发起写入操作时则需提供与服务器上一致的版本号,否则将更新失败;

每个znode上的数据都被原子地读取和写入。读取操作将获取与znode关联的所有数据,而写入将替换所有数据。每个节点都有一个访问控制列表(ACL),用于限制谁可以执行操作。

有序节点

znode可以被设置为有序(sequential)节点。有序znode节点被分配唯一一个单调递增的序号。 序号的格式为%010d,即10位数字,不足的填充为0,零如果创建了个一有序节点为/workers/worker-,zookeeper会自动分配一个序号1,追加在名字后面,znode名称为/workers/worker-0000000001。通过这种方式,可以创建唯一名称znode,并且可以直观 的看到创建的顺序。

znode常见操作及暴露的API:

  • ls /path 查看节点的所有子节点
  • create /path data :创建一个名为/path的znode,数据为data。
    • -e 临时节点(当前客户端关闭后/或当前节点重启后失效)
    • -s 有序节点(在节点名称后面添加节点自增的序号)
  • set /path data :设置名为/path的znode的数据为data
  • get /path :返回名为/path的znode的数据、

API

  • delete:删除节点
  • exists:测试某个位置是否存在节点
  • get children :获取节点子节点的列表
  • sync:等待数据在所用节点完成同步

注意:上述列出的指令部分用于zkCli部分用于javaAPI;

2.观察与通知(watch)

分布式应用需要及时知道zookeeper中znode的变化,从而了解到分布式应用整体的状况,如果采用轮 询方式,代价太大,绝大多数查询都是无效的。因此,zookeeper采用了通知的机制。客户端向 zookeeper请求,在特定的znode设置观察点(watcher)。Watcher是Zookeeper中的一个很重要的 特性。Zookeeper允许用户在指定节点上注册一些Watcher,并且在一些特定事件触发的时候, ZooKeeper服务端会将事件通知到感兴趣的客户端上去,该机制是Zookeeper实现分布式协调服务的重要支撑。、

wtahc的主要特性:

  • 当监听器监听的事件被触发,服务端会发送通知给客户端,但通知信息中不包括事件的具体内容。以监听ZNode结点数据变化为例,当Znode的数据被改变,客户端会收到事件类型为 NodeDataChanged的通知,但该Znode的数据改变成了什么客户端无法从通知中获取,需要客户端 在收到通知后手动去获取。
  • Watcher是一次性的。一旦被触发将会失效。
  • 3.6.0中的新增功:客户端可以在znode上设置永久性的监视,这些监视在触发时不会删除,并且会以递归方式触发注册znode以及所有子znode的通知。
posted @ 2020-06-06 23:42  CoderJerry  阅读(467)  评论(0编辑  收藏  举报