Hadoop架构: 流水线(PipeLine)

该系列总览: Hadoop3.1.1架构体系——设计原理阐述与Client源码图文详解 : 总览

流水线(PipeLine),简单地理解就是客户端向DataNode传输数据(Packet)和接收DataNode回复(ACK)[Acknowledge]的数据通路。

整条流水线由若干个DataNode串联而成,数据由客户端流向PipeLine,在流水线上,假如DataNode A 比 DataNode B 更接近流水线

那么称A在B的上游(Upstream),称B在A的下游(Downstream)。

流水线上传输数据步骤

1. 客户端向整条流水线的第一个DataNode发送Packet,第一个DataNode收到Packet就向下个DataNode转发,下游DataNode照做。

2. 接收到Packet的DataNode将Packet数据写入磁盘

3. 流水线上最后一个DataNode接收到Packet后向前一个DataNode发送ACK响应,表示自己已经收到Packet,上游DataNode照做

4. 当客户端收到第一个DataNode的ACK,表明此次Packet的传输成功

一.流水线基础概念

流水线就像一条水管,数据(Packets)从一端流进去,依次经过流水线上的各个DataNode。

回复(ACK)则是相反,ACK从最后一个节点依次向前传递,流回客户端

多么艺术的设计!

但是,有一个问题,要知道,若干个Packet才能传输完一个Block,并且多个Block组成一个文件

所以从文件或者Block的角度来看,即使每台机器的效率接近,也可能出现流水线不均匀的情况(接收文件数据量不均匀)

出现的情况往往是第一个节点接收的数据量最多,其后的节点递减,所以我们可以考虑把第一个DataNode选为性能较好的节点,或者是离客户端尽可能近的节点。但实际上,节点的选择是由NameNode根据机架感知等技术实现的。并且客户端的流水线节点选取是由NameNode决定的。

还有一个问题。HDFS是支持一写多读机制的,意味着在流水线上的DataNode(正在被写)允许被其他客户端读取(Reader 以下均称此类读客户端为Reader)。这样就会产生读的不一致性,比如说我在流水线上游的某个DataNode中读到“武汉加油!”这条数据,但是去下游的DataNode读,却读不到。这是因为下游的DataNode可能还没收到数据。

虽然说一般客户端只会读取一个DataNode的信息,但如果被读取的DataNode宕机,那么客户端就要另选DataNode,可能造成前后数据不一致。

或者有多个客户端需要根据对方的数据协调工作,每个客户端读的不是一个DataNode,那么对同一读取目标,读出来的数据不一致。这种水平上的不一致可能也会导致业务出错。

那么,怎么解决呢?

二.流水线读一致性设计

我们先来定义一下概念

首先提出问题,在流水线中的某个DataNode,怎么样判断自己的数据是否可以给Reader读取。

就比如上面那张图,不能一致性读的原因是下游的DataNode3没有接收到DataNode1已经接收的Packet。那么如果DataNode1确定DataNode3已经接收到Packet了,那不就能放心地把Packet的数据给Reader了吗?就算Reader再去DataNode3读,也会读到同样的数据,而不会出现数据找不到或者数据不一致的情况。

于是有了定义:对于一个数据块,一个DataNode接收到的数据为DR(Data Received),根据下游收到的ACK,已被下游确认接收的数据为DA(Data Acknowledged)

顺便定义:对于 i 节点的DA是DAi , DR是DRi  , 对于客户端,客户端发出去的数据为CS(Clent Send) ,而客户端确认的数据为CA(Client Acknowlege)

DA和DR其实是一个增量的概念,并且针对的是一个Block。下图是一个DataNode中的Replica(Block在DataNode中称为Replica,强调是Block的副本)在逐渐被写满的过程

我们可以分析一下,整个流水线上,各个节点的DR和DA的走势                   

以及从图形上看,DR和DA在一来一回的流水线上的分布情况

我们发现Writer发送数据(第一个DataNode的DR)最多,但是确认了的数据DA最少,原因是Packet和ACK在流水线一来一回需要路程时间

Reader直接访问一个DataNode中Replica的数据时,需要提供四个数据<BlockId,BGS(Block Generation Stamp 可以理解成Block的版本号) , offset, len>

BlockId 和 BGS 用来识别一个Block,当DataNode中不存在指定BlockId的Replica或者Replica的BGS比Reader给出的BGS旧,那么DataNode将拒绝这次读请求

offset 表示Reader将从哪里开始读取数据,len表示欲读取的数据长度,因为DA是线性增长的,所以只要保证 offset + len <= DA ,DataNode就允许这次读请求(当然offset 和 len 都大于0)

具体怎么做才能实现呢?有两种做法。

做法一,当其他应用请求一个Reader客户端读取数据的时候,Reader会向将要读的DataNode发送请求,询问DataNode的DA。如果应用请求的数据规模(offset + len)大于DA,那么将抛出异常

否则,Reader将获取DataNode的Min(DR, offset + len)长度数据放到缓存Q中,并且安全地返回 off + len 数据给应用,随后Reader监听这个DataNode的DA的变化,直到应用放弃对文件的读取。如果DA增加,表示Reader能从缓存Q中读到的最大数据量增加,也就是offset + len能达到更大的值。当读取任意一个DataNode P,假设他的DA是m,如果这个DataNode刚好宕机,1. Reader转而访问上游的DataNode,上游DataNode的DR比下游的DR大,随着时间的推迟,上游DataNode会把整个DR暴露给Reader,其中包含下游DR的数据,下游的数据在上游仍然能访问。2.Reader转而访问下游的DataNode,下游的DataNode的DA比P的要大,所以在P读到的数据在下游中仍然找得到。一致性读达成。

这种做法的缺点是客户端的代码和算法实现复杂,要时刻监听DA的变化。

做法二,为了更清楚地描述,分一下步骤

1.Reader向DataNode a发出<BlockId,BGS(Block Generation Stamp 可以理解成Block的版本号) , offset, len>,DataNode a的DA必须大于等于offset + len

2.读取的请求不是发给DataNode a,而是将请求发给另外一个DataNode b

3.如果

  1.offset + len <= DAb,那么可以安全地返回数据

  2.如果offset + len > DAb ,因为DAa >= offset + len > DAb。所以DAa > DAb,所以b在a的上游,所以DRb > DRa,所以在b上有a已经ACK了的数据。所以b也可以安全地返回offset + len的数据给Reader

  3.如果offset + len > DRb,那么将抛出异常。

虽然上述步骤2访问了DR,但是DR中被访问的数据已经在下游被ACK了,只是Reader自己移动到了上游去找数据。

当前访问的DataNode a如果宕机

  1.向下游读,下游的DA大于上游,故在上游的数据一般能在下游找得到,经过步骤1将数据返回

  2.向上游读,因为之前已经规定好,只能访问offset + len范围的数据,并且上游的BR总是包含DAa,所以 offset + len 长度的数据总是能在上游找到。

  一致性读解决

做法二虽然简单但是要访问两个节点。网络上的切换的开销不小。

具体HDFS实现了哪一个,需要看版本决定,笔者暂时还没有找到官方给定哪些版本实现哪种方案和研究源码,日后填坑。

三.流水线的生命周期

  1.流水线被建立(Setup) : 客户端Writer通告NameNode获得Block信息,通知信息里locations(Replica所在)包含的DataNode,告知这些DataNode将要创建一条流水线,DataNode收到后会回复。

   2.数据传输(DataStream) : 当Writer在步骤1接收到如数的DataNode的回应后,流水线正式创建,Writer能够在流水线上以Packet为单位传输数据。

   3.恢复(Recovery) : 恢复分三种情况 : 1.流水线创建时失败  2.流水线传输过程失败  3.流水线关闭失败

   4.关闭(Close) : 当一个块被写满,Writer将通知DataNode流水线关闭,DataNode可以将块的状态设置为FINALIZED并且DataNode向NameNode汇报

四.流水线的建立

流水线建立的时机:

  1.客户端请求新建一个Block,需要新建流水线,以便将新Block的数据写入到DataNode的Replica里

  2.客户端请求打开一个文件并且对这个文件进行append操作,这个文件末尾的最后一个块如果没有满,那么所有拥有这个Block的Replica的DataNode将被连起来成为一条流水线,以便对这些没写满的Replica进行追加,(其实是对Block进行追加)

  3.在恢复过程中需要建立流水线

流水线建立流程:

  客户端的行为:

  1.客户端首先需要询问NameNode相关信息,比如对应Block的Replica在哪,Block的BGS和ID等信息。如果流水线的建立的是为了恢复流水线,或者文件被打开用来append,那么客户端还会为Block向NameNode申请新的BGS。

  2.根据1中获取的信息,客户端试图和流水线的第一个DataNode通过Socket建立连接。

  3.客户端将1中获得的信息发布到流水线上,告知线上的DataNode,该Block对应的Replica需要被操作。

  发送的信息具体按流水线的用途分为:

  

DataNode行为:

  .1.当DataNode从3中得知信息后,将按情况进行如下操作

最后一步:

如果建立的流水线是用来恢复或者Append的,那么将会通知NameNode,流水线完成,告知NameNode更新流水线信息(块的位置等)。

重新架构流水线:

如果上述所有步骤不成功,则会重新建立流水线(进行流水线恢复)。

五:流水线的恢复

  请见:Hadoop架构: 关于Recovery (Lease Recovery , Block Recovery, PipeLine Recovery)

原文地址:https://www.cnblogs.com/lqlqlq/p/12321930.html

时间: 2024-08-29 07:01:44

Hadoop架构: 流水线(PipeLine)的相关文章

Hadoop架构的初略总结(1)

Hadoop架构的初略总结(1) Hadoop是一个开源的分布式系统基础架构,此架构可以帮助用户可以在不了解分布式底层细节的情况下开发分布式程序. 首先我们要理清楚几个问题. 1.我们为什么需要Hadoop? 解: 简单来说,我们每天上网浏览,上街购物,都会产生数据.我们处于一个数据量呈爆发式增长的时代.我们需要对这些数据进行分析处理,以获得更多有价值的东西.而Hadoop应时代而生.其次我们应该比较了解传统型关系数据库跟Hadoop之间有何区别.这些在前面的Hadoop第二课我们都有所提到.

Redis附加功能之Redis流水线pipeline

流水线功能的目的:通过减少客户端与服务器之间的通信次数来提高程序的执行效率. 一.通信 在一般情况下, 用户每执行一个 Redis 命令,客户端与服务器都需要进行一次通信:客户端会将命令请求发送给服务器,而服务器则会将执行命令所得的结果返回给客户端. 当程序执行一些复杂的操作时, 客户端可能需要执行多个命令, 并与服务器进行多次通信. 假设我们正在构建一个为图书打标签(tag)的网站,这个网站上的每本图书都可以被打上任意多个标签.并且为了记录哪些标签的图书是最多人阅览的,我们会为每个标签创建一个

hadoop架构

hadoop是一种主从架构模型 主(NameNode节点):保存文件元数据(描述文件的数据),单节点. 从(DataNode节点):保存文件Block数据,多节点. DataNode和NameNode保持心跳,提交Block列表. HdfsClient和NameNode交互元数据信息找到Block位置,然后在DataNode交互Block数据. DataNode利用服务器本地文件系统存储数据块. 原文地址:https://www.cnblogs.com/xumaomao/p/11449483.h

Hadoop架构及集群

摘要:Hadoop是一个由Apache基金会所开发的分布式基础架构,Hadoop的框架最核心的设计就是:HDFS和MapReduce.HDFS为海量的数据提供了存储,而MapReduce则为海量的数据提供了计算,特点是:高可靠性,高扩展性,高效性,高容错性.l 原文地址:https://www.cnblogs.com/gllyun/p/12302195.html

Tomcat总体架构:Pipeline 和 Valve+Connector 设计+Executor等

2.1.5?Pipeline 和 Valve 从架构设计的角度来考虑,至此的应用服务器设计主要完成了我们对核心概念的分解,确保 了整体架构的可伸缩性和可扩展性,除此之外,我们还要考虑如何提高每个组件的灵活性,使其同样易于扩展. 在增强组件的灵活性和可扩展性方面,职责链模式是一种比较好的选择.Tomcat即采用该模 式来实现客户端请求的处理--请求处理也是职责链模式典型的应用场景之一.换句话说,在 Tomcat中每个Container组件通过执行一个职责链来完成具体的请求处理. Tomcat定义了

Hadoop 架构初探

对流行Hadoop做了一些最基本的了解,暂时没太大感觉,恩先记点笔记吧. = = Hadoop 基本命令及环境安装 一.下载虚拟机镜像 目前比较流行的有以下三个: (CHD) http://www.cloudera.com (HDP)  http://hortonworks.com/ (MapR) http://www.mapr.com 本文使用HDP的沙盘 下载地址 http://hortonworks.com/products/hortonworks-sandbox/#install 我使用

Hadoop架构设计、执行原理具体解释

1.Map-Reduce的逻辑过程 如果我们须要处理一批有关天气的数据.其格式例如以下: 依照ASCII码存储.每行一条记录 每一行字符从0開始计数,第15个到第18个字符为年 第25个到第29个字符为温度.当中第25位是符号+/- 0067011990999991950051507+0000+ 0043011990999991950051512+0022+ 0043011990999991950051518-0011+ 0043012650999991949032412+0111+ 00430

hadoop 架构

Hadoop3.1.1源码Client详解 : Packet入队后消息系统运作之DataStreamer(Packet发送) : 主干

该系列总览: Hadoop3.1.1架构体系——设计原理阐述与Client源码图文详解 : 总览 在上一章(Hadoop3.1.1源码Client详解 : 写入准备-RPC调用与流的建立) 我们提到,在输出流DFSOutputStream创建后,DataStreamer也随之创建,并且被启动 下文主要是围绕DataStreamer进行讲解 DataStreamer是一个守护线程类,继承关系如下.       观察DataStreamer的run方法,没有意外的,我们可以发现他和普通的做法一样,用