服务器集群是什么意思 ZooKeeper八种典型应用场景详细介绍

ZooKeeper八种典型应用场景详细介绍

为了进一步增进对zk的认识,了解zk的作用,下面就zk在生产环境中的典型应用场景进行详细的介绍。

1. 配置维护 1.1 什么是配置维护

在分布式系统中,很多服务都是以集群的方式部署的,也就是多台服务器部署了完全相同的应用,起到完全相​​同的作用,当然集群中的这些服务器的配置文件也是完全相同的。

如果需要修改集群中服务器的配置文件,我们需要逐个修改这些服务器的配置文件。如果我们的集群中服务器比较少服务器集群是什么意思,那么这些修改还不算太麻烦,但如果集群中的服务器非常多,比如一些大型互联网公司的 Hadoop 集群有上千台服务器,那么手动更改这些配置文件几乎是一个不可能完成的任务。即便动用大量人员进行修改是可行的,但如果涉及的人太多,出错的概率也会大大增加,这对集群来说是非常危险的。

1.2 实现原理

zk可以通过“发布/订阅模型”来管理和维护集群配置文件,“发布/订阅模型”分为推送模式(Push)和拉取模式(Pull),zk的“发布/订阅模型”采用了推送和拉取模式相结合的方式。

与Nacos、Spring Cloud Config、携程Apollo功能相同

实现这一目标的具体步骤是:

2. 命名服务 2.1 什么是命名服务

命名服务是指可以赋予一定范围内的元素一个唯一的标识,以区别于其他元素。在分布式系统中,命名实体可以是集群中的主机、服务地址等。

2.2 实现原理

利用zk中节点路径不可重复的特性来实现命名服务,当然也可以利用顺序节点的有序性来体现唯一标识的有序性。

具体实现步骤:

3.集群管理

对于集群来说,我们总是希望能够随时获取当前集群中各个主机的运行状态,当前集群中主机的存活状态等信息,通过zk可以随时对集群进行监控。

3.1 基本原理

zk集群管理的基本原理如下图所示。

图表:

监控系统启动时,首先在ZK中注册/clusterManager根节点,并在子节点列表中注册Watcher监听变化

服务器集群是什么意思_集群服务器配置_集群服务器架构

一旦被监控集群的主机启动起来,就会在/clusterManager根节点下创建对应的临时子节点(临时节点的好处是如果被监控的服务器挂了服务器集群是什么意思,session就没有了,临时节点也就没了)

一旦被监控的集群中有新节点加入或者崩溃,就会触发子节点列表变化事件,监控系统会触发Watcher回调来更新信息,比如读取所有子节点列表展示在界面上,也就是展示存活状态。

被监控主机除了显示生存状态之外,还可以定期向自身节点更新其他状态数据,以便监控系统可以随时获取这些状态数据。

具体实施步骤为:

Step3:监控系统在根节点/clusterManager上注册一个watcher监听器,一旦集群中增加或者减少主机,就会触发子节点数量变化的watcher事件,然后zk会把事件推送到监控系统Step4:监控系统收到zk发送的事件后,调用对应的watcher对象回调,把变化展示到监控平台。Step5:如果集群主机状态信息写入根节点数据内容,那么监控系统需要在根节点上再注册一个数据内容变化的watcher监听器,以实时获取集群主机的状态数据。Step6:如果集群主机状态信息写入对应的临时节点,那么监控系统需要在每一个主机临时节点上注册一个数据内容变化的watcher监听器,以实时获取集群主机的状态数据。3.2 分布式日志收集系统

下面以分布式日志收集系统为例,分析zk对集群的管理。

(1)系统组成

首先要明确的是,分布式日志收集系统由四部分组成:日志源集群,日志收集器集群,zk集群,监控系统。

(2)系统工作原理

图表:

Sourcehost,这些源节点,设置为临时节点,监控存活状态很简单

收集器collector1/2/3…这些节点只能设置为持久节点,它们的存活状态很难监控,如何处理?

可以在持久节点下为采集器创建一个临时节点,如果临时节点没有了,说​​明采集器主机崩溃了。

但是如果收集器的临时节点崩溃了,但是收集器的持久节点和源主机对应的临时节点还在的话该怎么办呢?

这时候就需要把这些源主机的临时节点分配到其他收集器主机上,怎么分配呢?

负载均衡:根据每个采集器采集的主机数量,或者每个主机产生的日志量,将负载分配给压力较小的主机。

你可以给每个收集器主机分配一个负载,然后按照自己的分配方式分配故障收集器对应的主机,比如可以找出压力最大的前几个收集器并排除,再将需要分配的主机分配给剩余的收集器。

如果要扩大容量,可以选择压力最大的收集器,或者选择压力最大的前几个,分配给新增加的收集器。

分布式日志收集系统的工作步骤如下:

B.任务分配 C.状态收集 D.任务重新分配Rebalance 4.DNS服务

zk的DNS服务的作用主要是为了解耦消费者和提供者,防止提供者的单点问题,以及实现提供者的负载均衡。

图表:

比如一个消费者要调用service1,那么它首先从ZK中读取注册中心(即Service1服务节点下所有主机的列表),然后根据负载均衡策略选择一个主机来调用该服务。

此时ZK提供的功能就是把服务的提供者注册到ZK中,然后消费方通过读取注册表的方式,通过负载均衡来调用服务,也就是提供者写,调用方读,Dubbo就是这么实现的。

4.1 什么是 DNS

DNS,Domain Name System,域名系统,是一个能够将名字与特定主机IP和端口号绑定的系统。zk可以充当DNS的角色,完成域名到主机的映射。

4.2 DNS实现基本原理

假设提供方应用app1、app2分别用于提供service1、service2两个服务,现需要在zk中注册它们,具体实现步骤如下图所示。

具体实现步骤:

4.3 带状态收集功能的DNS实现原理

上面的模型存在一个问题,如何获取各个提供商主机的健康状态和运行状态?可以给每个域名节点增加一个状态子节点,状态子节点的数据内容是开发者定义的状态数据。这个状态数据是怎么获取的呢?就是通过状态收集器(开发者开发)定期写入到zk的节点中。

其他一些情况:

时差问题:状态收集器会定时更新状态,可能导致提供方主机崩溃,而ZK还未更新,恰巧有消费者读取到了ZK数据内容,调用该服务的机器就崩溃了。

如何解决:解决方案有很多种,下面是为主机定义一个临时节点的解决方案。

如果服务提供者宕机了怎么办?服务降级,降级点有很多,比如消费者可以自己处理,但是提供者不能,用本地代码返回一些信息

降级的目的是为了提升用户体验

集群服务器架构_集群服务器配置_服务器集群是什么意思

扩展-集群监控平台

PS:Green 需要程序员实现

阿里巴巴的Dubbo使用Zookeeper作为域名服务器。

5. 主选举5.1 什么是主选举

集群是分布式系统不可缺少的组成部分,是解决分布式系统中计算单元单点问题、水平扩展计算单元处理能力的一种解决方案。

一般情况下,集群中会选举出一个Master,来协调集群中其他Slave主机,并有权力决定Slave主机的状态。

5.2 广告推荐系统 (1)需求

系统会根据用户画像将​​用户分为不同的类别,针对不同类型的用户,系统会推荐不同的广告,每个用户前端需要从广告推荐系统获取不同的广告ID。

(2)分析

给前端提供服务的广告推荐系统一定是集群的,这样才能更加快速高效的响应前端。需要注意的是,推荐系统对广告ID的计算是一个比较复杂且比较耗费CPU等资源的过程,如果集群中每一台主机都能执行这个计算逻辑,势必会浪费资源,降低响应效率。这时候只需要其中一台主机处理这个计算逻辑,然后将计算结果写入一个中间存储系统,并通知集群中的其他主机,让它们从中间存储系统中共享计算结果。那么运行计算逻辑的主机就是Master,其他主机就是Slave。

(3)建筑

(4)主选举

方案一:利用DBMS独有的主键特性,实现Master选举。让集群内所有主机都往数据库的一张表中插入同一个主键的记录。由于DBMS有主键冲突检查功能,所以只能有一台主机插入成功。那么这台成功的主机就是Master,其他的主机就是Slaves。

解决方案2:这个广告推荐系统集群中的Master是如何选举出来的?这个可以使用ZooKeeper来实现,当ZooKeeper中多个客户端创建同一个节点时,只有一个客户端能够成功。

具体来说,分三步完成:

6. 分布式同步6.1 什么是分布式同步

分布式同步又称分布式协调,是分布式系统中不可缺少的一部分,是将不同的分布式组件有机地结合在一起的关键。对于一个运行在多台机器上的应用程序,通常需要一个协调器来控制整个系统的运行流程,比如执行的顺序,或者是否执行。

集群服务器架构_服务器集群是什么意思_集群服务器配置

6.2 MySQL数据复制总线

下面以“MySQL数据复制总线”为例分析zk的分布式同步服务。

(1)数据复制总线组成

MySQL Data Replication Bus 是一个实时数据复制框架,用于在不同的 MySQL 数据库实例之间进行异步数据复制(MySQL 自带的主从无法做到这一点)。其核心由生产者、复制管道、消费者三部分组成。

不同的 MySQL 数据库实体:数据库名称和表可以不同。您可以将一个表中的字段复制到另一个数据库表中的字段。对两个数据库没有要求。

那么,在MySQL数据复制总线体系中,ZK的分布式同步功能需要用在什么地方呢?上面的结构就暴露了存在的问题:复制器存在单点问题,为了解决这个问题,需要为其设置多台热备主机。那么,这些热备主机如何协调工作呢?这时候就需要ZK来做协调工作,也就是ZK完成分布式同步工作。

(2)数据复制总线工作原理

图表:

1. 首先,协调器创建根节点/mysql_replicator

2. 然后每个复制任务都会在根节点下创建一个子节点,每个任务节点都有status和instances节点,coordinator会在instances节点上注册子节点列表change watcher。

3.然后启动多个replicator,并在status节点上注册针对数据内容的watcher,然后在instances节点下创建对应的有序临时节点。

此时会触发 coordinator 的 watcher 对 instance 的监听回调,回调会立即指定各个 replicator host 的状态(按照你定义的规则,比如将序号最小的节点设置为 RUNNING 状态,其他的设置为 STANDBY 状态),并将状态写入 status node

4. 当状态节点的内容发生改变时,立即触发复制器,监控状态节点的数据内容,在回调中读取并解析状态内容,若检测到其状态为运行中,则执行复制任务。

5.复制任务过程中,每次复制都会在Binlog上记录RUNNING主机的消费点,并记录在instances中

6. 如果正在运行的 replicator 挂了,意味着 instance 列表会发生变化,会触发 coordinator 对应的子节点列表变化 watcher 监听,在回调中会立即读取该 instance 节点的所有子节点,并将新的 replicator 指定为 running 状态,其他的为 STANDBY 状态,并写入 status 节点。

7. 写入status节点后,会立即触发replicator去监控status节点的数据内容watcher,解析内容并检测到运行后,replicator再次启动复制任务,复制任务会先从instances节点获取Binlog的消费点,然后进行复制。

MySQL复制总线的工作步骤一般分为三步:

A. 复制任务注册

B.复制器热备

C. 主备切换

7.分布式锁

分布式锁是分布式系统对共享资源进行同步访问控制的一种方式,Zookeeper可以实现分布式锁,根据用户操作类型不同,可以分为独占锁和共享锁。

7.1 分布式锁的实现

ZK上的分布式锁实现采用类似“/xs_lock/[hostname]-请求类型-序列号”的临时序列节点,当客户端发出读写请求时,ZK中会创建不同的节点,根据读写操作的不同以及当前节点与上一个节点的序列号关系,执行不同的逻辑。

具体实现步骤:

第五步:客户端完成读写操作后,与zk的连接断开,zk中该session对应的节点消失。 7.2 分布式锁的改进

之前的实现方式存在“羊群效应”,为了解决其带来的性能下降,可以对前述分布式锁的实现进行改进。

由于一个操作而导致大量低效或者无用的操作被执行的情况称为羊群效应。

当客户端请求发出时,zk 中会创建对应的临时序列节点,并立即获取当前/xs_lock 的所有子节点列表。但是没有哪个客户端会向/xs_lock 注册 watcher 来监控子节点列表的变化,而是根据请求类型向“受影响”的子节点注册 watcher。

对其影响:

8.分布式队列

当我们说起分布式队列,我们​​立刻就能想到RabbitMQ、Kafka等分布式消息队列中间件产品,zk也可以实现简单的消息队列。

8.1 FIFO 队列

zk中实现FIFO队列的思路是:利用顺序节点的顺序,为每条数据在zk中创建一个对应的节点。然后为每个节点注册一个watcher,当一个节点被消费时,会触发consumer去消费下一个节点,直到消费完成。

具体实施步骤为:

8.2 分布式屏障队列

Barrier,屏障,障碍。屏障队列是分布式系统中的同步协调器。它规定队列中的所有元素必须聚集起来,才能执行后续任务,否则它们将一直等待。它常用于大规模分布式并行计算应用场景:最终的合并计算需要基于许多并行计算的子结果。

ZK for Barrier 的实现原理是在 ZK 中创建一个 /barrier 节点,并将其数据内容设置为开启屏障的阈值。即当其下的子节点数量达到这个阈值时,APP 才可以进行最后的计算,否则就等待。每次并行操作完成后,都会在 /barrier 下创建一个子节点,直至所有并行操作完成。

具体实施步骤为:

© 版权声明
THE END
喜欢就支持一下吧
点赞279赞赏 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容