中小研发团队架构实践之分布式协调器.Net版ZooKeeper

一、ZooKeeper是什么

Apache ZooKeeper是由Apache Hadoop的子项目发展而来,于2010年11月正式成为了Apache的顶级项目。

ZooKeeper是一个开放源代码的分布式协调服务。它具有高性能、高可用的特点,同时也具有严格的顺序访问控制能力(主要是写操作的严格顺序性)。基于对ZAB协议(ZooKeeper Atomic Broadcast,ZooKeeper原子消息广播协议)的实现,它能够很好地保证分布式环境中数据的一致性。也正是基于这样的特性,使得ZooKeeper成为了解决分布式数据一致性问题的利器。

二、ZooKeeper工作原理简介

2.1 ZooKeeper架构

 

中小研发团队架构实践之分布式协调器.Net版ZooKeeper

 

ZooKeeper整体架构

请见上图,文字说明如下:

ZooKeeper由两部分组成:ZooKeeper服务端和客户端。

ZooKeeper服务器采用集群的形式。值得一提的是,只要集群中存在超过一半的、处于正常工作状态的服务器,那么整个集群就能够正常对外服务。组成ZooKeeper集群的每台服务器都会在内存中维护当前的ZooKeeeper服务状态,并且每台服务器之间都互相保持着通信。

客户端在连接ZooKeeper服务集群时,会按照一定的随机算法选择集群中的某台服务器,然后和它共同创建一个TCP连接,使客户端连上到那台服务器。而当那台服务器失效时,客户端自动会重新选择另一台服务器进行连接,从而保证服务的连续性。

当其中一个客户端修改数据时,ZooKeeper会将修改同步到集群中所有的服务器上,从而使连接到集群中其它服务器上的客户端也能立即看到修改后的数据,很好地保证了分布式环境中数据的一致性。

2.2 ZooKeeper数据模型

 

中小研发团队架构实践之分布式协调器.Net版ZooKeeper

 

ZooKeeper数据模型

请见上图,文字说明如下:

Zookeeper的数据模型采用类似于文件系统的树结构。树上的每个节点称为ZNode,而每个节点都可能有一个或者多个子节点。ZNode的节点路径标识方式是由一系列斜杠【/】进行分割的路径表示。

可以向ZNode节点写入、修改、读取数据,也可以创建、删除ZNode节点或ZNode节点下的子节点。值得注意的是,ZooKeeper的设计目标不是传统的数据库存储或者大数据对象存储,而是协同数据的存储,因此在实现时ZNode存储的数据大小不应超过1MB。另外,每一个节点都有个ACL(Access Control List,访问控制列表),据此控制该节点的访问权限。

ZNode数据节点是有生命周期的,其生命周期的长短取决于数据节点的节点类型。节点类型共有4种:持久节点(PERSISTENT)、持久顺序节点(PERSISTENT_SEQUENTIAL)、临时节点(EPHEMERAL)、临时顺序节点(EPHEMERAL_SEQUENTIAL)。

2.3 Watcher:ZNode数据变化通知

ZooKeeper的Watcher机制,概括为三个过程:客户端注册Watcher成为订阅者、服务端处理Watcher以及客户端回调Watcher。

客户端在自己需要关注的位于ZooKeeper服务器里的ZNode节点上注册一个Watcher监听后,一旦这个ZNode节点发生变化,则在该节点上注册过Watcher监听的所有客户端会收到ZNode节点变化通知。在收到通知时,客户端通过回调Watcher做相应的处理,从而实现特定的功能。

三、ZooKeeper的典型应用场景

通过对ZooKeeper中丰富的数据节点类型进行交叉使用,配合Watcher事件通知机制,可以非常方便地构建分布式应用中都会涉及的核心功能,如:数据发布/订阅(即配置中心)、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等。

3.1 配置服务:ConfigServiceDemo

Demo中的【ConfigServiceDemo(配置服务Demo)】适用于ZooKeeper的配置中心应用场景:

应用中用到的一些常用配置信息放到ZooKeeper的一系列ZNode节点上,供应用获取配置数据;同时,如果某应用在需要关注的配置项节点上注册了个Watcher,则以后每次被关注的配置项有更新的时候,都会实时通知到该应用,从而达到获取最新配置信息的目的。

3.1.1 为公司解决了什么问题

a. 减少我们的运维工作人员的工作量:当公司的应用程序以集群环境模式被部署的时候,若第1次部署应用程序或遇到需要配置新增/修改/删除的情况,我们的运维工作人员不得不为集群中的每台服务器进行一台一台地修改。而利用了ZooKeeper后,他们只需要修改一次,就能为集群中的所有服务器完成配置新增/修改/删除。

b. 使任意客户端能够看到即时生效的被改后的配置数据:目前现状:由于运维工作人员需要为集群中的每台服务器进行一台一台地配置修改,而导致出现了配置延时问题,使得集群中的每台服务器的配置数据不一致。也就是说,客户端(如应用程序)可能会无法立即读取到最新的配置值,需要过段时间后才能读取到。当运维工作人员利用ZooKeeper修改配置数据后,新的配置数据会立即被同步到集群中的所有服务器,从而保证集群中的所有服务器的配置数据对于任意客户端而言每时每刻都是准确无误的(可选加Watcher)。

如果想免费学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java后端群:479499375,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。

3.1.2 ConfigService管理

下图显示的是ZooKeeper配置服务页面。

中小研发团队架构实践之分布式协调器.Net版ZooKeeper

 

3.2 Master选举:MasterElectionDemo

3.2.1 为公司解决了什么问题

我们都知道,集群中的服务器一般只有1台起着Master角色。一旦这台具有Master角色的服务器出现宕机情况,则就出现了服务器单点故障问题。并且,我们并不知道这台具有Master角色的服务器是从什么时候开始处于宕机状态。利用ZooKeeper的“对在ZooKeeper上创建的临时顺序节点(EPHEMERAL_SEQUENTIAL),一旦创建它的客户端与ZooKeeper服务集群之间的会话失效,那么该临时节点也就被自动清除”这一特性,再加上Watcher事件通知机制的使用,就能够解决服务器的单点故障问题——一旦当前具有Master角色的服务器宕机了,它创建的临时顺序节点(EPHEMERAL_SEQUENTIAL)会马上消失;紧接着集群中注册过Watcher的所有服务器会马上收到当前Master服务器已宕机的通知,然后将重新进行Master选举。

转载于:https://my.oschina.net/u/3967312/blog/3000221

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
什么是ZooKeeperZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。 ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。 Rabbit ZooKeeper Extensions 该项目使用了 Apache ZooKeeper .NET async Client 组件,除提供了基本的zk操作,还额外封装了常用的功能以便让.net开发者更好的使用zookeeper。 提供的功能 session过期重连 永久watcher 递归删除节点 递归创建节点 跨平台(支持.net core) 使用说明 创建连接 IZookeeperClient client = new ZookeeperClient(new ZookeeperClientOptions         {             ConnectionString = "172.18.20.132:2181",             BasePath = "/", //default value             ConnectionTimeout = TimeSpan.FromSeconds(10), //default value             SessionTimeout = TimeSpan.FromSeconds(20), //default value             OperatingTimeout = TimeSpan.FromSeconds(60), //default value             ReadOnly = false, //default value             SessionId = 0, //default value             SessionPasswd = null //default value         }); 创建节点 var data = Encoding.UTF8.GetBytes("2016"); //快速创建临时节点 await client.CreateEphemeralAsync("/year", data); await client.CreateEphemeralAsync("/year", data, ZooDefs.Ids.OPEN_ACL_UNSAFE); //快速创建永久节点 await client.CreatePersistentAsync("/year", data); await client.CreatePersistentAsync("/year", data, ZooDefs.Ids.OPEN_ACL_UNSAFE); //完整调用 await client.CreateAsync("/year", data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL); //递归创建 await client.CreateRecursiveAsync("/microsoft/netcore/aspnet", data, CreateMode.PERSISTENT); 获取节点数据 IEnumerable data = await client.GetDataAsync("/year"); Encoding.UTF8.GetString(data.ToArray()); 获取子节点 IEnumerable children= await client.GetChildrenAsync("/microsoft"); 判断节点是否存在 bool exists = await client.ExistsAsync("/year"); 删除节点 await client.DeleteAsync("/year"); //递归删除 bool success = await client.DeleteRecursiveAsync("/microsoft"); 更新数据 Stat stat = await client.SetDataAsync("/year", Encoding.UTF8.GetBytes("2017")); 订阅数据变化 await client.Subscrib

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值