大数据框架Hadoop(二)HDFS

大数据框架Hadoop(二)HDFS

hdfs是是一个分布式的(Distributed)文件(File)系统(System)

  • 通俗的说,hdfs是一个可以管理多台机器文件的管理系统。
  • 允许文件通过网络在多台主机上分析的文件系统,可以让多机器上的多用户分享文件和存储空间。
  • 通透性。让实际上通过网络来访问文件的动作,由程序与用户看来,就像是访问本地磁盘一样。
  • 容错。若系统中有些节点宕机,整体来说系统可以持续运作而不会有数据损失(通过副本机制实现)
  • 分布式文件管理系统(hdfs,S3,GFS等)很多,hdfs只是其中一种,hdfs不适合存储小文件。

HDFS Shell

  • hdfs shell是操作分布式文件系统的一个客户端
    • 使用格式 bin/hdfs dfs -xxx URL
      • URL格式是 scheme://authority/path。HDFS的scheme是hdfs,对本地文件系统来说scheme是file。scheme和authority参数都是可选的,如果未加指定,就会使用配置中指定的默认scheme。
      • 如: /parent/child可以表示成hdfs://hadop100:9000/parent/child
      • scheme://authority/path
      • hdfs://ip:port/path
      • 大多数hdfs shell的命令和对应Linux shell命令类似
      • 常用命令 -xxx
      • -ls /
    • 路径为空,显示/user/<currentuser>
    • -h 显示文件大小时选用合适单位
    • -R 递归显示路径的索引内容
      • -put localSrc hdfsDst
    • 从本地上传文件(文件夹)到hdfs。如果上传位置已经存在同名的文件(文件夹)则报错。
    • -f 覆盖同名文件(文件夹)
    • -p 上传时保留文件原理的ownid、groupid、accesstime、modification time等属性。
      • -get hdfsSrc localDst
    • 从hdfs下载文件到本地
      • -mkdir hdfsDst
    • 创建文件夹
    • -p 递归创建
      • -cp hdfsSrc hdfsDst
    • 在hdfs上复制
      • -help cmd
    • 显示命令帮助
      • -cat url url
    • 将路径指定文件的内容输出到stdout。
      • -test -e
    • 判断hdfs目录是否存在

RPC(远程过程调用协议)

  • RPC(Remote Procedure Call)是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。
  • RPC采用C/S模式。请求程序是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,等待应答信息。在服务器端,进程保持睡眠状态直到调用信息的到达。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最好和互动调用进程接收答复信息,获得进程结构,然后调用执行继续进行。
  • Hadoop整个架构都是建立在RPC上的。
  • RPC接口分析
    • ClientProtocol
      • 客户端(FileSystem)与Namenode通信的接口。
        • DatanodeProtocol
        • DataNode与NameNode通信的接口。
        • NamenodeProtocol
        • SecondaryNameNode与NameNode通信的接口。

hdfs体系结构

hdfs体系架构

  • Client与NameNode、NameNode与SecondNameNode、DataNode与NameNodet通过PRC协议通信。
  • Client与DataNode通过TCP进行通信。

HDFS 客户端使用

hdfs客户端

NameNode

  • NameNode是整个文件系统的管理节点。
    • 它接受客户端请求。
    • 维护整个文件系统的目录树,文件/目录的元信息以及每个文件对应的数据块(block)列表。
      • 维护两个关系:文件与block list的关系(对应的关系信息存储在fsimage和edits文件中,当Namnode启动时会把文件中的内容加载到内存中);DataNode与block的关系(当DataNode启动时,会把当前节点上的block信息和节点信息上报给NameNode)
  • NameNode主要包括以下文件【/data/hadoop_repo/name/current】
    • fsimage:元数据镜像。存储某一时刻NameNode内存中的元数据信息。
    • edits:操作日志文件【事务文件】
    • seen_txid:存放transactionid的文件,format之后为0,代表是Namnode里面edits_*文件的位数,NameNode重启时,会按照seen_txid的顺序,顺序从头跑edits_000 0001 ~到seen_txid的数字。如果根据对应的seen_txid无法加载到对应的文件,NameNode进程将不会完成启动以保护数据一致性。
    • VERSION:保存了HDFS的版本信息。

SecondaryNameNode

  • 定期把edis文件中的内容合并到fsimage中
    • 这个合并操作成为checkpoint(快照)
    • checkpoint条件:离上一次checkpoint操作是否已经一个小时,或者hdfs已经进行了100万次操作
    • 合并的适合会对edits中的内容进行转化,生成新的内容保存到fsimage文件中。
  • Hadoop2.x中针对NameNode提供了HA机制,可以有两个NameNode(active NN && standby NN)。Standby NN 负责实现把edits中的内容合并到fsimage中,同时清除旧的edits文件。所以这种架构下就不需要SecondaryNameNode进程了。

DataNode

  • 提供真实文件数据的存储服务

    • 存储目录通过hdfs-default.xml文件中的dfs.datanode.data.dir参数控制
  • 文件块(block):最基本的存储单位。对于文件内容而言,一个文件长度大小是size,那么从文件的0偏移开始,按照固定的大小,顺序对文件进行划分并编号,划分好的每一块成一个Block。HDFS默认的block块大小是128M。一个256M的文件会被划分成2个block。

  • HDFS中,如果一个文件小于一个数据块的大小,并不会占用整个数据块的存储空间。

  • Replication:多副本,默认是三个

    • hdfs-site.xml的dfs.replication属性。

    • Client读取多副本文件过程(取最近节点的block)

hdfs 文件读写流程

数据存储-读文件

hdfs_read

  • 读文件流程分析
    1. 调用FileSystem对象的open方法,其实时DistributedFileSystem的实例
    2. DistributedFileSystem通过rpc获得文件的第一个block的location,同一个block按照副本数会返回多个locations,这些locations按照hadoop拓扑结构排序,距离客户端近的排在前面。
    3. 前两步会返回一个FSDataInputStream对象,该对象会被封装成DFSInputStream对象,DFSInputStream可以方便的管理datanode和namenode数据流。客户端调用read方法,DFSInputStream会找出离客户端最近的datanode并进行连接。
    4. 数据从datanode源源不断流向客户端。
    5. 如果第一块数据读完了,就会关闭指向第一块datanode连接,接着读取下一块,这些操作对客户端来说时透明的,客户端的角度来看只是读一个持续不断的流。
    6. 如果第一批block都读完了,DFSInputStream就会去namnode拿下一批blocks的location,然后继续读,如果所有的块都读完,这时就会关闭掉所有的流。
    7. 如果在读数据的时候,DFSInputStream和dataNode的通讯发生异常,就会尝试正在读的block的排第二近的datanode,并且会记录哪个datanode发生错误,剩余blocks读的时候会直接跳过该datanode。DFSInputStream也会检查block数据校验和,如果发现一个坏的block,就会先报告到namenode节点,然后DFSInputStream在其他的datanode上读该block的镜像
  • 该设计方向就是客户端直接连接datanode来检索数据并且namenode来负责为每一个block提供最优的datanode,namenode仅仅处理block location的请求,这些信息都加载在namenode的内存中,hdfs通过datanode集群可以承受大量客户端的并发访问。

hdfs 写文件

hdfs_write

  • 写文件流程分析

    1. 客户端通过调用DistributedFileSystem的create方法创建新文件。

    2. DistributedFileSystem通过RPC调用NameNode去创建一个没有blocks关联的新文件,创建前,NameNode会做各种校验,比如文件是否存在,客户端有无权限去创建等。如果校验通过,NameNode就会记录下新文件,否则就会抛出IO异常。

    3. 前两步结束后会返回FSDataOutputStream的对象,和读文件的时候类似,FSDataOutputStream被封装成DFSOutputStream.DFSOutputStream可以协调NameNode和DataNode。客户端开始写数据到DFSOutputStream,DFSOutputStream会把数据切成一个个小packet,然后排成队列data quene.

    4. DataStreamer会处理接收data quene,他询问NameNode这个新的Block最适合存储到哪几个DataNode里,比如副本数是3.那么就找到3个最适合的DataNode,把他们排成一个pipeline。DataStreamer把packet按队列输出到管道的第一个DataNode中,第一个DataNode又把packet输出到第二个DataNode中,以此类推。

    5. DFSOutputStream还有一个队列叫ack quene,也是由packet组成,等待DataNode收到响应,当pipeline中所有的DataNode都表示已经收到的时候,这时候ack queue才会把对应的packet包移除掉。

      如果在写的过程中某个DataNode发生错误,会采取以下几步:

      1. pipeline被关闭掉。
      2. 为了防止丢包ack queue里的packet会同步到data queue里。
      3. 把产生错误的DataNode上当前在写但未完成的block删掉。
      4. block剩下的部分被写到剩下的两个正常的DataNode中。
      5. NameNode找到另外的DataNode去创建这个块的复制。当然这些操作对客户端是无感知的。
    6. 客户但完成写数据后调用close方法关闭写入流。

    7. DataStreamer把剩余的包都刷到pipeline里然后等待ack信息,收到最后一个ack后,通知DataNode把文件标识为已完成。

  • 注意:客户端执行write操作后,写完得block才是可见的,正在写的block对客户端是不可见的,只有调用sync方法,客户端才确保该文件被写操作已经全部完成,当客户端调用close方法时会默认调用sync方法。是否需要手动调用取决你根据程序需要在数据健壮性和吞吐率之间的权衡。

hdfs 的Trash回收站

  • Hdfs为每一个用户创建一个回收站目录: /user/用户名/.Trash/,

  • 每个被用户通过Shell删除的文件/目录,在系统回收站中都有一个时间周期,也就是当系统回收站中的文件/目录在一段时间之后没有被用户恢复的话,HDFS就会自动的把这个文件/目录彻底删除,之后用户就永远也找不回这个文件/目录了。

  • 配置:在每个节点(不仅仅是主节点)上添加配置core-site.xml增加内容如下(单位:分钟)

    1
    2
    3
    4
    <property>
    <name>fs.trash.interval</name>
    <value>1440</value>
    </property>
  • 注意:如果删除的文件过大,超过回收站大小的话会提示删除失败。需要指定参数 -skipTrash跳过回收站直接彻底删除。

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×