HDFS详解(架构设计、副本放置策略、读写流程、进程、常用命令等)

    前言:当数据集的大小超过一台独立的物理计算机的存储能力时,就有必要对它进行分区(Partition)并存储到若干台单独的计算机上。管理网络中跨多台计算机存储的文件系统成为分布式文件系统(distributed filesystem)。该系统架构与网络之上,势必会引入网络编程的复杂性,因此分布式文件系统比普通磁盘文件系统更为复杂。例如:使文件系统能够容忍节点故障且不丢失任何数据,就是一个极大的挑战。

一、HDFS的设计

    HDFS是以流式数据访问模式来存储超大文件,具有以下特点:

  1. 流式数据访问    HDFS构建思路决定为:一次写入、多次读取是最高效的访问模式。
  2. 商用硬件    Hadoop不需要部署在高昂且高可靠的硬件上,HDFS的设计使得数据的靠可性和安全性增加。
  3. 低时间延迟的数据访问    HDFS不适合此种方式,对于低延迟的访问需求,可以选择HBase。
  4. 大量的小文件    Namenode用于存储文件系统的元数据,首相与Namenode的内存,对于大量的小文件,Namenode的管理压力过大。
  5. 多用户写入,任意修改文件    HDFS不支持多用户写入操作,也不支持在文件任意位置进行修改,数据的添加在文件的末尾。

二、HDFS的架构设计

    HDFS的架构遵循主/从架构模式,主要进程为Namenode,Datanode,Secondarynamenode,在启动过程中,启动顺序也是按照这个顺序。

    对于磁盘的存储,我们每个磁盘都有默认的数据块,文件系统块的大小(默认512字节)一般为数据块的整数倍。对于HDFS同样有数据块这一概念,原先官方默认的数据块为64M,目前新版本的默认为128M。若想改变这一默认,需要修改HDFS的配置文件,名称为:dfs.blocksize,默认128M。

    Q1:HDFS块为何这么大?

    A:HDFS的块比磁盘的块大,目的是最小化寻址开销。如果块设置的足够大,从磁盘传输数据的时间会明显大于定位这个块开始位置的时间。假如寻址时间为10ms,文件传输速率为100MB/s,为了使寻址时间仅占传输时间的1%,我们就需要将块设置为100MB左右,以此来达到最优占比。但是数据块也不宜设置过大,因为Mapreduce的map任务每次只处理一个数据块,故如果任务量少于集群的节点数量,作业运行速度就比较慢。

    Q2:对于一个130M的文件,需要几个块,如何分配,实际存储大小是多少?

    A:需要两个块,分别为128M 2M ,实际存储大小也是为130M。

扫描二维码关注公众号,回复: 1464818 查看本文章

    HDFS架构图如下图所示。


    HDFS集群有两类节点以管理者-工作者模式运行,即Namenode(管理者)和多个Datanode(工作者)(也包含Namenode的辅助节点Secondarynamenode)。

    1、Namenode负责内容

  • 文件系统的命名空间
  • 文件名称,字节数
  • 文件目录结构
  • 文件的属性(权限、创建时间、副本数)
  • 文件对应哪些数据块以及数据块对应哪些datanode节点

    作用:管理文件系统的命名空间。维护着文件系统书以及整棵树内所有的文件和目录。这些信息以两个文件形式永久保存在本次磁盘上:命名空间镜像文件fsimage和编辑日志文件editlog。NN官方默认配置为1000M

    在工作环境中,我们可能面临诸多文件都是小文件的状况,这时候就需要考虑小文件如何压缩成大文件。

    假设一个文件的名称占30字节,对于NN默认内存为1000M,则可以存储3495 2522个文件名称。假如我们有3495 2522个小文件,每个文件是1M,则我们会有3495 2522个数据块,那么NN中的文件名称就会占满NN的内存,这样一来不利于NN节点的工作。若我们将3495 2522个小文件,压缩成128M一个的文件,需要27 3067个文件,这时候在NN中所需要的文件名称存储大小就仅为7.8M,大幅度降低了NN维护的压力,同时DN实际存储没有变化。

    2、Datanode负责内容

  • 数据块和数据块校验和

    Datanode与Namenode通信方式:每隔3秒发送一个心跳包,每十次心跳发送一次blockReport

    3、Secondarynamenode

  • 定期整合fsimage和editlog文件

    作用就是定期合并fsimage+editlog文件为新的fsimage,推送给namenode,俗称检查点动作,checkpoint,时间周期为默认1小时;内存大小默认64M。



三、副本放置策略

  1. 第一副本:放置在上传文件的DataNode上;如果是集群外提交,则随机挑选一台磁盘不太慢,CPU不太忙的节点上;
  2. 第二副本:放置在于第一个副本不同的机架节点上;
  3. 第三副本:与第二个副本相同机架的不同节点上;
  4. 如果还有更多的副本,则随机放在节点中。

下图为三副本配置示意图


四、文件读写流程


  1. Client通过FileSystem.open(filepath)方法,去与Namenode进行rpc通信,返回该文件的部分或全部的block列表(也包含该列表各block的分布在Datanode地址的列表),也就是返回FSDataInputStream对象;
  2. Client调用FSDataInputStream对象的read()方法:
  • 去与第一个块的最近的Datanode进行read,读取完成后,会check,加入successful,会关闭与当前Datanode通信;(假如check fail,会记录失败的块和Datanode信息,下次就不会读取;那么回去该块的第二个Datanode地址读取)
  • 然后去第二个块的最近的Datanode上进行读取,check后,关闭此Datanode的通信;
  • 假如block列表读取完了,文件还未结束,那么FileSystem会从Namenode获取下一批的block的列表。(读操作对于Client端是透明的,感觉就是连续的数据流)

     3.Client调用FSDataInputStream.close()方法,关闭输入流。



  1. Client调用FileSystem.create(filepath)方法,去与Namenode进行rpc通信,check该路径的文件是否存在以及有没有权限创建该文件,假如可以,就创建一个空的新文件,但是并不关联任何block,返回一个FSDataOutputStream对象;(假如不可以创建,就返回错误信息,一般代码要带有try-catch去捕捉异常)
  2. Client调用FSDataOutputStream对象的write()方法,会将第一个块写入第一个Datanode,第一个Datanode写完传给第二个节点,第二个写完传给第三个节点,当第三个节点写完返回一个ack packet给第二个节点,第二个返回一个ack packet 给第一个节点,第一个节点返回ack packet给FSDataOutputStream对象,表示第一个块写完,副本数为3;
  3. 剩余的块依次这样写;
  4. 当向文件写入数据完成后,Client调用FSDataOutputStream.close()方法,关闭输入流,flush缓存区的数据包;
  5. 再调用FileSystem.complete()方法,告诉Namenode节点写入成功。

五、pid进程详解

    Hadoop进程的pid文件默认存放在/tmp目录中,linux默认情况下是一个月清空一次。若将pid文件删除了,对我们的HDFS运行没有影响,但是当停止集群时,若将namenode的pid删除,会发生错误显示:no namenode to stop。这时会存在残留进程,下次启动时可能启动不起来,不利于集群维护。(jps显示的是hsperfdata文件中的内容)


    解决方法是不修改Linux系统内容,而是更改Hadoop的pid进程的默认存储路径,进入etc配置文件,修改hadoop-env.sh文件。

cd /opt/software/hadoop-2.8.1/etc/hadoop
# The directory where pid files are stored. /tmp by default.
# NOTE: this should be set to a directory that can only be written to by 
#       the user that will run the hadoop daemons.  Otherwise there is the
#       potential for a symlink attack.
export HADOOP_PID_DIR=${HADOOP_PID_DIR}
export HADOOP_SECURE_DN_PID_DIR=${HADOOP_PID_DIR}

六、HDFS常用命令

    1、hadoop fs == hdfs dfs

命令的执行要在bin目录下
例:./hadoop fs -ls /
hadoop fs -ls / 查看
hadoop fs -lsr
hadoop fs -mkdir /user/haodop 创建文件夹
hadoop fs -put a.txt /user/hadoop 上传到hdfs
hadoop fs -get /user/hadoop/a.txt 从hdfs下载
hadoop fs -cp src dst 复制
hadoop fs -mv src dst 移动
hadoop fs -cat /user/hadoop/a.txt 查看文件内容
hadoop fs -rm /user/hadoop/a.txt 删除文件
hadoop fs -rmr /user/hadoop 删除文件夹
hadoop fs -text /user/hadoop/a.txt 查看文件内容
hadoop fs -copyFromLocal localsrc dst  与hadoop fs -put功能类似
hadoop fs -moveFromLocal localsrc dst 将本地文件上传到hdfs,同时删除本地文件

    2、帮助命令查看

hadoop帮助命令查看,不需要输入help,只需要在bin目录下输入即可。
例:./hadoop 
    ./hadoop fs

猜你喜欢

转载自blog.csdn.net/qq_25302531/article/details/80563216
今日推荐