Hadoop 之 HDFS

HDFS架构

  NameNode:负责管理和存储元数据;文件名、目录结构、文件属性(时间、副本、权限)、文件块列表,块所在DataNode(BlockId)。
  DataNode:本地文件系统中存储文件块数据、块校验和。
  SecondaryNameNode:定时将日志文件和镜像文件进行合并。
   说明:谁启动的hdfs谁具有最高权限。

Hadoop 之 HDFS

格式化namenode的过程中都做了什么?
  1.创建文件存储的目录。
  2.创建编辑日志和镜像文件
  3.创建UID

不同进程间节点距离的计算: 节点、机架、集群、数据中心
   特点:不同的节点之间建立连接需要先到达通信节点可以共同到达的最小交汇点,然后再走向目标节点。
  同一节点的进程:0
  同一机架上不同节点进程:2
  同一集群不同机架节点上的进程:4
  同一数据中心不同集群中节点上的进程:6

HDFS数据写入流程:
  1.客户端将文件分块,默认块大小为128M,HDFS不支持并发写入,每次只能上传一个块。
  2.客户端通过分布式文件系统 DistributeFileSystem 向 NameNode 发送上传文件请求,
     NameNode 收到请求后检查目标文件是否存在,父目录是否存在,之后响应客户端可以上传文件。
  3.客户端收到响应后向 NameNode 请求上传第一个块信息,并请求返回 DataNode,NameNode
     收到请求后根据文件的备份数量返回相应数量的 DataNode 节点。
  4.客户端收到来自 NameNode 返回的节点信息,通过 FSDataOutPutStream 向离客户端最近的
     节点上传数据,第一个节点收到请求后会继续调用下一个的DataNode节点,然后下一个节点去调用自己的下一个节点,
   直到最后一个节点,将通信管道 PipeLine 建立,然后各个节点从后向前逐级应答客户端。
  5.通信管道 PipeLine 建立完成后,客户端先将磁盘中的块信息读到内存,然后通过 FSDataOutPutStream
   开始以 Packet 为单位传送块数据,其中 Packet 为64K由 Chunk 组成,每个 Chunk 为 512B
   并且每个 Chunk 还包含了4B的 crc 校验信息,共516B。当 Packet 被 Chunk 填满以后就将 Packet
   放入到应答队列 DataQueue 队列中等待,再从该队列中将 Packet 取出存入另一个队列 ACKQueue 队列中,
   然后将该 Patcket 发送给离客户端最近的 DataNode 。
  6.第一个 DataNode 收到数据后,会将该数据传递给下一个 DataNode,每个节点收到数据后都会逐级传递给
     下个节点直至 PipeLine 中的最后一个节点。并且在传输 Packet 的过程中,每向 DataNode发送一个 Packet
   数据客户端都会等待来自 DataNode 的应答响应,若响应则代表当前节点收来自客户端发送的数据,若没有
   响应时会将 ACKQueun 中的 Packet 数据重新放回到 DataQueue 队列中等待再次发送,避免了数据丢失。
  7.当第一个Block 块信息传输完成后,客户端会再次请求 NameNode 上传第其他个 Block 块信息。
 说明:
   1.块大小的设置,受磁盘读写速度的影响,寻址时间为传输时间的1%为最佳状态,由于寻址时间为 10ms 所以传输时间为1S,
      而磁盘的传输速率约为 100MB/s 所以块大小约100M,但100不是2的整次幂,所以选离它较近的128M。
    如果块太小会导致文件被分的过多造成资源浪费;由于 MapReduce 的切片规则是默认是按照文件的块大小
    切分的,如果块太大了会导致切片过大会使 MapTask 的个数过少,单个 MapTask 的任务量过大,无法快速完成任务。
   2.通信管道 PipeLine 的建立,如果在创建过程中其中某个节点没有应答,客户端会向 NameNode 重新请求 DataNode,
    NameNode 收到请求后会重新分配并发送新的 DataNode;如果在文件传输过程中,某个节点因为某种原因挂掉了,
    或者其他的原因该节点收不到数据没有应答,客户端会正常重新向其发送数据,再重复发一次之后还收不到应答
    则认为该节点不可用便会跳过该节点向其余的节点传送数据,传输完成之后,NameNode 在收到 DataNode 的
    上报信息时会发现少了一个备份,则会将其他节点上的文件自动备份一份。特别:如果是第一个节点有问题,则整个管道
    不会形成,或形成管道之后第一个节点有问题则直接导致任务失败。
  3.每个 Chunk 都会包含4B的 crc 校验信息,所以每传128M的信息都会包含1M的 crc 校验信息。
  4.HDFS不支持随机写,但支持追加写入。

HDFS读出数据流程:
  1.客户端通过 DistributeFileSystem 向 NameNode 申请下载文件请求,NameNode 收到客户端下载请求后通过
     查询文件的元数据找到文件所在的 DataNode ,然后返回包含所有该下载文件的 DataNode 给客户端。
  2.客户端收到 NameNode 发送回来的 DataNode 信息后,会寻找据当前节点最近的 DataNode 节点请求下载文件。
  3.DataNode 收到客户端下载请求后开始向客户端发送数据,先将磁盘中的块信息通过输入流读出到内存,然后以 Packet
     作为单位校验,传输给客户端。
  4.客户端收到 Packet 后先将文件读入到内存然后通过输出流写出到磁盘存储。

NameNode和DataNode:
  1.当开启 DataNode后,DataNode 会主动向 NameNode 申请注册。
  2.注册成功后, DataNode周期性的每隔1小时(默认6)向NameNode上报所有块信息,通过 DataNode 的主动上报,NameNode
     可以检查文件的副本数以及副本信息,如果某个副本存在问题,NameNode 会等到 DataNode 主动上报信息后查询文件信息,发现文件错误或丢失时,
     通知该 DataNode 节点将错误文件丢弃,并从其他 DataNode 节点将其重新备份。并且每3秒1次心跳,心跳中包含了
     NameNode带给 DataNade 的命令信息。
  3.若3秒内没有收到来自 DataNode 的心跳,NameNode 不会立刻认为该节点挂掉了,而时会等待10分30秒的时间,如果
     超过该时间才会认为该节点不可用。
  4.每个数据块在 DataNode 上以文件的形式存储在磁盘上,包括两个文件一个数据本身,另一个是元数据。
  5.NameNode 只记录了 Block与 DataNode 的映射关系,存储了一个 BlockId。

  说明:
    1.之所以让 DataNode 每次自己主动上报而不直接将 DataNode 信息存储在 NameNode 中是无法保证每次 NameNode中
       存储的 DataNode 信息是正确的,NameNode 每次读取 Block 信息时都会计算 CheckSum,如果计算的 CheckSum 与当时创建
     Block是的值不一样则代表Block损坏,会从其他节点备份。
    2. 每一个DataNode 都包含一套完整的块信息。

上一篇:在PHP中,将一个汉字数组按照拼音首字母进行排序


下一篇:hadoop 2.x VS 3.x 端口对比