Zookeeper详解(六):Zookeeper的应用场景

Zookeeper是一个发布/订阅模式的分布式数据管理与协调框架,结合Watcher事件通知,能够搭建分布式框架中的不少核心功能。
算法


数据发布和订阅数据库

也就是经常使用的配置管理,将数据信息发布到一个或者多个ZK节点上,应用程序监听这些节点当有数据变化时就获取这些变化并应用到程序中,实现动态更新配置的功能。发布订阅中一般有推拉两种模式,ZK采用推拉结合,客户端注册感兴趣的节点,一旦节点发生变化服务器会发出Watcher事件通知(推),而后客户端收到消息后主动去服务器提取变化(拉)。编程

这种配置管理一般应用在具备配置通用性的场景中,好比机器列表、某些参数的开关或者数据库配置信息等。服务器

  • 这些信息一般体量小app

  • 在应用运行时会随时调整负载均衡

  • 这些应用(至少是某一组应用)都使用相同的配置框架

常规解决办法是本地配置文件或者内存变量(经过JMX方式对正在运行的JAVA程序进行修改)。这些常规办法在集群规模较小的时候比较方便可是集群规模一大管理就比较困难。编程语言

好比数据库配置信息变化分布式

  • 首先在ZK上建立一个节点叫作 /Configuration 这里面有一个APP名称节点表示特定APP,这个APP名称节点下面有一个叫作 dbConfig的节点用于存储数据库配置信息(/Configuration-->APP1-->dbConfig)ide

  • 而后将配置信息写入到这个节点(这些信息确定是序列化后写入的,若是在程序中不是以对象形式存在也能够不用序列化)

  • 应用程序启动后读取这个节点数据,而后在这个节点上注册一个Watcher事件,当数据有变化时再次读取该节点数据并应用到本身的程序上。


负载均衡

ZK提供的负载属于软负载均衡服务。一般的作法就是动态的DNS服务,若是你的机器数量比较少你能够手动在内网DNS上配置这些域名,你要知道一个域名就对应一个IP。若是集群规模比较大手动维护这些信息至关繁琐;另外你还能够采用HOST的方式就是在服务器上配置本地HOST把这些域名写进去,仍是同样的问题规模小传统方式都很好用,可是规模大尤为是有时候须要动态扩容或者缩容的时候你再去手动维护这些HOST或者DNS记录显然就不能知足业务需求。

在Zookeeper中如何解决呢?下面的名称就是名字不必定你也这样取,毕竟节点名称是自定义的。

  • 首先创建一个节点叫作 /DDNS 这下面包含全部应用的名字好比APP1,APP2等,每一个应用名字节点下面又一个域名好比  app1.servers.abc.com这样一个域名(/DDNS-->APP1-->app1.servers.abc.com)后面这个域名就是改APP1集群使用的,这个节点包含的数据能够是IP:PORT或者多个IP:PORT,看下图

        Snip20180623_87.png

  • 应用读取节点数据获取IP列表,而后根据负载均衡算法找到一个IP来使用,以后注册一个监听事件来监听该节点的变化

  • IP变动咱们只须要在该节点进行操做就能够

上面的过程仍是须要人工干预,如何改进一下呢?能够划分几个组件出来

  1. Register,负载域名动态注册的服务,这个服务能够是单台但最好是一个集群,服务提供者经过SDK向Register注册,也就是把服务提供者所使用域名和IP:PORT发给Register,它再获取ZK集群节点数据,加上本次注册的数据,产生一个新数据更新到ZK节点上

  2. Dispatcher,负载域名解析,经过域名向该服务查询获取IP:PORT列表,它监听ZK节点发生有变化以后就更新存储在本身内存中的信息,至关于域名使用者不直接去ZK节点读取数据。同时它还提供屏蔽功能,也就是说服务提供者均可用可是我能够设置只解析出部分服务提供者IP:PORT出来。

  3. Scanner,负载检查维护服务状态,它做用是检查服务提供者的可用性,这里采用服务提供者主动汇报自身状态的方式,这种状态能够包括不少信息服务是否可用、当前QPS、RT、JVM的资源状态等。Scanner会记录服务提供者每一次的状态。若是一段时间后(一般为几秒)发现有服务提供者没有汇报,那么就认为不可用,而后去更新ZK节点,把失败的IP:PORT信息删除。

  4. Monitor,负载监控DDNS系统自己的状态。

  5. Controller,是一个DDNS的后台管理端,负载管理上述组件以及必要时候的手工干预。

  6. SDK,服务提供者和消费者经过封装的SDK来和上述组件通讯。


命名服务

命名服务是分布式系统中的基本功能之一。被命名的实体一般能够是集群中的机器、提供的服务地址或者远程对象,这些均可以称做为名字。常见的就是一些分布式服务框架(RPC、RMI)中的服务地址列表,经过使用名称服务客户端能够获取资源的实体、服务地址和提供者信息。命名服务就是经过一个资源引用的方式来实现对资源的定位和使用。在分布式环境中,上层应用仅仅须要一个全局惟一名称,就像数据库中的主键。

在单库单表系统中能够经过自增ID来标识每一条记录,可是随着规模变大分库分表很常见,那么自增ID有仅能针对单一表生成ID,因此在这种状况下没法依靠这个来标识惟一ID。UUID就是一种惟一识别码在分布式中也会用到,最典型的GUID,全局惟一标识符。可是长度过长不易识别。

在Zookeeper中经过建立顺序节点就能够实现。你建立的时候只须要提供节点名称,至于序号它本身会返回一个。你每次使用的语句是相同的,可是因为顺序节点的特性它返回的内容不一样可是是有顺序的。那么你经过  type1-job00000000 这种就能够获得一个惟一ID。

Snip20180623_88.png


分布式协调/通知


集群管理

集群管理包括集群监控和集群控制。前者侧重收集集群运行状态,后者侧重对进行的操做和控制。场景的需求是

  • 获取当前集群有多少机器

  • 每一个机器运行的状态

  • 对集群机器上下线操做

在传统方式中一般使用Agent,Agent收集服务器信息向监控中心上报。在小规模环境中这种方式还比较适用。可是集群规模变大问题也就来了。

  • 大规模升级Agent困难,升级成本和进度

  • 统一的Agent没法知足多样要求,对硬件资源比较好办,可是若是涉及到对程序内部的监控Agent就容易一筹莫展了,这种东西不适合用一个统一的Agent来监控

  • 编程语言多样,你须要提供各类语言版本的Agent

经过Zookeeper怎么解决?利用节点监听和临时节点特性。


Master选举

简单来讲就是争抢Zookeeper上个一个节点且这个节点只能被一个机器争抢到,其余没有抢到的就在这个节点上注册监听变化。


分布式锁服务

相关文章
相关标签/搜索