Hadoop学习笔记-3 HDFS 原理剖析

1. HDFS体系结构

主从。。。


2.NameNode

概念

  • [x] 是整个文件系统的管理节点。它维护着整个文件系统的文件目录树,文件/目录的元信息和每个文件对应的数据块列表。接收用户的操作请求。

  • [x] hdfs-site.xml中的dfs.namenode.name.dir属性

  • [x] 文件包括:

    • [x] 文件包括:

      ①fsimage:元数据镜像文件。存储某一时段NameNode内存元数据信息。

      ②edits:操作日志文件。

      ③fstime:保存最近一次checkpoint的时间

      以上这些文件是保存在linux的文件系统中。

查看 fsimageedits的内容

  1. 查看 NameNode中 fsimage 的内容

    • 查看 fsimage镜像文件内容Usage: bin/hdfs oiv [OPTIONS] -i INPUTFILE -o OUTPUTFILE

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      # 可以知道数据存在那个哪个 fsimage 镜像中
      ------------------------------------
      # 使用离线的查看器 输出到网页查看
      oiv -i hadoopdata/namenode/current/fsimage_0000000000000000250 -o 0000000000000000250

      # 出现这样的提示
      INFO offlineImageViewer.WebImageViewer: WebImageViewer started. Listening on /127.0.0.1:5978. Press Ctrl+C to stop the viewer.

      # 另起一个窗口查看
      hadoop fs -ls -R webhdfs://127.0.0.1:5978
      ------------------------------------

      # 也可以导出到 xml 文件
      bin/hdfs oiv -p XML -i tmp/dfs/name/current/fsimage_0000000000000000055 -o fsimage.xml
  1. 查看edits文件, 也可以导出到 xml

    1
    2
    # 查看edtis内容
    bin/hdfs oev -i tmp/dfs/name/current/edits_0000000000000000057-0000000000000000186 -o edits.xml


3. Datanode

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

  • Datanode 节点的数据切块存储位置

    • ~/hadoopdata/datanode/current/BP-1070660005-192.168.170.131-1527865615372/current/finalized/subdir0/subdir0

      1
      2
      3
      4
      5
      6
      7
      8
      [ap@cs2]~/hadoopdata/datanode/current/BP-1070660005-192.168.170.131-1527865615372/current/finalized/subdir0/subdir0% ll
      总用量 213340
      -rw-r--r-- 1 ap ap 134217728 6月 2 13:35 blk_1073741842
      -rw-r--r-- 1 ap ap 1048583 6月 2 13:35 blk_1073741842_1018.meta
      -rw-r--r-- 1 ap ap 82527955 6月 2 13:35 blk_1073741843
      -rw-r--r-- 1 ap ap 644759 6月 2 13:35 blk_1073741843_1019.meta
      -rw-r--r-- 1 ap ap 13 6月 3 02:12 blk_1073741850
      -rw-r--r-- 1 ap ap 11 6月 3 02:12 blk_1073741850_1028.meta
  • 文件块(block):最基本的存储单位。对于文件内容而言,一个文件的长度大小是size,那么从文件的0偏移开始,按照固定的大小,顺序对文件进行划分并编号,划分好的每一个块称一个Block。HDFS默认Block大小是128MB,以一个256MB文件,共有256/128=2个Block.

  • 不同于普通文件系统的是,HDFS中,如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间, 按文件大小的实际容量存储

  • Replication。多复本。默认是三个。

    • hdfs-site.xmldfs.replication属性
    • 手动设置某个文件的副本数为3个
      • bin/hdfs dfs -setrep 3 /a.txt

4. 数据存储: 写文件解析

  • [x] 疑点: HDFS client上传数据到HDFS时,会首先在本地缓存数据,当数据达到一个block大小时,请求NameNode分配一个block。NameNode会把block所在的DataNode的地址告诉HDFS client。HDFS client会直接和DataNode通信,把数据写到DataNode节点一个block文件中。

    问题: 如果一直写的数据都没有达到一个 block 大小, 那怎么存储??

image-20180603205640605

image-20180603205412264

写文件的过程:

  1. 首先调用FileSystem对象的open方法,其实是一个DistributedFileSystem的实例
  2. DistributedFileSystem通过rpc获得文件的第一批个block的locations,同一block按照重复数会返回多个locations,这些locations按照hadoop拓扑结构排序,距离客户端近的排在前面.
  3. 前两步会返回一个FSDataInputStream对象,该对象会被封装成DFSInputStream对象,DFSInputStream可以方便的管理datanode和namenode数据流。客户端调用read方法,DFSInputStream最会找出离客户端最近的datanode并连接。
  4. 数据从datanode源源不断的流向客户端。
  5. 如果第一块的数据读完了,就会关闭指向第一块的datanode连接,接着读取下一块。这些操作对客户端来说是透明的,客户端的角度看来只是读一个持续不断的流。
  6. 如果第一批block都读完了,DFSInputStream就会去namenode拿下一批blocks的location,然后继续读,如果所有的块都读完,这时就会关闭掉所有的流。

如果在读数据的时候,DFSInputStream和datanode的通讯发生异常,就会尝试正在读的block的排第二近的datanode,并且会记录哪个datanode发生错误,剩余的blocks读的时候就会直接跳过该datanode。DFSInputStream也会检查block数据校验和,如果发现一个坏的block,就会先报告到namenode节点,然后DFSInputStream在其他的datanode上读该block的镜像

该设计的方向就是客户端直接连接datanode来检索数据并且namenode来负责为每一个block提供最优的datanode,namenode仅仅处理block location的请求,这些信息都加载在namenode的内存中,hdfs通过datanode集群可以承受大量客户端的并发访问。


5. 数据存储: 读文件解析

image-20180603205556077

image-20180603205203151

读文件的过程

  1. 首先调用FileSystem对象的open方法,其实是一个DistributedFileSystem的实例
  2. DistributedFileSystem通过rpc获得文件的第一批个block的locations,同一block按照重复数会返回多个locations,这些locations按照hadoop拓扑结构排序,距离客户端近的排在前面.
  3. 前两步会返回一个FSDataInputStream对象,该对象会被封装成DFSInputStream对象,DFSInputStream可以方便的管理datanode和namenode数据流。客户端调用read方法,DFSInputStream最会找出离客户端最近的datanode并连接。
  4. 数据从datanode源源不断的流向客户端。
  5. 如果第一块的数据读完了,就会关闭指向第一块的datanode连接,接着读取下一块。这些操作对客户端来说是透明的,客户端的角度看来只是读一个持续不断的流。
  6. 如果第一批block都读完了,DFSInputStream就会去namenode拿下一批blocks的location,然后继续读,如果所有的块都读完,这时就会关闭掉所有的流。

如果在读数据的时候,DFSInputStream和datanode的通讯发生异常,就会尝试正在读的block的排第二近的datanode,并且会记录哪个datanode发生错误,剩余的blocks读的时候就会直接跳过该datanode。DFSInputStream也会检查block数据校验和,如果发现一个坏的block,就会先报告到namenode节点,然后DFSInputStream在其他的datanode上读该block的镜像

该设计的方向就是客户端直接连接datanode来检索数据并且namenode来负责为每一个block提供最优的datanode,namenode仅仅处理block location的请求,这些信息都加载在namenode的内存中,hdfs通过datanode集群可以承受大量客户端的并发访问。


6.Hadoop Archives (HAR files)

Hadoop Archives (HAR files)是在0.18.0版本中引入的,它的出现就是为了缓解大量小文件消耗namenode内存的问题。HAR文件是通过在HDFS上构建一个层次化的文件系统来工作。一个HAR文件是通过hadoop的archive命令来创建,而这个命令实 际上也是运行了一个MapReduce任务来将小文件打包成HAR。对于client端来说,使用HAR文件没有任何影响。所有的原始文件都 (using har://URL)。但在HDFS端它内部的文件数减少了。

通过HAR来读取一个文件并不会比直接从HDFS中读取文件高效,而且实际上可能还会稍微低效一点,因为对每一个HAR文件的访问都需要完成两层 index文件的读取和文件本身数据的读取。并且尽管HAR文件可以被用来作为MapReduce job的input,但是并没有特殊的方法来使maps将HAR文件中打包的文件当作一个HDFS文件处理。

打包出来的 har 文件在xxx.har/part-0 中, contentz-size 跟原来的文件总大小一样

创建文件 hadoop archive -archiveName xxx.har -p /src /dest
查看内容 hadoop fs -lsr har:///dest/xxx.har 可以原封不动的显示出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 打包成 har
hadoop archive -archiveName test.har -p /user/test /

# 查看har 文件
[ap@cs1]~% hadoop fs -count /test.har/part-0
0(目录数) 1(文件数) 72(文件大小) /test.har/part-0 (文件名)

# 查看打包前文件
[ap@cs1]~% hadoop fs -count /user/test
1 2 72 /user/test

# 查看 har 文件, 把打包前的原本文件都显示出来了
[ap@cs1]~% hadoop fs -ls -R har:///test.har
-rw-r--r-- 3 ap supergroup 50 2018-06-03 04:24 har:///test.har/a.txt
-rw-r--r-- 3 ap supergroup 22 2018-06-03 04:24 har:///test.har/b.txt

注意点:

  • 存储层面:为了解决小文件过多导致的 Namenode 压力过大问题, 把很多小文件打包成一个 har 文件。
    • 使用层面: 但是实际处理的时候, 还是会还原出原本的小文件进行处理, 不会把 har 文件当成一个 HDFS 文件处理。
    • HDFS 上不支持 tar, 只支持 har打包

7.HDFS 的 HA

如果帮到你, 可以给我赞助杯咖啡☕️
0%