HDFS理论基础

什么是HDFS?

Hadoop是Apache软件基金会所开发的并行计算框架与分布式文件系统,是Hadoop分布式文件系统(Hadoop Distributed File System)的缩写,为分布式计算存储提供了底层支持。采用Java语言开发,可以部署在多种普通的廉价机器上,以集群处理数量积达到大型主机处理性能。

HDFS的存储模型

  • 文件按字节线性切割成块(block),块的大小默认为128M(hadoop1.0版本为64M),并具有offset,id。
  • 文件与文件的大小可以不一样。
  • 一个文件除最后一个block,其他block的大小是一致的。
  • block被存储在不同的集群节点上。
  • block具有副本(replication),副本没有主从概念,且相同的副本不能保存在同一台机器上。
  • 文件上传时可以指定block的大小和副本数量,上传之后只能修改副本数量。
    HDFS支持一次写入多次读取,支持追加数据,但不支持修改。

HDFS的架构模型

  • HDFS是一个主从架构模型(master/slaver)。
  • 由NameNode和多台DataNode组成。
  • 面向文件包含:文件数据(data)和文件源数据(metadata)。
  • NameNode管理元数据并维护一个文件目录树,DataNode管理文件数据(block)并提供文件的读写服务。
  • DataNode和NameNode保持心跳连接,并定时向NameNode汇报自己所保存的block信息。
  • client与NameNode交互文件元数据,与DataNode交互block数据。
    HDFS架构图

角色功能

  • Namenode

完全基于内存存储元数据(因为其要快速的对外提供服务),目录结构和文件block的映射,需要进行持久化以保证数据的可靠性。提供副本的存储策略。

  • Datandode
    基于本地磁盘存储block文件数据,与NameNode保持心跳连接,并向NameNode汇报其所保存的block状态。

元数据的持久化

  • 任何对HDFS元数据产生修改的操作,NameNode都会将其写入一个名为EditLog的日志文件。
  • 使用FsImage来存储所有的元数据状态,本地磁盘保存EditLog和FsImage。
  • EditLog文件体积小,数据丢失少,但恢复速度慢,并且有体积膨胀风险。
  • FsImage恢复速度快,体积与内存占用不大,但不能实时保存,容易造成数据丢失
  • 使用EditLog+FsImage的方式,滚动将EditLog更新到FsImage中,以保证数据不丢失,并减小EditLog的体积。

HDFS中的SNN

在非HA模式下,SNN(Secondary Namenode)一般是独立的节点,周期性地完对NN中的EditLog和FsImAGE的合并工作,减少EditLog的大小。周期时间可以根据配置项fs.checkpoint.period来设置,默认是3600秒,此外EditlLog的大小使用fs.checkpoint.size来设置,默认大小是64M。
SNN

Block副本的存储策略

  • 第一个副本就存储在上传的Datanode中(这样不需要走IO,也不需要走网络传输),如果是集群外提交(即DataNode不在本集群),则随机挑选一台磁盘不太满,CPU空闲的节点存放。
  • 第二个副本尽可能与第一个副本不在一个机架上,以保证可靠性。
  • 第三个副本放在与第二个副本相同机架的不同机器上(考虑到成本),如果有更多副本,则随机存放

HDFS写流程

  1. 客户端想Namenode发送RPC写数据请求,假设副本数量为3。
  2. NameNode 首先检查要创建的文件是否已经存在,创建者是否有权限进行操作,成功则会触发Block副本存储策略,返回n个要进行存储的DataNode,其中n为副本的数量。并为文件创建一个记录,将记录写到EditLog中,否则会让客户端抛出异常;
  3. 客户端和返回的第一个DataNode建立TCP连接,再由第一个DataNode和第二个DataNode建立TCP连接,再由第二个DataNode和第三个DataNode建立TCP连接,而不是一个客户端同时和三个DataNode建立连接
  4. 客户端与第一个DataNode建立连接后,将第一个block以packet为单位进行传输,packet大小为64K,同时写入时DataNode会以chunk为单位进行校验,chunk会被写入到packet中,默认大小为512B(因为还有4B大小的校验值,所以实际写入的大小为516B)。
  5. 当第一个DataNode收到packet后,就会将packet分发到第二台DataNode,第二台再分发到第三台。第一台DataNode会有一个应答队列等待后面的DataNode应答。
  6. client会重复以上操作,直到所有block传输成功,同时DataNode会向NameNode汇报自身所有的块信息。
    :如果中间有block传输失败,那么上游节点会直接连接失败节点的下游节点继续传输,最终在完成一个block块的传输时,DataNode向NameNode汇报block信息,NameNode会发现副本数量不够,然后触发Datanode复制更多副本。
    HDFS写流程

HDFS读流程

  1. 客户端调用FileSystem 实例的open()方法,获得这个文件对应的输入流InputStream。
  2. 通过RPC 远程调用NameNode ,获得NameNode 中此文件对应的数据块保存位置,包括这个文件的副本的保存位置( 主要是各DataNode的地址) 。
  3. 获得输入流之后,客户端调用read()方法读取数据。选择最近的DataNode 建立连接并读取数据。
  4. 如果客户端和其中一个DataNode 位于同一机器(比如MapReduce 过程中的mapper 和reducer),那么就会直接从本地读取数据。
  5. 到达数据块末端,关闭与这个DataNode 的连接,然后重新查找下一个数据块。
  6. 不断执行第2 - 5 步直到数据全部读完。
  7. 客户端调用close ,关闭输入流DFS InputStream
    注: 读流程引自k_q的博客HDFS读流程
发布了4 篇原创文章 · 获赞 0 · 访问量 36

猜你喜欢

转载自blog.csdn.net/qq_37163925/article/details/105574928
今日推荐