HDFS读写流程及容错

1. hdfs的写入流程及容错

在这里插入图片描述

文件上传流程如下:

  • 创建文件:
    ①HDFS client向HDFS写入数据,先调用DistributedFileSystem.create()
    ②RPC调用namenode的create(),会在HDFS目录树中指定的路径,添加新文件;并将操作记录在edits.log中
    namenode.create()方法执行完后,返回一个FSDataOutputStream,它是DFSOutputStream的包装类

  • 建立数据流管道pipeline
    ③client调用DFSOutputStream.write()写数据(先写第一个块的数据,暂时叫blk1)
    ④DFSOutputStream通过RPC调用namenode的addBlock,向namenode申请一个空的数据块block
    ⑤addBlock返回LocatedBlock对象;此对象中包含了当前blk要存储在哪三个datanode的信息,比如dn1、dn2、dn3
    ⑥客户端,根据位置信息,建立数据流管道(图中蓝色线条)

  • 向数据流管道写当前块的数据
    ⑦写数据时,先将数据写入一个检验块chunk中,写满512字节后,对此chunk计算校验和checksum值(4字节)
    ⑧然后将chunk及对应校验和写入packet中,一个packet是64KB
    ⑨随着源源不断的带校验和的chunk写入packet,当packet写满后,将packet写入dataqueue数据队列中
    ⑩packet从队列中取出,沿pipeline发送到dn1,再从dn1发送到dn2,再从dn2发送到dn3
    ⑪同时,此packet会保存一份到一个确认队列ack queue中
    ⑫packet到达最后一个datanode即dn3后,做校验,将校验结果逆着pipeline方向回传到客户端,具体是校验结果从dn3传到dn2,dn2也会做校验,校验结果再
    传到dn1,dn1也做校验;结果再传回客户端
    ⑬客户端根据校验结果,如果“成功”,则将将保存在ack queue中的packet删除;如果失败,则将packet取出,重新放回到data queue末尾,等待再次沿pipeline发送
    ⑭如此,将block中的一个数据一个个packet发送出去;当此block发送完毕,
    即dn1、dn2、dn3都接受了blk1的完整的副本,那么三个dn分别RPC调用namenode的blockReceivedAndDeleted(),
    namenode会更新内存中block与datanode的对应关系(比如dn1上多了一个blk1副本)

  • 关闭dn1、dn2、dn3构建的pipeline;且文件还有下一个块时,再从④开始;直到文件全部数据写完
    ⑮最终,调用DFSOutputStream的close()
    ⑯客户端调用namenode的complete(),告知namenode文件传输完成

  • 容错

在这里插入图片描述

  • 假设说当前构建的pipeline是dn1、dn2、dn3构成的
    当传输数据的过程中,dn2挂了或通信不畅了,则当前pipeline中断
    HDFS会如何做?

  • 先将ack queue中的所有packet全部放回到data queue中
    客户端RPC调用namenode的updateBlockForPipeline(),为当前block(假设是blk1)生成新的版本比如ts1(本质是时间戳)
    故障dn2会从pipeline中删除
    DFSOutputStream再RPC调用namenode的getAdditionalDatanode(),让namenode分配新的datanode,比如是dn4
    输出流将原dn1、dn3与新的dn4组成新的管道,他们上边的blk1版本设置为新版本ts1
    由于新添加的dn4上没有blk1的数据,客户端告知dn1或dn3,将其上的blk1的数据拷贝到dn4上
    新的数据管道建立好后,DFSOutputStream调用updatePipeline()更新namenode元数据
    至此,pipeline恢复,客户端按正常的写入流程,完成文件的上传

  • 故障datanode重启后,namenode发现它上边的block的blk1的时间戳是老的,会让datanode将blk1删除掉

2. hdfs的读取流程及容错

在这里插入图片描述

  • 1、client端读取HDFS文件,client调用文件系统对象DistributedFileSystem的open方法
  • 2、返回FSDataInputStream对象(对DFSInputStream的包装)
  • 3、构造DFSInputStream对象时,调用namenode的getBlockLocations方法,获得file的开始若干block(如blk1, blk2, blk3, blk4)的存储datanode(以下简称dn)列表;针对每个block的dn列表,会根据网络拓扑做排序,离client近的排在前;
  • 4、调用DFSInputStream的read方法,先读取blk1的数据,与client最近的datanode建立连接,读取数据
  • 5、读取完后,关闭与dn建立的流
  • 6、读取下一个block,如blk2的数据(重复步骤4、5、6)
  • 7、这一批block读取完后,再读取下一批block的数据(重复3、4、5、6、7)
  • 8、完成文件数据读取后,调用FSDataInputStream的close方法

6.2.2 容错

  • 情况一:读取block过程中,client与datanode通信中断

    • client与存储此block的第二个datandoe建立连接,读取数据
    • 记录此有问题的datanode,不会再从它上读取数据
  • 情况二:client读取block,发现block数据有问题

    • client读取block数据时,同时会读取到block的校验和,若client针对读取过来的block数据,计算检验和,其值与读取过来的校验和不一样,说明block数据损坏
    • client从存储此block副本的其它datanode上读取block数据(也会计算校验和)
    • 同时,client会告知namenode此情况;
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在信号处理领域,DOA(Direction of Arrival)估计是一项关键技术,主要用于确定多个信号源到达接收阵列的方向。本文将详细探讨三种ESPRIT(Estimation of Signal Parameters via Rotational Invariance Techniques)算法在DOA估计中的实现,以及它们在MATLAB环境中的具体应用。 ESPRIT算法是由Paul Kailath等人于1986年提出的,其核心思想是利用阵列数据的旋转不变性来估计信号源的角度。这种算法相比传统的 MUSIC(Multiple Signal Classification)算法具有较低的计算复杂度,且无需进行特征值分解,因此在实际应用中颇具优势。 1. 普通ESPRIT算法 普通ESPRIT算法分为两个主要步骤:构造等效旋转不变系统和估计角度。通过空间平移(如延时)构建两个子阵列,使得它们之间的关系具有旋转不变性。然后,通过对子阵列数据进行最小二乘拟合,可以得到信号源的角频率估计,进一步转换为DOA估计。 2. 常规ESPRIT算法实现 在描述中提到的`common_esprit_method1.m`和`common_esprit_method2.m`是两种不同的普通ESPRIT算法实现。它们可能在实现细节上略有差异,比如选择子阵列的方式、参数估计的策略等。MATLAB代码通常会包含预处理步骤(如数据归一化)、子阵列构造、旋转不变性矩阵的建立、最小二乘估计等部分。通过运行这两个文件,可以比较它们在估计精度和计算效率上的异同。 3. TLS_ESPRIT算法 TLS(Total Least Squares)ESPRIT是对普通ESPRIT的优化,它考虑了数据噪声的影响,提高了估计的稳健性。在TLS_ESPRIT算法中,不假设数据噪声是高斯白噪声,而是采用总最小二乘准则来拟合数据。这使得算法在噪声环境下表现更优。`TLS_esprit.m`文件应该包含了TLS_ESPRIT算法的完整实现,包括TLS估计的步骤和旋转不变性矩阵的改进处理。 在实际应用中,选择合适的ESPRIT变体取决于系统条件,例如噪声水平、信号质量以及计算资源。通过MATLAB实现,研究者和工程师可以方便地比较不同算法的效果,并根据需要进行调整和优化。同时,这些代码也为教学和学习DOA估计提供了一个直观的平台,有助于深入理解ESPRIT算法的工作原理。
HDFS(Hadoop Distributed File System)是Hadoop生态系统中的一部分,它是一个可伸缩的分布式文件系统,可以在大型集群中存储和处理超大型数据集。下面是HDFS读写流程和原理: 1. 写入流程 (1)客户端向NameNode请求写入文件,NameNode返回一个DataNode列表,客户端接收到后与DataNode进行数据通信。 (2)客户端将数据划分为一个个数据块,并与DataNode建立连接,将数据块写入DataNode。 (3)DataNode接收到数据块后,先将数据写入本地磁盘,然后将数据块复制到其他DataNode上,以实现数据备份。 (4)客户端在写入完数据后,向NameNode发送文件元数据,即文件名、数据块ID、数据块所在的DataNode等信息,NameNode将这些信息保存在内存中,并更新元数据信息。 2. 读取流程 (1)客户端向NameNode请求读取文件,NameNode返回一个DataNode列表和对应的数据块位置信息。 (2)客户端与DataNode建立连接,请求数据块,DataNode将数据块返回给客户端。 (3)客户端读取完所有数据块后,将数据块组合成完整的文件。 HDFS的主要原理是数据分片和复制。HDFS将大文件划分为多个数据块,每个数据块默认大小为128MB,每个数据块会复制到多个DataNode上,以实现数据备份和容错。NameNode负责管理文件系统的元数据,包括文件名、文件目录、数据块位置等信息,而DataNode则负责数据块的存储和读写。这种分布式存储方式可以实现高可用性和高可靠性,并且可以通过增加DataNode数量来提高存储和读写性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值