淘先锋技术网

首页 1 2 3 4 5 6 7

目录

HDFS基础

HDFS架构

副本存储策略

Block 块

HDFS读写

HDFS写数据

写文件异常情况处理

HDFS读数据

NAMENODE对元数据的管理

伪分布式Hadoop安装(CDH版本)

JAVA 操作HDFS

JAVA API 操作HDFS文件


HDFS基础

HDFS设计目标

●巨大的分布式文件系统

●运行在普通、低廉的硬件上

●易扩展,为用户提供性能不错的文件存储服务

HDFS架构

●HDFS集群分为两大角色:NameNode(Secondary Namenode)、DataNode

●一个Master(Name Node),对应多个Slave(DataNode)

●一个文件会被拆分成多个block,blocksize:128M.

●Name Node:

1、负责客户端请求的响应;

2、负责元数据(文件名称、副本系数、Block存放的DN)的管理

●Data Node:

1、存储用户的文件对应的数据块(Block);

2、定期向Name Node发送心跳,汇报本机器所有的Block信息,健康状况

●NameNode和N个DataNode,建议NN和DN部署在不同的节点上

Hadoop中封装了PRC框架,Namenode,datanode等之间的通信都是用内置rpc框架进行。

副本存储策略

replication factor:副本系数、副本因子 (文件拷贝数量)

●如果写请求方所在机器是其中一个datanode,则直接存放在本地,否则随机在集群中选择一个datanode;

●第二个副本放在其他机架的某一个机器上面;

●第三个副本放在第二个副本相同机架的另外一个机器上面;

●如果还有更多的副本:随机放在节点中;

Block 块

从2.7.3版本开始,官方关于Data Blocks 的说明中,block size由64 MB变成了128 MB的。

block数据块是HDFS文件系统基本的存储单位 

block(块)128M 小于一个块的文件,不会占据整个块的空间

block数据块大小设置较大的原因: 

1)减少文件寻址时间 

2)减少管理块的数据开销,每个块都需要在NameNode上有对应的记录 

3)对数据块进行读写,减少建立网络的连接成本 

HDFS优点 

●数据冗余、硬件容错

●处理流式的数据访问

●适合存储大文件

●可构建在廉价机器上

HDFS缺点

●低延迟的数据访问

●不适合存储小文件存储

HDFS读写

HDFS写数据

流程

1、client向namenode请求上传文件;

2、namenode检查完目标及目录是否存在,返回可以上传;

3、client按照block大小(默认128M)将要上传的文件进行切分;

首先客户端client需要知道1、默认block大小128M,2、默认副本系数3

4、client向namenode通信请求上传文件(内容包括:文件切分后的block大小(第一个block信息),文件副本系数);

5、namenode将文件副本系数个datanode信息返回给client;

6、client请求一台datanode上传数据(本质上是一个RPC调用,建立pipeline),第一个datanode收到请求会继续调用第二个datanode,然后第二个调用第三个datanode,将整个pipeline建立完成,逐级返回客户端 ;

7、client开始往A上传第一个block(先从磁盘读取数据放到一个本地内存缓存),以packet为单位(一个packet为64kb),当然在写入的时候datanode会进行数据校验,它并不是通过一个packet进行一次校验而是以chunk为单位进行校验(512byte),第一台datanode收到一个packet就会传给第二台,第二台传给第三台;第一台每传一个packet会放入一个应答队列等待应答

8、当一个block传输完成之后,client再次请求namenode上传第二个block的服务器。

上传数据时,datanode的选择策略:

●如果写请求方所在机器是其中一个datanode,则直接存放在本地,否则随机在集群中选择一个datanode;

●第二个副本放在跨机架的某一个机器上面;

●第三个副本放在第二个副本相同机架的另外一个机器上面;

●如果还有更多的副本:随机放在节点中;

写文件异常情况处理

可能的异常模式如下所列:

  • Client 在写入过程中,自己挂了
  • Client 在写入过程中,有 DataNode 挂了
  • Client 在写入过程中,NameNode 挂了

对于以上所列的异常模式,都有分别对应的恢复模式。

当 Client 在写入过程中,自己挂了。由于 Client 在写文件之前需要向 NameNode 申请该文件的租约(lease),只有持有租约才允许写入,而且租约需要定期续约。所以当 Client 挂了后租约会超时,HDFS 在超时后会释放该文件的租约并关闭该文件,避免文件一直被这个挂掉的 Client 独占导致其他人不能写入。这个过程称为 lease recovery。

在发起 lease recovery 时,若多个文件 block 副本在多个 DataNodes 上处于不一致的状态,首先需要将其恢复到一致长度的状态。这个过程称为 block recovery。 这个过程只能在 lease recovery 过程中发起。

当 Client 在写入过程中,有 DataNode 挂了。写入过程不会立刻终止(如果立刻终止,易用性和可用性都太不友好),取而代之 HDFS 尝试从流水线中摘除挂了的 DataNode 并恢复写入,这个过程称为 pipeline recovery。

当 Client 在写入过程中,NameNode 挂了。这里的前提是已经开始写入了,所以 NameNode 已经完成了对 DataNode 的分配,若一开始 NameNode 就挂了,整个 HDFS 是不可用的所以也无法开始写入。流水线写入过程中,当一个 block 写完后需向 NameNode 报告其状态,这时 NameNode 挂了,状态报告失败,但不影响 DataNode 的流线工作,数据先被保存下来,但最后一步 Client 写完向 NameNode 请求关闭文件时会出错,由于 NameNode 的单点特性,所以无法自动恢复,需人工介入恢复。

HDFS读数据

客户端将要读取的文件路径发送给namenode,namenode获取文件的元信息(主要是block的存放位置信息)返回给客户端,客户端根据返回的信息找到相应datanode逐个获取文件的block并在客户端本地进行数据追加合并从而获得整个文件。

流程

1、client跟namenode通信查询元数据(一系列block和所在的datanode节点),找到文件块所在的datanode服务器;

2、挑选一台datanode(就近原则,然后随机)服务器,请求返回第n个block建立socket流;

3、datanode开始发送数据(从磁盘里面读取数据放入流,以packet为单位来做校验);

4、客户端以packet为单位接收,先在本地缓存,然后写入目标文件,后面的block块就相当于是append到前面的block块最后合成最终需要的文件。 

读文件异常情况处理

读文件可能发生的异常有两种:

1、读取过程中 DataNode 挂了

2、读取到的文件数据损坏

HDFS 的文件块多副本分散存储机制保障了数据存储的可靠性,对于第一种情况 DataNode 挂了只需要失败转移到其他副本所在的 DataNode 继续读取。

第二种情况读取到的文件数据块若校验失败可认定为损坏,依然可以转移到读取其他完好的副本,并向 NameNode 汇报该文件 block 损坏,后续处理由 NameNode 通知 DataNode 删除损坏文件 block,并根据完好的副本来复制一份新的文件 block 副本。

NAMENODE对元数据的管理

更新元数据:

1、更新到内存;

2、记录追加操作日志:edits inprocess ,edits 002,edits 003;

3、secondary namenode定时向namenode请求是否需要checkpoint(合并);

4、secondary namenode向namenode请求checknode(合并那些已经完成的edits文件,同时可以滚动让edits inporcess结束并生成edits 00..,然后新的元数据更新到新的edits inprocess),将edits 00文件和fsimage下载到secondary namenode进行合并;

5、在secondary namenode上dump一个新fsimage.checkpoint;

6、secondary namenode上传fsimage.checkpoint到namenode,重命名覆盖fsimage镜像文件。

7、secondary node的作用只有一个:image镜像文件的管理。

8、namenode的内存一般有128G。

9、每一个block占元数据150BYTE,hdfs集群不适合存储大量小文件,因为有可能namenode满了(小文件也要占用name node的150BYTE),而datanode未满。

namenode如果磁盘坏掉,只能通过second name node 恢复一部分数据(上次合并后的);

所以为了避免数据丢失,应该让name node的数据存在多块磁盘上,通过配置文件hdfs-site.xml。

data node工作目录也可以配置多磁盘,但是namenode的数据都是相同的多份,而data node的数据是分布式存储。

name node工作目录下有一个:seen_txid文件,记录的是edits滚动的序号,每次重启namenode时,namenode就知道将哪些edits进行加载(加载到内存)。

启动HDFS文件系统过程:

1、启动namenode:

2、读取fsimage元数据镜像文件,加载到内存中。

3、读取editlog日志文件,加载到内存中,使当前内存中元数据信息与上次关闭系统时保持一致。然后在磁盘上生成一份同内存中元数据镜像相同的fsimage文件,同时生成一个新的null的editlog文件用于记录以后的hdfs文件系统的更改。

4、启动datanode:

5、向namenode注册;

6、向namenode发送blockreport。

伪分布式Hadoop安装(CDH版本)

slaves配置data node的hostname。

文件操作命令:hadoop/hdfs fs -各种命令

JAVA 操作HDFS

List集合和迭代器的区别:集合要将所有数据存到内存中,而迭代起是通过hasNext()一个一个读取的。

MapReduce相对于HDFS来讲,它是一个客户端。

客户端写了一个MapReduce程序,假设分配了60M的任务(分配多少任务决定了程序实例跑在一个还是多个datanode上),

假设有300M的数据(HDFS也将文件数据存到多个datanode中),则需要5个MapReduce实例。

这时需要5个MapReduce实例分别去跑300M任务的其中一部分,例如一个实例去跑0-60M的任务。

用流的方式操作HDFS文件,可以实现读取指定偏移量范围的数据。

IOUtils可以实现流的相关拷贝、读取、写入。

HDFS无法实现更改上传文件的内容,只能做到追加。

JAVA API 操作HDFS文件

主要是用FileSystem类。

  

另外有一个IOUtils工具类。

hadoop 默认副本系数是3。