设为首页 收藏本站
查看: 481|回复: 0

[经验分享] Zookeeper简介(一)

[复制链接]

尚未签到

发表于 2019-1-8 06:09:09 | 显示全部楼层 |阅读模式
一、ZK是干嘛的
  话说Google的三篇论文堪称分布式的经典:
  

    MapReduce=Hadoop  GFS:HDFS
  BigTable:HBase
  

  Zab:Zookeeper背后使用的一致性协议的(Zookeeper atomic broadcast protocol) 是 Google 的 Chubby一个开源的实现,是 Hadoop 的分布式协调服务
  简单来说:zk是分布式协调服务(a service for coordinating processes of distributed applications)
  在进程内进行协调我们可以使用语言,平台,操作系统等为我们提供的机制。
  在分布式环境中,由于网络的不可靠,一个服务的调用失败,并不表示一定是失败的。可能是执行成功了,但是返回失败了。
  还有,A和B都去调用C服务,在时间上A还先调用一些,B后调用,那么最后的结果是不是一定A的请求就先于B到达呢?
  在分布式环境中为了提升可靠性,我们往往会部署多套服务,但是如何在多套服务中达到一致性,这在同一个进程内很容易解决的问题,但在分布式环境中确实一个大难题。
  因此ZK应用而生
  官网解释:ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services.
  作用:配置管理、名称服务、分布式同步、集群管理

1、配置管理
  在我们的应用中除了代码外,还有一些就是各种配置。比如数据库连接等。一般我们都是使用配置文件的方式,在代码中引入这些配置文件。但是当我们只有一种配置,只有一台服务器,并且不经常修改的时候,使用配置文件是一个很好的做法,但是如果我们配置非常多,有很多服务器都需要这个配置,而且还可能是动态的话使用配置文件就不是个好主意了。这个时候往往需要寻找一种集中管理配置的方法,我们在这个集中的地方修改了配置,所有对这个配置感兴趣的都可以获得变更。比如我们可以把配置放在数据库里,然后所有需要配置的服务都去这个数据库读取配置。但是,因为很多服务的正常运行都非常依赖这个配置,所以需要这个集中提供配置服务的服务具备很高的可靠性。一般我们可以用一个集群来提供这个配置服务,但是用集群提升可靠性,那如何保证配置在集群中的一致性呢? 这个时候就需要使用一种实现了一致性协议的服务了。Zookeeper就是这种服务,它使用Zab这种一致性协议来提供一致性。现在有很多开源项目使用Zookeeper来维护配置,比如在HBase中,客户端就是连接一个Zookeeper,获得必要的HBase集群的配置信息,然后才可以进一步操作。还有在开源的消息队列Kafka中,也使用Zookeeper来维护broker的信息。在Alibaba开源的SOA框架Dubbo中也广泛的使用Zookeeper管理一些配置来实现服务治理。
  //rsync+inontify可以在一定程度上简单实现

2、名称服务
  名字服务这个就很好理解了。比如为了通过网络访问一个系统,我们得知道对方的IP地址,但是IP地址对人非常不友好,这个时候我们就需要使用域名来访问。但是计算机是不能识别域名的。怎么办呢?如果我们每台机器里都备有一份域名到IP地址的映射,这个倒是能解决一部分问题,但是如果域名对应的IP发生变化了又该怎么办呢?于是我们有了DNS这个东西。我们只需要访问一个大家熟知的(known)的点,它就会告诉你这个域名对应的IP是什么。在我们的应用中也会存在很多这类问题,特别是在我们的服务特别多的时候,如果我们在本地保存服务的地址的时候将非常不方便,但是如果我们只需要访问一个大家都熟知的访问点,这里提供统一的入口,那么维护起来将方便得多了。
  //类似DNS

3、分布式锁
  利用Zookeeper来协调多个分布式进程之间的活动。比如在一个分布式环境中,为了提高可靠性,我们的集群的每台服务器上都部署着同样的服务。但是,一件事情如果集群中的每个服务器都进行的话,那相互之间就要协调,编程起来将非常复杂。而如果我们只让一个服务进行操作,那又存在单点。通常还有一种做法就是使用分布式锁,在某个时刻只让一个服务去干活,当这台服务出问题的时候锁释放,立即fail over到另外的服务。这在很多分布式系统中都是这么做,这种设计有一个更好听的名字叫Leader Election(leader选举)。比如HBase的Master就是采用这种机制。但要注意的是分布式锁跟同一个进程的锁还是有区别的,所以使用的时候要比同一个进程里的锁更谨慎的使用。
  //资源协调

4、集群管理
  在分布式的集群中,经常会由于各种原因,比如硬件故障,软件故障,网络问题,有些节点会进进出出。有新的节点加入进来,也有老的节点退出集群。这个时候,集群中其他机器需要感知到这种变化,然后根据这种变化做出对应的决策。比如我们是一个分布式存储系统,有一个中央控制节点负责存储的分配,当有新的存储进来的时候我们要根据现在集群目前的状态来分配存储节点。这个时候我们就需要动态感知到集群目前的状态。还有,比如一个分布式的SOA架构中,服务是一个集群提供的,当消费者访问某个服务时,就需要采用某种机制发现现在有哪些节点可以提供该服务
  (这也称之为服务发现Zookeeper作为服务发现的底层机制)。还有开源的Kafka队列就采用了Zookeeper作为Cosnumer的上下线管理。
  //服务发现与拆除

二、ZK相关概念介绍

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

2、ZK特点
  图1:

  (1)Zookeeper是可重用的
  组成Zookeeper的各个服务器必须要能相互通信。他们在内存中保存了服务器状态,也保存了操作的日志,并且持久化快照。只要大多数的服务器是可用的,那么Zookeeper就是可用的。
  客户端连接到一个Zookeeper服务器,并且维持TCP连接。并且发送请求,获取回复,获取事件,并且发送连接信号。如果这个TCP连接断掉了,那么客户端可以连接另外一个服务器。
  (2)Zookeeper是有序的
  Zookeeper使用数字来对每一个更新进行标记。这样能保证Zookeeper交互的有序。后续的操作可以根据这个顺序实现诸如同步操作这样更高更抽象的服务。
  (3)Zookeeper是高效的
  Zookeeper的高效更表现在以读为主的系统上。Zookeeper可以在千台服务器组成的读写比例大约为10:1的分布系统上表现优异。
  (4)数据结构和分等级的命名空间
  Zookeeper的命名空间的结构和文件系统很像。一个名字和文件一样使用/的路径表现,zookeeper的每个节点都是被路径唯一标识
  ZooKeeper's Hierarchical Namespace
  图2:


3、zk的存储结构
  图3:

  zookeeper中的数据是按照“树”结构进行存储的。而且znode节点还分为4中不同的类型。

(1)、znode
  zookeeper集群自身维护了一套数据结构。这个存储结构是一个树形结构,其上的每一个节点,我们称之为“znode”。如下所示:
  图2-3-1

  每一个znode默认能够存储1MB的数据(对于记录状态性质的数据来说,够了)
  可以使用zkCli命令,登录到zookeeper上,并通过ls、create、delete、sync等命令操作这些znode节点
  znode除了名称、数据以外,还有一套属性:zxid。这套zid与时间戳对应,记录zid不同的状态
  Znode结构信息
  图2-3-2

  此外,znode还有操作权限。如果我们把以上几类属性细化,又可以得到以下属性的细节:
  

    czxid:创建节点的事务的zxid  mzxid:对znode最近修改的zxid
  ctime:以距离时间原点(epoch)的毫秒数表示的znode创建时间
  mtime:以距离时间原点(epoch)的毫秒数表示的znode最近修改时间
  version:znode数据的修改次数
  cversion:znode子节点修改次数
  aversion:znode的ACL修改次数
  ephemeralOwner:如果znode是临时节点,则指示节点所有者的会话ID;如果不是临时节点,则为零。
  dataLength:znode数据长度。
  numChildren:znode子节点个数。
  

(2)、znode中的存在类型
  zookeeper内部维护了一套数据结构:由znode构成的集合,znode的集合又是一个树形结构。每一个znode又有很多属性进行描述。并且znode的存在性还分为四类,如下如所示:
  图2-3-3

  znode是由客户端创建的,它和创建它的客户端的内在联系,决定了它的存在性:
  zookeeper中的数据是按照“树”结构进行存储的。而且znode节点还分为4中不同的类型。
  1)PERSISTENT-持久化目录节点
  客户端与zookeeper断开连接后,该节点依旧存在(除非用API强制删除)
  2)PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点
  客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号
  zookeeper会根据parent-znode的zxid状态,为这个A节点编写一个全目录唯一的编号(这个编号只会一直增长)。
  3)EPHEMERAL-临时目录节点
  客户端与zookeeper断开连接后,该节点(以及子节点)被删除
  4)EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点
  客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号
  无论是EPHEMERAL还是EPHEMERAL_SEQUENTIAL节点类型,在zookeeper的client异常终止后,节点也会被删除。
  Zk的数据结构:图4

  Zookeeper 这种数据结构有如下这些特点:
  每个子目录项如 NameService 都被称作为 znode,这个 znode 是被它所在的路径唯一标识,如 Server1 这个 znode 的标识为 /NameService/Server1
  znode 可以有子节点目录,并且每个 znode 可以存储数据,注意 EPHEMERAL 类型的目录节点不能有子节点目录
  znode 是有版本的,每个 znode 中存储的数据可以有多个版本,也就是一个访问路径中可以存储多份数据
  znode 可以是临时节点,一旦创建这个 znode 的客户端与服务器失去联系,这个 znode 也将自动删除,Zookeeper 的客户端和服务器通信采用长连接方式,每个客户端和服务器通过心跳来保持连接,这个连接状态称为 session,如果 znode 是临时节点,这个 session 失效,znode 也就删除了
  znode 的目录名可以自动编号,如 App1 已经存在,再创建的话,将会自动命名为 App2
  znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个是 Zookeeper 的核心特性,Zookeeper 的很多功能都是基于这个特性实现的,后面在典型的应用场景中会有实例介绍

(3)、zk中的选举FastLeaderELection
  zk集群中一个leader其他都是flower状态zookeeper中的选举规则,默认的选举规则称为:FastLeaderELection
  FastLeaderELection的中心思想:
  1)全天下我最牛,在我没有发现比我牛的推荐人的情况下,我就一直推举我当leader。第一次投票那必须推举我自己当leader。
  2)每当我接收到其它的被推举者,我都要回馈一个信息,表明我还是不是推举我自己。如果被推举者没我大,我就一直推举我当leader,是我是我还是我!
  3)我有一个票箱, 和我属于同一轮的投票情况都在这个票箱里面。一人一票 重复的或者过期的票,我都不接受。
  4)一旦我不再推举我自己了(这时我发现别人推举的人比我推荐的更牛),我就把我的票箱清空,重新发起一轮投票(这时我的票箱一定有两票了,都是选的我认为最牛的人)。
  5)一旦我发现收到的推举信息中投票轮要高于我的投票轮,我也要清空我的票箱。并且还是投当初我觉得最牛的那个人(除非当前的人比我最初的推荐牛,我就顺带更新我的推荐)。
  6)不断的重复上面的过程,不断的告诉别人“我的投票是第几轮”、“我推举的人是谁”。直到我的票箱中“我推举的最牛的人”收到了不少于 N /2 + 1的推举投票。
  7)这时我就可以决定我是flower还是leader了(如果至始至终都是我最牛,那我就是leader咯,其它情况就是follower咯)。并且不论随后收到谁的投票,都向它直接反馈“我的结果”。
  图6:


三、zk的事件和状态
  zk的事件和状态
  事件和状态构成了zookeeper客户端连接描述的两个维度。

1、zookeeper客户端与zookeeper server连接的状态
  连接状态    状态含义
  KeeperState.Expired     客户端和服务器在ticktime的时间周期内,是要发送心跳通知的。这是租约协议的一个实现。客户端发送request,告诉服务器其上一个租约时间,服务器收到这个请求后,告诉客户端其下一个租约时间是哪个时间点。当客户端时间戳达到最后一个租约时间,而没有收到服务器发来的任何新租约时间,即认为自己下线(此后客户端会废弃这次连接,并试图重新建立连接)。这个过期状态就是Expired状态
  KeeperState.Disconnected    就像上面那个状态所述,当客户端断开一个连接(可能是租约期满,也可能是客户端主动断开)这是客户端和服务器的连接就是Disconnected状态
  KeeperState.SyncConnected   一旦客户端和服务器的某一个节点建立连接(注意,虽然集群有多个节点,但是客户端一次连接到一个节点就行了),并完成一次version、zxid的同步,这时的客户端和服务器的连接状态就是SyncConnected
  KeeperState.AuthFailed  zookeeper客户端进行连接认
  需要说明的是,这些状态在触发时,所记录的事件类型都是:EventType.None

2、zookeeper中的事件。当zookeeper客户端监听某个znode节点”/node-x”时:
  zookeeper事件     事件含义
  EventType.NodeCreated   当node-x这个节点被创建时,该事件被触发
  EventType.NodeChildrenChanged   当node-x这个节点的直接子节点被创建、被删除、子节点数据发生变更时,该事件被触发。
  EventType.NodeDataChanged   当node-x这个节点的数据发生变更时,该事件被触发
  EventType.NodeDeleted   当node-x这个节点被删除时,该事件被触发。
  EventType.None  当zookeeper客户端的连接状态发生变更时,即KeeperState.Expired、KeeperState.Disconnected、KeeperState.SyncConnected、KeeperState.AuthFailed状态切换时,描述的事件类型为EventType.None

四、watcher机制
  Zookeeper C API 的声明和描述在 include/zookeeper.h 中可以找到,另外大部分的 Zookeeper C API 常量、结构体声明也在 zookeeper.h 中,如果如果你在使用 C API 是遇到不明白的地方,最好看看 zookeeper.h,或者自己使用 doxygen 生成 Zookeeper C API 的帮助文档。
  Zookeeper 中最有特色且最不容易理解的是监视(Watches)。Zookeeper 所有的读操作——getData(), getChildren(), 和 exists() 都 可以设置监视(watch),监视事件可以理解为一次性的触发器, 官方定义如下: a watch event is one-time trigger, sent to the client that set the watch, which occurs when the data for which the watch was set changes。对此需要作出如下理解:

1、(一次性触发)One-time trigger
  当设置监视的数据发生改变时,该监视事件会被发送到客户端,例如,如果客户端调用了 getData("/znode1", true) 并且稍后 /znode1 节点上的数据发生了改变或者被删除了,客户端将会获取到 /znode1 发生变化的监视事件,而如果 /znode1 再一次发生了变化,除非客户端再次对 /znode1 设置监视,否则客户端不会收到事件通知。

2、(发送至客户端)Sent to the client
  Zookeeper 客户端和服务端是通过 socket 进行通信的,由于网络存在故障,所以监视事件很有可能不会成功地到达客户端,监视事件是异步发送至监视者的,Zookeeper 本身提供了保序性(ordering guarantee):即客户端只有首先看到了监视事件后,才会感知到它所设置监视的 znode 发生了变化(a client will never see a change for which it has set a watch until it first sees the watch event). 网络延迟或者其他因素可能导致不同的客户端在不同的时刻感知某一监视事件,但是不同的客户端所看到的一切具有一致的顺序。

3、(被设置 watch 的数据)The data for which the watch was set
  这意味着 znode 节点本身具有不同的改变方式。你也可以想象 Zookeeper 维护了两条监视链表:数据监视和子节点监视(data watches and child watches) getData() and exists() 设置数据监视,getChildren() 设置子节点监视。 或者,你也可以想象 Zookeeper 设置的不同监视返回不同的数据,getData() 和 exists() 返回 znode 节点的相关信息,而 getChildren() 返回子节点列表。因此, setData() 会触发设置在某一节点上所设置的数据监视(假定数据设置成功),而一次成功的 create() 操作则会出发当前节点上所设置的数据监视以及父节点的子节点监视。一次成功的 delete() 操作将会触发当前节点的数据监视和子节点监视事件,同时也会触发该节点父节点的child watch。
  Zookeeper 中的监视是轻量级的,因此容易设置、维护和分发。当客户端与 Zookeeper 服务器端失去联系时,客户端并不会收到监视事件的通知,只有当客户端重新连接后,若在必要的情况下,以前注册的监视会重新被注册并触发,对于开发人员来说 这通常是透明的。只有一种情况会导致监视事件的丢失,即:通过 exists() 设置了某个 znode 节点的监视,但是如果某个客户端在此 znode 节点被创建和删除的时间间隔内与 zookeeper 服务器失去了联系,该客户端即使稍后重新连接 zookeeper服务器后也得不到事件通知。

4、提醒
  一个节点可以注册多个watcher,但是分成两种情况,当一个watcher实例多次注册时,zkClient也只会通知一次;当多个不同的watcher实例都注册时,zkClient会依次进行通知(并不是很多网贴粗略说的“多次注册一次通知”)
  监控同一个节点X的一个watcher实例,通过exist、getData等注册方式多次注册的,zkClient也只会通知一次。
  注意,很多网贴都说zk.getData(“/node-x”,watcher)这种注册方式可以监控节点的NodeCreated事件,实际上是不行的(或者说没有意义)。当一个节点还不存在时,zk.getData这样设置的watcher是会抛出KeeperException$NoNodeException异常的,这次注册会失败,watcher也不会起作用;一旦node-x节点存在了,那这个节点的NodeCreated事件又有什么意义呢?
  zookeeper中并没有“永久监听”这种机制。网上所谓实现了”永久监听”的帖子,只是一种编程技巧。思路可以归为两类:一种是“在保证所有节点的watcher都被重新注册”的前提下,再进行目录、子目录的更改;另外一种是“在监听被触发后,被重新注册前,重新取一次节点的信息”确保在“监听真空期”znode没有变化。 有兴趣的读者可自行百度。
  ZK监听真空期
  图7:

  真空期:注册监听后主动检查本次节点的znode-version和上次节点的znode-version是否一致,来确定是否真空期有节点变化。

五、zk的工作原理
  ZK的核心是原子广播,保证server之间的同步,基于Zab协议实现。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。
  为了保证事务的顺序一致性,zookeeper采用了递增的事务id号(zxid)来标识事务。所有的提议(proposal)都在被提出的时候加上了zxid。实现中zxid是一个64位的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的统治时期。低32位用于递增计数。
  每个Server在工作过程中有三种状态:
  LOOKING:当前Server不知道leader是谁,正在搜寻
  LEADING:当前Server即为选举出来的leader
  FOLLOWING:leader已经选举出来,当前Server与之同步

1、ZK的选主流程
  当leader崩溃或者leader失去大多数的follower,这时候zk进入恢复模式,恢复模式需要重新选举出一个新的leader,让所有的Server都恢复到一个正确的状态。Zk的选举算法有两种:一种是基于basic paxos实现的,另外一种是基于fast paxos算法实现的。系统默认的选举算法为fast paxos。先介绍basic paxos流程:
  1)选举线程由当前Server发起选举的线程担任,其主要功能是对投票结果进行统计,并选出推荐的Server;
  2)选举线程首先向所有Server发起一次询问(包括自己);
  3)选举线程收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中;
  4)收到所有Server回复以后,就计算出zxid最大的那个Server,并将这个Server相关信息设置成下一次要投票的Server;
  5)线程将当前zxid最大的Server设置为当前Server要推荐的Leader,如果此时获胜的Server获得n/2 + 1的Server票数, 设置当前推荐的leader为获胜的Server,将根据获胜的Server相关信息设置自己的状态,否则,继续这个过程,直到leader被选举出来。
  通过流程分析我们可以得出:要使Leader获得多数Server的支持,则Server总数必须是奇数2n+1,且存活的Server的数目不得少于n+1.
  每个Server启动后都会重复以上流程。在恢复模式下,如果是刚从崩溃状态恢复的或者刚启动的server还会从磁盘快照中恢复数据和会话信息,zk会记录事务日志并定期进行快照,方便在恢复时进行状态恢复。
  fast paxos流程是在选举过程中,某Server首先向所有Server提议自己要成为leader,当其它Server收到提议以后,解决epoch和zxid的冲突,并接受对方的提议,然后向对方发送接受提议完成的消息,重复这个流程,最后一定能选举出Leader。

2、工作流程
  Leader主要有三个功能:
  1)恢复数据;
  2)维持与Learner的心跳,接收Learner请求并判断Learner的请求消息类型;
  3)Learner的消息类型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根据不同的消息类型,进行不同的处理。
  PING消息是指Learner的心跳信息;REQUEST消息是Follower发送的提议信息,包括写请求及同步请求;ACK消息是Follower的对提议的回复,超过半数的Follower通过,则commit该提议;REVALIDATE消息是用来延长SESSION有效时间。
  //三个线程维护
  Follower工作流程:
  Follower主要有四个功能:
  1)向Leader发送请求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息);
  2)接收Leader消息并进行处理;
  3)接收Client的请求,如果为写请求,发送给Leader进行投票;
  4)返回Client结果。
  Follower的消息循环处理如下几种来自Leader的消息:
  1)PING消息: 心跳消息;
  2)PROPOSAL消息:Leader发起的提案,要求Follower投票;
  3)COMMIT消息:服务器端最新一次提案的信息;
  4)UPTODATE消息:表明同步完成;
  5)REVALIDATE消息:根据Leader的REVALIDATE结果,关闭待revalidate的session还是允许其接受消息;
  6)SYNC消息:返回SYNC结果到客户端,这个消息最初由客户端发起,用来强制得到最新的更新。
  //Follower是通过5个线程来实现该功能的
  observer流程和Follower的唯一不同的地方就是observer不会参加leader发起的投票。

六、zk的运用场景
  数据发布与订阅 //应用配置集中到节点上,应用启动时主动获取,并在节点上注册一个watcher,每次配置更新都会通知到应用。
  命名空间服务 //分布式命名服务,创建一个节点后,节点的路径就是全局唯一的,可以作为全局名称使用。
  分布式通知 ///协调不同的系统都监听同一个节点,一旦有了更新,另一个系统能够收到通知。
  分布式锁  //Zookeeper能保证数据的强一致性,用户任何时候都可以相信集群中每个节点的数据都是相同的。一个用户创建一个节点作为锁,另一个用户检测该节点,如果存在,代表别的用户已经锁住,如果不存在,则可以创建一个节点,代表拥有一个锁。
  集群管理 //每个加入集群的机器都创建一个节点,写入自己的状态。监控父节点的用户会受到通知,进行相应的处理。离开时删除节点,监控父节点的用户同样会收到通知。
  主流应用场景:

(1)配置管理
  集中式的配置管理在应用集群中是非常常见的,一般商业公司内部都会实现一套集中的配置管理中心,应对不同的应用集群对于共享各自配置的需求,并且在配置变更时能够通知到集群中的每一个机器。
  Zookeeper很容易实现这种集中式的配置管理,比如将APP1的所有配置配置到/APP1 znode下,APP1所有机器一启动就对/APP1这个节点进行监控(zk.exist("/APP1",true)),并且实现回调方法Watcher,那么在zookeeper上/APP1 znode节点下数据发生变化的时候,每个机器都会收到通知,Watcher方法将会被执行,那么应用再取下数据即可(zk.getData("/APP1",false,null));
  以上这个例子只是简单的粗颗粒度配置监控,细颗粒度的数据可以进行分层级监控,这一切都是可以设计和控制的。

(2)集群管理
  应用集群中,我们常常需要让每一个机器知道集群中(或依赖的其他某一个集群)哪些机器是活着的,并且在集群机器因为宕机,网络断链等原因能够不在人工介入的情况下迅速通知到每一个机器。
  Zookeeper同样很容易实现这个功能,比如我在zookeeper服务器端有一个znode叫/APP1SERVERS,那么集群中每一个机器启动的时候都去这个节点下创建一个EPHEMERAL类型的节点,比如server1创建/APP1SERVERS/SERVER1(可以使用ip,保证不重复),server2创建/APP1SERVERS/SERVER2,然后SERVER1和SERVER2都watch /APP1SERVERS这个父节点,那么也就是这个父节点下数据或者子节点变化都会通知对该节点进行watch的客户端。因为EPHEMERAL类型节点有一个很重要的特性,就是客户端和服务器端连接断掉或者session过期就会使节点消失,那么在某一个机器挂掉或者断链的时候,其对应的节点就会消失,然后集群中所有对/APP1SERVERS进行watch的客户端都会收到通知,然后取得最新列表即可。
  另外有一个应用场景就是集群选master,一旦master挂掉能够马上能从slave中选出一个master,实现步骤和前者一样,只是机器在启动的时候在APP1SERVERS创建的节点类型变为EPHEMERAL_SEQUENTIAL类型,这样每个节点会自动被编号
  我们默认规定编号最小的为master,所以当我们对/APP1SERVERS节点做监控的时候,得到服务器列表,只要所有集群机器逻辑认为最小编号节点为master,那么master就被选出,而这个master宕机的时候,相应的znode会消失,然后新的服务器列表就被推送到客户端,然后每个节点逻辑认为最小编号节点为master,这样就做到动态master选举。
  参考博客:
  https://www.cnblogs.com/yuyijq/p/3424473.html
  https://blog.csdn.net/guchuanyun111/article/details/52091318
  http://www.cnblogs.com/raphael5200/p/5285380.html
  https://www.w3cschool.cn/zookeeper/zookeeper_fundamentals.html



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-660467-1-1.html 上篇帖子: dubbo+zookeeper小例子 下篇帖子: 基于docker搭建zookeeper集群
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表