shanghaipc 发表于 2019-1-8 12:38:05

zookeeper的虚拟文件系统

  ZooKeeper是分布式应用中的一种框架。
  ZooKeeper能干什么哪?我总结了一句话,就是:ZooKeeper是用来保证数据在集群间的事务性一致。
  我们细细品一下这句话,可以获得以下认识:

[*]  ZK是集群部署的;
[*]  集群之间是传递数据的;
[*]  集群之间传递的数据必须保证在各个节点之间的事务性一致;
  这是我们获得的认识。
  下面谈一谈,ZK到底是怎么一回事?
  简单地讲,ZK是一个文件系统,类似于Linux的文件,有根路径“/”,根目录下各级子目录,可以有一级一级的子目录。在ZK中,目录被称作“节点”。与linux不同的是,ZK的节点是可以存放数据的。也就是说,ZK中保存的数据是存放在节点中的。
  既然节点是一级级的。那么,必然有父节点,有子节点。谈这个话题有什么用?继续向下看。
  在ZK中,还有一个很重要的特性,就是事件的监听机制。
  当我们想在ZK中建立节点、删除节点、修改节点值等时候,都会产生事件,注册了事件监听器的类,就可以获得这些事件。换句话说,只要ZK的节点变化了,那么数据肯定变化,那么注册器通过监控节点的变化就可以知道数据的变化。那么而这正是ZK的无比强大之处。
  总结一下,ZK中数据的通知机制是通过对节点变化的监听机制实现的。
  下面,看一下ZK的应用场景吧!

[*]  统一命名服务
  举例子,公司有很多业务系统,这些业务系统都需要某种单据号,那么这个单据号肯定在所有系统中都是唯一的,在不指定哪个系统产生该单据号的情况下,可以使用ZK做这件事情。ZK可以保证原子性,不会因为多个系统的争抢造成不一致。

[*]  统一配置管理
  比如,公司的一套产品部署了N多的客户,你现在要对配置文件升级,那么你不会挨家挨户的去修改,那真是累死人的。我们可以在ZK中设定一个更新地址,让所有的产品都从这个地址下载。当需要升级的时候,可以修改该节点的值。每次升级,改一次值。这样,所有客户那边就可以自动升级了,不必我们跑来跑去了。

[*]  集群中管理
  对于运维工作而言,集群的管理非常重要,有服务器down掉那是非常要紧的事情,必须第一时间知道。那么,服务器down有可能是断电,网络中断等各种原因。服务器 一旦down掉,它是没有办法向外界发送求救信号的。怎么办?当服务器启动时,在ZK集群建立一个连接,如果服务器down掉,那么连接就中断了,那么ZK那么就知道有服务器down掉了,这时候ZK就可以对外发送求救信号了。

[*]  独占锁实现
  在多系统架构中,有些资源是独占的,也就是说同一时刻只能有一个系统在用。如果是虚拟机内部,可以通过synchronized关键字实现,但是系统之间就无能为力了。可以这样做:当系统占用资源时,去ZK创建一个指定节点;如果其他系统想要占用资源,也要去创建相同的节点,但是发现已经被创建了,那么就不能再次创建,只能等待。这就实现了独占锁机制了。
  ZK的特性还有很多,需要我们把这些特性应用到具体的工作中。
  有的同学想:为什么原来没有这样的东西啊?因为ZK是分布式系统,在单机下是用不上这套东西的。只有到了分布式环境下,才有ZK的用武之地!
  二、            zookeeper提供了什么
  简单的说,zookeeper=文件系统+通知机制。
  1、 文件系统
  Zookeeper维护一个类似文件系统的数据结构:
  
  每个子目录项如 NameService 都被称作为 znode,和文件系统一样,我们能够自由的增加、删除znode,在一个znode下增加、删除子znode,唯一的不同在于znode是可以存储数据的。
  有四种类型的znode:
  1、PERSISTENT-持久化目录节点
  客户端与zookeeper断开连接后,该节点依旧存在
  2、 PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点
  客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号
  3、EPHEMERAL-临时目录节点
  客户端与zookeeper断开连接后,该节点被删除
  4、EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点
  客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号
  2、 通知机制
  客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、被删除、子目录节点增加删除)时,zookeeper会通知客户端。
  就这么简单,下面我们看看能做点什么呢?
  三、            我们能用zookeeper做什么
  1、 命名服务
  这个似乎最简单,在zookeeper的文件系统里创建一个目录,即有唯一的path。在我们使用tborg无法确定上游程序的部署机器时即可与下游程序约定好path,通过path即能互相探索发现,不见不散了。
  2、 配置管理
  程序总是需要配置的,如果程序分散部署在多台机器上,要逐个改变配置就变得困难。好吧,现在把这些配置全部放到zookeeper上去,保存在 Zookeeper 的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到 Zookeeper 的通知,然后从 Zookeeper 获取新的配置信息应用到系统中就好。
  
  3、 集群管理
  所谓集群管理无在乎两点:是否有机器退出和加入、选举master。
  对于第一点,所有机器约定在父目录GroupMembers下创建临时目录节点,然后监听父目录节点的子节点变化消息。一旦有机器挂掉,该机器与zookeeper的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个兄弟目录被删除,于是,所有人都知道:它上船了。新机器加入也是类似,所有机器收到通知:新兄弟目录加入,highcount又有了。
  对于第二点,我们稍微改变一下,所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为master就好。
  
  4、分布式锁
  有了zookeeper的一致性文件系统,锁的问题变得容易。锁服务可以分为两类,一个是保持独占,另一个是控制时序。
  对于第一类,我们将zookeeper上的一个znode看作是一把锁,通过createznode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。厕所有言:来也冲冲,去也冲冲,用完删除掉自己创建的distribute_lock 节点就释放出锁。
  对于第二类, /distribute_lock 已经预先存在,所有客户端在它下面创建临时顺序编号目录节点,和选master一样,编号最小的获得锁,用完删除,依次方便。
  5、队列管理
  两种类型的队列:
  1、 同步队列,当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达。
  2、队列按照 FIFO 方式进行入队和出队操作。
  第一类,在约定目录下创建临时目录节点,监听节点数目是否是我们要求的数目。
  第二类,和分布式锁服务中的控制时序场景基本原理一致,入列有编号,出列按编号。
  终于了解完我们能用zookeeper做什么了,可是作为一个程序员,我们总是想狂热了解zookeeper是如何做到这一点的,单点维护一个文件系统没有什么难度,可是如果是一个集群维护一个文件系统保持数据的一致性就非常困难了。
  四、            分布式与数据复制
  Zookeeper作为一个集群提供一致的数据服务,自然,它要在所有机器间做数据复制。数据复制的好处:
  1、 容错
  一个节点出错,不致于让整个系统停止工作,别的节点可以接管它的工作;
  2、提高系统的扩展能力
  把负载分布到多个节点上,或者增加节点来提高系统的负载能力;
  3、提高性能
  让客户端本地访问就近的节点,提高用户访问速度。
  从客户端读写访问的透明度来看,数据复制集群系统分下面两种:
  1、写主(WriteMaster)
  对数据的修改提交给指定的节点。读无此限制,可以读取任何一个节点。这种情况下客户端需要对读与写进行区别,俗称读写分离;
  2、写任意(Write Any)
  对数据的修改可提交给任意的节点,跟读一样。这种情况下,客户端对集群节点的角色与变化透明。
  对zookeeper来说,它采用的方式是写任意。通过增加机器,它的读吞吐能力和响应能力扩展性非常好,而写,随着机器的增多吞吐能力肯定下降(这也是它建立observer的原因),而响应能力则取决于具体实现方式,是延迟复制保持最终一致性,还是立即复制快速响应。
  我们关注的重点还是在如何保证数据在集群所有机器的一致性,这就涉及到paxos算法。

页: [1]
查看完整版本: zookeeper的虚拟文件系统