Hadoop

  • 在hadoop中,zk主要用来实现HA(High Availability)。这部分逻辑主要集中在hadoop common的HA模块中,HDFS的NameNode和Yarn的ResourceManager都是基于此HA模块来实现自己的HA功能的。同时,在YARN中又特别提供了zk来存储应用的运行状态。

YARN

  • Yarn主要由ResourceManager、NodeManager、ApplicationMaster和Container四部分组成。
  • 其中最核心的就是RM,它作为全局的资源管理器,负责整个系统的资源管理和分配。

RM单点问题

  • RM是YARN中非常复杂的一个组件,负责集群中所有资源的统一管理和分配,同时接受各个NM的资源汇报信息,并把这些信息按照一定的策略分配给各个app。
  • ResourceManager HA的解决方案就是使用 Active/Standby模式的RM HA架构。
  • 可以看到,在运行期间会有多个RM存在,但只有一个处于Active状态,其他的是standby。当active节点无法正常工作时,其余处于standby的节点则会通过竞争选举产生新的节点。

主备切换

    • RM使用基于zk实现的ActiveStandbyElector组件来确定RM的状态:Active或Standby。
      具体做法如下:
      1. 创建锁节点:在zk上有一个类似于/yarn-leader-election/pseudo-yarn-rm-cluster的锁节点,所有rm在启动时都会去竞争一个lock子节点/yarn-leader-election/pseudo-yarn-rm-cluster/ActiveStandbyElectorLock,该节点是临时节点。
      2. 注册Watcher监听:所有standby状态的rm都会向/yarn-leader-election/pseudo-yarn-rm-cluster/ActiveStandbyElectorLock节点注册一个节点变更的Watcher监听,利用临时节点的特性,能快速感知到Active状态的RM的运行状态。
      3. 主备切换:当active节点不可用时,其对应zk上的Lock节点也会随之被删除,其他standby状态的rm都会接收到zk server的watcher事件通知,然后重复步骤1。
    • 以上,实际上就是通过临时节点 + Watcher事件通知来实现的。
    • HDFS中的NameNode和RM模块都是使用ActiveStandbyElector组件来实现各自的HA的。

Fencing(隔离)

  • 在分布式环境中,经常会出现诸如单机“假死”的情况。所谓“假死”是指机器由于网络闪断或是自身负载过高(常见的有GC占用时间过长或CPU的负载过高等)而导致无法正常地对外进行及时响应。
  • 在上述主备切换过程中,我们假设RM集群由rm1和rm2组成,且rm1为active,rm2为standby。某一刻rm1发生“假死”现象,此时zk认为rm1挂了,从而主备切换,rm2称为active。但是随后,rm1恢复了正常,其依然认为自己还处于active。那么就出现了我们常说的分布式“脑裂”(Brain-Split)现象,即存在多个处于Active状态的rm各司其职。
  • Yarn引入了Fencing机制来解决上述问题,即借助zk数据节点的ACL权限控制机制来实现不同rm之间的隔离。
  • 具体做法很简单:在主备切换过程中,多个rm之间通过竞争创建锁节点来实现主备状态的确定。这个过程中,有一点需要改进:创建的根节点必须携带zk的ACL信息,目的是为了独占该根节点,以防止其他RM对该节点进行更新。
  • 具体来说:
    • RM1出现假死之后,zk就会将其创建的锁节点移除,此时RM2会创建相应的锁节点,并切换为Active状态。RM1恢复之后,会试图去更新zk的相关数据,但是此时发现自己没有权限更新zk的相关数据节点。从而rm1自动切换到Standby状态。

RM状态存储

  • 在RM中,RMStateStore能够存储一些RM内部状态信息,包括Application以及它们的Attempts信息、Delegatioln Token及Version Information等。
  • RMStateStore中绝大多数信息都是不需要持久化存储,因为很容易从上下文信息中将其重构出来。
  • 在存储的设计方案中,提供了三种可能的实现,分别如下:
    • 基于内存实现,一般用于日常开发测试;
    • 基于文件系统的实现,如HDFS;
    • 基于zk的实现。
  • 由于这些状态数据量都不大,因此hadoop官方建议基于zk来实现状态信息存储。
  • 在zk上,rm的状态信息都存储在/rmstore这个根节点上,其数据节点的组织结构如下:
  • Please read this link.

HBase

  • HBase是一个基于Hadoop文件系统设计的面向海量数据的高可靠性、高性能、面向列、可伸缩的分布式存储系统。
  • 与大部分分布式NoSQL数据库不同的是,HBase针对数据写入具有强一致性,甚至包括索引列也实现了强一致性。
  • HBase整体架构如下图:
  • 可以看到,在整个HBase架构体系中,zk是串联起HBase集群与client的关键所在。
  • 早期Hbase没有引入zk时,存在一系列问题:
    • RegionServer挂掉时,系统无法及时得知信息,client也无法知晓,因此服务难以迁移至其他RegionServer上
    • 类似的问题都是缺少相应的分布式协调组件。
  • 下面从以下几个方面讲解zk在HBase中的应用场景。

系统冗错

  • (系统冗错其实就是监控rs
  • 当HBase启动时,每个RegionServer都会到zk的/hbase/rs节点下创建一个信息节点(rs状态节点),例如/hbase/rs/[Hostname],同时HMaster会监听该节点。
  • 当某个rs挂掉时,zk会因为在一段时间内无法接受其心跳信息(即Session失效),而删除掉该rs对应的rs状态节点。同时,HMaster收到zk的NodeDelete通知,并立即开始冗错工作:
    • HMaster会将该RegionServer所处理的数据分片(Region)重新路由到其他节点上,并记录到Meta信息中供client查询。
  • 那么,为什么不直接让HMaster来负责RegionServer的监控呢?是因为通过心跳机制来管理rs状态会使HMaster的负载随着系统容量而不断增大。并且,HMaster可能挂掉,因此数据还需要持久化。

RootRegion管理

  • 对HBase集群而言,数据存储的位置信息是记录在元数据分片,也就是RootRegion上的。每次client发起新的请求,需要知道数据的位置,就会去查询RootRegion,而RootRegion自身的位置是记录在zk上的。当RootRegion发生变化,比如Region的手工移动、Balance或是RootRegion所在server发生故障等时,就能通过zk来感知到这一变化并做出一系列容灾措施。

Region状态管理

  • Region是HBase中数据的物理切片,每个Region中记录了全局数据的一小部分。
  • 对一个分布式系统而言,Region是会经常发生变更的。一旦Region发生移动,它必然会经历Offline和重新Online的过程。
  • Offline期间数据是不能被访问的,并且Region的这个状态必须被全局知晓,否则可能会出现事务性的异常。

分布式SplitLog任务管理

  • 当某台RS挂掉时,由于总有一部分新写入的数据还没有持久化到HFile中,因此在迁移该RegionServer的服务时,一个重要的工作就是从HLog中恢复这部分还在内存中的数据(WAL)。
  • 而这部分工作最关键的一步就是SpitLog,即HMaster需要遍历该RS的HLog,并按Region切分成小块移动到新地址下,并进行数据的Replay。
  • 由于单个RS的日志量相对庞大(可能有数千个Region,上GB的日志),一个快速恢复的可行方案就是将这个处理HLog的任务分配给多台rs来共同处理。
  • 因此需要一个持久化组件来辅助HMaster完成任务的分配。当前的做法是,在zk上创建一个splitlog节点,将rs和待处理的region之间的映射关系存放到该节点。然后各个rs到该节点上领取任务并在执行后将成功or失败的信息更新到节点。
  • 整个过程中,zk担负了分布式集群中相互通知和信息持久化的角色。

Kafka

  • kafka:开源分布式消息系统
  • 主要用于实现低延迟的发送和收集大量的事件和日志数据。
  • kafka是一个吞吐量极高的分布式消息系统,其整体设计是典型的发布与订阅模式。
  • 在kafka集群中,没有“中心主节点”的概念,所有server都是对等的。 -->   因而可以在不做任何配置更改的情况下实现server的添加和删除。同样,消息的生产者和消费者也能够随意重启和机器的上下线。
  • kafka中生产者和消费者之间的部署关系如下图:

术语介绍

  • Kafka是一个近似符合JMS规范的消息中间件实现。
  • producer:
  • consumer:
  • topic:由用户定义并配置在kafka server端,用于建立producer和consumer之间的订阅关系
  • partition:一个topic下面会分为多个分区
  • broker:kafka的服务器,用于存储消息。
  • group:用于归组同类消费者
  • offset:

Broker注册

  • 虽然broker是分布式部署并且相互之间是互相独立运行的,但还是需要有一个注册系统能够将整个集群中的broker server都管理起来。  -->   在kafka的设计中,选择了使用zk来进行所有broker的管理。
  • broker节点:/brokers/ids   -->    每个broker sever启动时都会到zk上注册 /broker/ids/[0...N]  (临时节点,以动态表征broker server的可用性),broker会把自己的IP和port写入该节点。
  • 可以看出每个broker节点都有一个全局唯一的 Broker ID.

Topic注册

  • kafka中,用一个topic的消息会分成多个partition并分布到多个broker中。   -->   映射关系由zk维护。
  • topic节点:/brokers/topics/[topic]   (临时节点)

生产者负载均衡

  • 因为同一个topic会被分区从而分布到不同的broker server上。因而生产者需要将消息合理地发送到这些分布式的broker上。 -->  从而产生了如何进行生产者负载均衡的问题。
  • 对于生产者的负载均衡,kafka支持传统的四层负载均衡,同时也支持使用zk的方式来实现负载均衡。

四层负载均衡

  • 设计简单:根据生产者的IP地址和端口来为其确定一个相关联的broker。通常一个生产者只会对应单个broker。
  • 优点:1. 整体逻辑简单,不需要引入第三方系统。2. 每个producer只需与broker维护单个TCP链接即可。
  • 缺点:1. 无法做到真正的负载均衡。因为每个producer产生的消息量不同,从而导致不同broker接收到的消息总数非常不均匀。2. 生产者无法实时感知到broker的新增与删除。

使用zk进行负载均衡

  • 在kafka中,client使用了基于zk的负载均衡策略来解决producer的负载均衡问题。
  • kafka producer会对zk上的“broker的新增与减少”、“Topic的新增与减少”和“Broker与Topic关联关系的变化”等事件注册watcher监听,从而实现一种动态的负载均衡机制。

消费者负载均衡

  • kafka consumer也需要进行负载均衡来实现多个consumers合理地从对应broker server上接收消息。(生产者负载均衡则是producer合理地选择broker来发送消息)
  • 对于一个消费者分组,如果组内的consumers发生变更或broker server发生变更,会触发消费者负载均衡。
  • 关于consumer group:group是对整个kafka集群的概念,kafka保证每条消息在同一个group内只会被某一个consumer消费。(比如说kafka + Spark streaming的组合,那么所有的streaming executor组成一个group,去消费某个topic。)
  • kafka提供的consumer负载均衡算法:
    • topic的所有消息分区Pt  -->  需要对Pt进行排序,从而使分布在同一个broker server的分区尽量靠在一起。
    • 同一个group中的所有消费者Cg  -->  对Cg进行排序。
    • N = size(Pt) / size(Cg)
    • 将编号为 i * N ~ (i + 1) * N - 1的消息分区分配给消费者Ci
    • 更新zk上消息分区与消费者Ci的关系

kafka小结

  • kafka从设计之初就是一个大规模分布式消息中间件,其server端存在多个broker,同时为了达到负载均衡,将每个topic的消息分成了多个partition,并分布在不同broker上。多个消费者和生产者能够同时发生和接收消息。
  • kafka使用zk作为其分布式协调框架,能很好地将消息生产、消息存储和消息消费结合起来。借助zk,来保持包括producer、consumer和broker在内的所有组件无状态情况下,建立起producer和consumer之间的订阅关系,并实现了producer和consumer的负载均衡。

<zk在大型分布式系统中的应用>的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. Python多线程threading的使用

    一. threading的参数传递,参数之后的’,‘不能少,此处的’,‘是用来区分此参数作为元组(包含多个参数)来传递的,而不是单个参数传递 #coding:utf- import threading ...

  2. Solr和Lucene的区别?

    1.Lucene 是工具包 是jar包 2.Solr是索引引擎服务  War 3.Solr是基于Lucene(底层是由Lucene写的) 4.上面二个软件都是Apache公司由java写的 5.Luc ...

  3. Html textarea 标签

    Html textarea 标签 </body> </html> <!-- textarea 标签输入多行文本框,name="xxx"标识后端获取名称 ...

  4. 剑指offer(1)二维数组的查找

    限制今天起开始也刷剑指offer啦,一步一步来. 题目描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数, ...

  5. css的再深入9(更新中···)

    一 单位 1.px 就是一个基本的单位 像素 2.em 也是一个单位 用父级元素的字体大小乘以em前面的数字.如果父级没有就继承上一个父级直到body,如果body没有那就默认是16px. 3.rem ...

  6. 【问题解决:信息提示】SpringBoot启动时提示The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path

    问题描述 springboot程序在启动时提示信息 [2018-10-24 21:59:05.214] - 440 信息 [restartedMain] --- org.apache.catalina ...

  7. (转载)【UGUI】侧面滑出的菜单栏,宽度自适应

    首先看下项目效果 实现效果 发现实现效果并不难,利用动画(iTween)+UGUI 有一个长按的判断处理即可 附上项目和代码 using System.Collections; using Syste ...

  8. Mac OS X 显示和隐藏文件

    参考: mac系统如何显示和隐藏文件 Mac OSX系统 显示和隐藏文件 1.显示隐藏文件: 打开Terminal,并输入以下命令: defaults write com.apple.finder A ...

  9. Foxmail7.2新建的文件夹不见了

    Foxmail在客户端上,新建了几个文件夹,并把相应的邮件都都选择了“总是把**邮件转移到”这个选项. 今天早上打开电脑一看,所有的邮件连同对应的文件夹都找不到了 Foxmail中没显示因为默认是隐藏 ...

  10. 揭示牌面使之升序 Reveal Cards In Increasing Order

    2019-03-27 14:10:37 问题描述: 问题求解: 模拟题.考虑角度是从结果来进行反推. input - [2,3,5,7,11,13,17] (just sort the input t ...