1 - HDFS 文件的写入

1.1 写入过程

1、Client 发起文件上传请求,通过 RPC 与 NameNode 建立连接,NameNode 检查 Client 是否有相应权限,以及目标文件是否已存在、父目录是否存在,向 Client 返回是否可以上传;

2、Client 从 NameNode 中获取第一个 block 的传输目的地,也就是应该传输到哪些 DataNode 上;

3、NameNode 根据配置文件中指定的备份数量及机架感知原理进行文件分配,返回可用的 DataNode 的地址,假设分别是 A、B、C;

机架感知:Hadoop 在设计时考虑到数据存储的安全与高效,数据文件在 HDFS 上默认存放三份副本。

副本的存储策略为:客户端所在 DataNode 一份,同机架内其它某一节点上一份,不同机架的某一节点上一份。

4、Client 先向 DataNode A 上传数据(也是一个 RPC 调用,建立 pipeline ),A 收到请求会继续调用 B,然后 B 调用 C,建立完成所有的 pipeline 之后,逐级返回 Client;

5、Client 开始向 DataNode A 上传第一个 block,以 packet 为单位(默认是64K),A 收到一个 packet 就会传给 B,B 传给 C,A 每传一个 packet 会放入一个 ack 队列等待应答;

6、数据被分割成一个个的 packet 数据包在 pipeline 上依次传输,在 pipeline 反方向上逐个发送 ack(操作是否成功的应答),最终由 pipeline 中第一个 DataNode 节点 A 将 pipelineack 发送给 Client;

7、当一个 block 传输完成后,Client 再次请求 NameNode 上传第二个 block ,继续上述 (4) - (7) 步骤。

1.2 写入异常时的处理

当数据写入失败时,HDFS 会作出以下反应:

首先管道会被关闭,任何在确认通知队列中的文件包都会被添加到数据队列的前端,以确保故障节点下游的 DataNode 不会漏掉任何一个数据包。

为存储在另一个正常的 DataNode 的当前数据块指定一个新的标识,并将标识传送给 NameNode,以便 故障 DataNode 在恢复后可以删除存储的部分数据块

删除故障 DataNode 的 pipeline 连接,基于两个正常的 DataNode 构建新的 pipeline,剩余的数据块写入新的 pipeline 中。

NameNode 在注意到副本个数不足时,会在其他 DataNode 上创建一个新的副本。后续的数据块就能正常的接受处理。

1.3 写入的一致性

  • 新建一个文件后,HDFS 的命名空间中立即可见;
  • 写入文件的内容不保证立即可见(即使数据流已经调用 flush() 方法刷新并存储);
  • 当前正在写入的块对其他 Reader 不可见;
  • 调用 hflush() 方法后,数据被写入 DataNode 的内存中,可保证对所有 Reader 可见;
  • 调用 hsync() 方法后,数据就会被写到磁盘上;
  • 如果没有调用 hflush()hsync(),客户端在故障的情况下可能丢失正在写入的数据块。

2 - HDFS 文件的读取

2.1 读取过程

1、Client 向 NameNode 发起 RPC 请求,来确定请求文件 block 所在的位置;

2、NameNode 会视情况返回文件的部分或者全部 block 列表:对每个 block,NameNode 都会返回含有该 block 副本的 DataNode 地址 —— 按照集群拓扑结构得出 DataNode 与客户端的距离,然后进行排序,排序规则是:

网络拓扑结构中距离 Client 近的靠前 —— 网络拓扑需要根据数据中心、机架、数据节点等因素手动设置;

心跳机制中超时汇报的 DataNnode 状态为 STALE 的排靠后。

3、Client 选取排序靠前的 DataNode 来读取 block,如果客户端本身就是 DataNode,就会从本地直接获取数据(短路读取特性);

4、底层本质是建立 Socket Stream(FSDataInputStream),重复调用父类 DataInputStream 的 read 方法,直到这个 block 上的数据读取完毕;

5、当读完列表的 block 后,若文件读取还没有结束,客户端会继续向 NameNode 获取下一批的 block 列表;

DataInputStream#read() 方法是并行读取 block 信息,仍然是以 packet 为单位(默认是64K)在 pipeline 上依次传输;

6、读取完所有的 block 后,客户端会将它们合并成一个完整的文件。

【注意】NameNode 只是返回 Client 请求的 block 的 DataNode 地址,并不会返回 block 的具体数据。

2.2 读取异常时的处理

1)如果客户端和所连接的 DataNode 在读取数据时出现故障,那客户端就会去尝试连接存储这个 block 的下一个最近的 DataNode,同时它会 记录这个发生故障的 DataNode,以免后面再次连接该节点。

2)客户端每读完一个 block 都会进行 checksum 验证,如果从某个 DataNode 上读取到的 block 是损坏的,客户端会通知 NameNode 更新该 block 的相关信息,然后从下一个拥有该 block 副本的 DataNode 继续读取文件。

版权声明

作者:瘦风(https://healchow.com)

出处:博客园-瘦风的南墙(https://www.cnblogs.com/shoufeng)

感谢阅读,公众号 「瘦风的南墙」 ,手机端阅读更佳,还有其他福利和心得输出,欢迎扫码关注

HDFS 03 - 你能说说 HDFS 的写入和读取过程吗?的更多相关文章

  1. HDFS写入和读取流程

    HDFS写入和读取流程 一.HDFS HDFS全称是Hadoop Distributed System.HDFS是为以流的方式存取大文件而设计的.适用于几百MB,GB以及TB,并写一次读多次的场合.而 ...

  2. 从HDFS的写入和读取中,我发现了点东西

    摘要:从HDFS的写入和读取中,我们能学习到什么? 本文分享自华为云社区<从HDFS的写入和读取中,我们能学习到什么>,作者: breakDawn . 最近开发过程涉及了一些和文件读取有关 ...

  3. Hadoop HDFS (3) JAVA訪问HDFS

    如今我们来深入了解一下Hadoop的FileSystem类. 这个类是用来跟Hadoop的文件系统进行交互的.尽管我们这里主要是针对HDFS.可是我们还是应该让我们的代码仅仅使用抽象类FileSyst ...

  4. Hadoop HDFS (3) JAVA訪问HDFS之二 文件分布式读写策略

    先把上节未完毕的部分补全,再剖析一下HDFS读写文件的内部原理 列举文件 FileSystem(org.apache.hadoop.fs.FileSystem)的listStatus()方法能够列出一 ...

  5. HDFS概述(4)————HDFS权限

    概述 Hadoop分布式文件系统(HDFS)的权限模型与POSIX模型的文件和目录权限模型一致.每个文件和目录与所有者和组相关联.该文件或目录将权限划分为所有者的权限,作为该组成员的其他用户的权限.以 ...

  6. HDFS概述(1)————HDFS架构

    概述 Hadoop分布式文件系统(HDFS)是一种分布式文件系统,用于在普通商用硬件上运行.它与现有的分布式文件系统有许多相似之处.然而,与其他分布式文件系统的区别很大.HDFS具有高度的容错能力,旨 ...

  7. 初识HDFS(10分钟了解HDFS、NameNode和DataNode)

    概览 首先我们来认识一下HDFS, HDFS(Hadoop Distributed File System )Hadoop分布式文件系统.它其实是将一个大文件分成若干块保存在不同服务器的多个节点中.通 ...

  8. HDFS API 操作实例(一) HDFS读写操作

    1. 读取HDFS文件 1.1 字符读取HDFS上的文件 Configuration conf = new Configuration(); Path path = new Path(pathstr) ...

  9. Flume启动时报错Caused by: java.lang.InterruptedException: Timed out before HDFS call was made. Your hdfs.callTimeout might be set too low or HDFS calls are taking too long.解决办法(图文详解)

    前期博客 Flume自定义拦截器(Interceptors)或自带拦截器时的一些经验技巧总结(图文详解) 问题详情 -- ::, (agent-shutdown-hook) [INFO - org.a ...

随机推荐

  1. vs中python包安装教程

    vs安装python很简单,只需要在vs安装包中选择python就可以了,这里使用的python3.7: 如果有了解,都知道安装python包的指令:"pip install xxx&quo ...

  2. hdu3652B-number (数位dp)

    Problem Description A wqb-number, or B-number for short, is a non-negative integer whose decimal for ...

  3. fiddler抓包+雷电模拟器 完成手机app抓包的配置

    1.下载最新版Fiddler,强烈建议在官网下载:https://www.telerik.com/download/fiddler 不下载最新版的话,配置起来会遇到很多问题,弄太麻烦了.因为我下载的是 ...

  4. vi、wc、gzip、bzip2、tar、yum安装、dpek、用户信息操作等命令

    命令模式 输入"dd"即可将这一行删除 按下"p"即可粘贴 插入模式: a:从光标这个位置之后插入 A:在行尾插入 i:从光标之前插入 I:行首插入 o:在光标 ...

  5. 使用cfssl生成自签证书

    安装ssl wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 wget https://pkg.cfssl.org/R1.2/cfssljson_li ...

  6. Linux-单用户/救援模式

    目录 企业案例一:忘记root密码 企业案例二:修改了默认的运行级别为poweroff或者reboot 企业案例三:误损坏MBR(只能以救援模式解决) 企业案例四:误删除GRUB菜单(只能以救援模式解 ...

  7. WOJ1022 Competition of Programming 贪心 WOJ1023 Division dp

    title: WOJ1022 Competition of Programming 贪心 date: 2020-03-19 13:43:00 categories: acm tags: [acm,wo ...

  8. C++的memset

    1. 需要的头文件 C中为<memory.h> 或 <string.h> C++中为<cstring> void * memset ( void * ptr, in ...

  9. HDU - 4462 Scaring the Birds

    It's harvest season now! Farmer John plants a lot of corn. There are many birds living around his co ...

  10. C++ part2

    为什么析构函数必须是虚函数?为什么C++默认的析构函数不是虚函数? references: nowcoder 将可能会被继承的父类的析构函数设置为虚函数,可以保证当我们new一个子类,然后使用基类指针 ...