Zookeeper可以做什么?

Zookeeper是一个分布式服务框架,是Apache Hadoop的一个子项目,它主要用于解决分布式应用中经常遇到的一些数据管理问题,比如配置管理、命名服务、分布式锁、集群管理等。
刚接触zookeeper的时候有些云里雾里,不知从哪里入手好,其实简单的说zookeeper就是 文件系统 + 监听通知机制

系统原理

文件系统

在zookeeper中维护了类似Unix系统的树形文件节点,可以往这个节点中存储或者获取数据,我们将这些节点称为znode,每个znode默认能够存储1Mb的数据,znode有四种不同的类型。

  • PERSISTENT 持久化目录节点 所谓持久节点就是指节点创建后,除非进行删除操作就一直存在,不会因创建该节点的客户端会话失效或者zookeeper服务停止而消失
  • **PERSISTENT_SEQUENTIAL 持久化顺序编号节点 ** 和持久节点基本特性一致,额外的特点是,每个父节点会为他的第一级子节点维护一份时序,会记录每个子节点创建的先后顺序。在创建子节点的过程中,zookeeper会自动给子节点的名称后面增加一个数字后缀。例如创建名为"test"的子节点,zookeeper会给 "test_" 后自动补充数字。
  • EPHEMERAL 临时目录节点 和持久节点不同,临时节点的生命周期和客户端会话绑定,也就是说,如果客户端会话失效,那么这个节点会被自动清除掉。这里有几点需要注意,首先这里说的是会话失效而不是连接断开,其次临时节点下不能创建子节点,另外客户端会话失效后,所有的节点也不是瞬间消失,而是要过一段时间,大概10s以内。
  • EPHEMERAL_SEQUENTIAL 临时顺序编号目录节点 节点属于临时节点,不过创建的子节点带有顺序,客户端会话结束节点会自动消失。

通过上面的节点类型可以看出,znode的节点有临时/持久,顺序/无序两大类,组合成四种不同的节点类型。

监听通知机制

客户端注册到zookeeper上监听它所关心的目录节点,当目录节点发生变化(数据改变、节点被删除、子目录节点增加或删除)时,zookeeper会通知客户端该节点发生了变化。

Zookeeper的作用

配置管理

在我们的应用程序肯定会有很多的配置,例如数据库连接、日志等。一般都是通过配置文件的方式引入系统,当我们只有少数几种配置或只有一台服务器,并且不经常修改的情况下,这是一种很好的做法,但是当我们的配置文件非常多,存在很多应用服务器,那么在修改配置文件的时候是一件很恐怖的事情。这个时候就需要一种集中管理配置的方法,在这个集中管理的地方修改了配置,所有关系这个配置的地方都能获取变更并进行修改。
那么zookeeper如何实现呢?我们将配置信息放到zookeeper的某个目录节点中,然后所有相关的应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序都会收到zookeeper的通知,然后从zookeeper中获取最新的配置信息。

命名服务

命名服务就比较好理解了,以网络访问为例,通常我们如果要访问一个系统,需要知道这个系统服务的ip,但是ip对人来说是不友好的,那么我们可以通过域名来访问,但是计算机是无法直接识别出域名的。如果我们每台计算机上都存在一份域名到ip的映射,那么可以简单的解决这一问题。但是如果域名对应的ip发生了变化怎么办呢?于是我们有了DNS这个东西,我们只需要访问一个大家都熟知的点,它会告诉你这个域名对应的ip是什么。
而在我们的系统中存在类似的问题,当我们的服务特别多时,保存或者配置服务的地址就会变得非常不方便,同样的,如果我们访问一个大家都熟悉的点,这里提供统一的入口,在进行服务调用时不需要关心服务的具体地址,那么维护起来就方便的多了。
以两个服务调用为例,被调用的服务首先在zookeeper上创建以服务名命名的持久化顺序编号目录节点,然后创建临时子节点存储地址信息,为什么要创建一个父节点然后在子节点中存储地址信息呢?因为被调用方有可能是集群服务,那么就有多个地址可供访问。调用方根据服务名去zookeeper中获取创建的持久化顺序编号的目录节点,子节点若有多个的话随机获取一个得到子节点存储的地址信息。

分布式锁

为保证系统的可靠性,一般是将系统进行集群部署,如果一个任务每个集群中的服务都要运行的话就要相互协调,防止数据的不一致性。通常的做法是使用分布式锁,当一个服务持有锁的时候,其他服务等待,一旦锁释放,其他服务竞争锁,然后得到锁的服务运行,其他服务继续等待锁(这里只是简单的原理,实际肯定更为复杂)。
zookeeper实现分布式锁是利用文件系统的顺序编号目录节点,首先创建一个持久化顺序节点,每个线程或者系统获取锁前先创建自己的子目录节点,释放锁时删除自己创建的节点。由于子节点存在顺序并且递增,可以规定最小的那个节点获得锁,每个线程或者系统创建完属于自己的子节点后判断该节点是否最小,最小则获得锁,否则等待通知,只需要等待前一个节点的通知即可。当锁释放即节点删除时,后一个接到通知占有锁。这样第一个通知第二个,第二个通知第三个,击鼓传花似的依次向后。

集群管理

在分布式集群服务中,经常由于各种原因,比如硬件故障、网络问题、软件故障等,某些节点会进进出出,既有新的节点加入进来也有老的节点退出,这个时候集群的其他机器需要感知到这种变化,然后根据这种变化制订响应的策略。比如在一个分布式架构的系统中,服务是一个集群提供的,当消费者访问某个服务时,就需要采取某些机制发现现在还有哪些节点可以提供该服务,这也称之为服务发现。这里可以和zookeeper的命名服务配合理解,被调用方创建临时目录存储调用地址,如若退出集群,临时节点删除,消费者自然无法发现该服务。

设计目的

  1. 最终一致性:client 不论连接到哪个 Server,展示给它都是同一个视图,这是 zookeeper 最重要的性能。
  2. 可靠性:具有简单、健壮、良好的性能,如果消息 m 被到一台服务器接受,那么它 将被所有的服务器接受。
  3. 实时性:Zookeeper 保证客户端将在一个时间间隔范围内获得服务器的更新信息,或 者服务器失效的信息。但由于网络延时等原因,Zookeeper 不能保证两个客户端能同时得到 刚更新的数据,如果需要最新数据,应该在读数据之前调用 sync()接口。
  4. 等待无关(wait-free):慢的或者失效的 client 不得干预快速的 client 的请求,使得每 个 client 都能有效的等待。
  5. 原子性:更新只能成功或者失败,没有中间状态。
  6. 顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息 a 在消息 b 前发布,则在所有 Server 上消息 a 都将在消息 b 前被发布;偏序是指如果一个消息 b 在消 息 a 后被同一个发送者发布,a 必将排在 b 前面。

Zookeeper集群中的角色

zookeeper集群中的角色主要有以下三类:

  1. 领导者 Leader: 领导者负责进行投票的发起和决议,更新系统状态
  2. 学习者 Learner
  • 跟随者 Follower: 跟随者用于接收客户端请求并向客户端返回结果,在选主过程中参与投票
  • 观察者 Observer:观察者可以接收客户端连接,将写请求转发给leader节点,但观察者不参与投票过程,只同步leader的状态,观察者的目的是为了扩展系统,提高读取速度
  1. 客户端 Client:请求发起方
posted @ 2021-08-15 22:24  ~鲨鱼辣椒~  阅读(176)  评论(0编辑  收藏  举报