Hadoop--HDFS之NameNode

  之前就打算写一下Hadoop系列博客的,由于写别的东西去了,一直也没抽空出来,上篇Hadoop–HDFS架构和Shell对HDFS的一个简单概述,还是两三个月前的事情了。做了这么久的Hadoop了,在这里算是自我总结一下吧,本篇博客主要讲解一下Hadoop HDFS的NameNode

  • 重点掌握
  1. NameNode 的作用;
  2. NameNode 元数据的底层结构;
  3. SecondaryNameNode 的作用以及工作流程,以及为什么需要SecondaryNameNode。

NameNode简介

  • 管理节点
  1. 核心元数据,包括文件(夹)的目录结构和属性信息,还有文件与其所在位置的映射信息。
  2. 一切读写的操作必须经过NameNode,但是传输数据本身不经过NameNode(好好理解这句话)。

NameNode

  • NameNode 包括以下文件:(保存在linux的文件系统中

    1. fsimage:元数据镜像文件,存储某一时段NameNode内存元数据信息即保存了最新的元数据checkpoint。
    2. edits:操作日志文件。
    3. fstime:保存最近一次checkpoint的时间
      NameNode元数据信息
  • NameNode 元数据

  1. NameNode 为了保证交互速度,会在内存中保存这些元数据信息,但同时也会将这些信息保存到硬盘上进行持久化存储;
  2. fsimage文件是内存中的元数据在硬盘上的checkpoint,它是一种序列化的格式,不能直接修改。
  3. Hadoop在重启时就是通过fsimage+edits来状态恢复,fsimage相当于一个checkpoint,首先将最新的checkpoint的元数据信息从fsimage中加载到内存,然后逐一执行edits修改日志文件中的操作以恢复到重启之前的最终状态。
  4. Hadoop的持久化过程是将上一次checkpoint以后最近一段时间的操作保存到修改日志文件edits中。

SecondaryNameNode

上面出现的一个问题是:edits会随着时间增加而越来越大,导致以后重启时需要花费很长的时间来按照edits中记录的操作进行恢复,于是Hadoop就专门弄了一个进程SecondaryNameNode

SecondaryNameNode工作流程

  • SecondaryNameNode节点 的主要功能是周期性将元数据节点的命名空间镜像文件(fsimage)和修改日志(edits)进行合并,以防edits日志文件过大。下面来看一看合并的流程
  1. SecondaryNameNode节点 需要合并时,首先通知NameNode节点生成新的日志文件,以后的日志都写到新的日志文件中。
  2. SecondaryNameNode节点 用http getNameNode节点获得fsimage文件旧的edits日志文件
  3. SecondaryNameNode节点 将 fsimage 文件加载到内存中,并执行日志文件中的操作,然后生成新的fsimage文件
  4. SecondaryNameNode 节点将新的fsimage文件用http post传回NameNode节点上。
  5. NameNode 节点可以将旧的fsimage文件及旧的日志文件,换为新的fsimage文件和新的日志文件(第一步生成的),然后更新fstime文件,写入此次checkpoint的时间。
  6. 这样NameNode 节点中的fsimage文件保存了最新的checkpoint的元数据信息,日志文件也重新开始,不会变的很大了
  • 注意
  1. 这种机制有个问题:因edits存放在NameNode中,当NameNode挂掉,edits也会丢失,导致利用Secondary NameNode恢复Namenode时,会有部分数据丢失
  2. HDFS设置了两种机制进行条件合并(hdfs-site.xml):
    第一种:当时间间隔大于或者等于dfs.namenode.checkpoint.period配置的时间是做合并(默认一小时)
    第二种:当最后一次往journalNode写入的TxId(这个可以在namenode日志或者50070界面可以看到)和最近一次做Checkpoint的TxId的差值大于或者等于dfs.namenode.checkpoint.txns配置的数量(默认1000000)时做一次合并
    HDFS设置了两种条件合并

底层文件查看

  • 保存的NameNode元数据信息,在HADOOP_HOME/etc/hadoop/hdfs-site.xml 的 dfs.namenode.name.dir配置,如下图:

    1
    2
    3
    4
    5
    6
    <property>
    <name>dfs.namenode.name.dir</name>
    <value>file:///usr/local/hadoop_repo/name</value>
    </property>
    <!-- 我切换到/usr/local/hadoop_repo/name/current就能查看元数据信息了 -->
    <!-- value可以配置多个,用逗号隔开,这样也算是一种备份方式吧-->
  • 第一步:开启服务,查看某个fsimage文件,开启服务命令:bin/hdfs oiv -i fsimage文件,不然提示:ls: Connection refused

  • 第二步:查看内容,命令:bin/hdfs dfs -ls -R webhdfs://127.0.0.1:5978/。我的hdfs里面有hbase和hive的数据,所以元数据也比较多,这里来个部分截图(这个看上去就和web以及hdfs dfs -ls查看的结果差不多):
    NameNode元数据信息

  • 第三步:导出结果,这是导出fsimage文件内容,命令:hdfs oiv -p XML -i /usr/local/hadoop_repo/name/current/fsimage_0000000000000003292 -o fsimage.xml
    导出的fsimage.xml文件

  1. xml节点在上面大家也能看见,主要看inode节点,下面就是文件以及文件夹的基本信息;
  2. idnametypemtimepermissionnsquotadsquota
  3. 如果是文件还有更多属性,比如atimeperferredBlockSizeblocks
  4. fsimage 保存有如下信息:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    一、加载Img头信息,如下:
    1、imgVersion(int):当前image的版本信息
    2、namespaceID(int):用来确保别的HDFS instance中的datanode不会误连上当前NN。
    3、numFiles(long):整个文件系统中包含有多少文件和目录
    4、genStamp(long):生成该image时的时间戳信息。
    二 、如果加载目录,包含以下信息:
    1、path(String):该目录的路径,如”/user/build/build-index”
    2、replications(short):副本数(目录虽然没有副本,但这里记录的目录副本数也为3
    3、mtime(long):该目录的修改时间的时间戳信息
    4、atime(long):该目录的访问时间的时间戳信息
    5、blocksize(long):目录的blocksize都为0
    6、numBlocks(int):文件块数,-1表示目录,大于1时,表示该文件对应有多个block信息
    7、nsQuota(long):namespace Quota值,若没加Quota限制则为-1
    8、dsQuota(long):disk Quota值,若没加限制则也为-1
    9、username(String):该目录的所属用户名
    10、group(String):该目录的所属组
    11、permission(short):该目录的permission信息,如644等,有一个short来记录。
    三、如果加载文件,则还会额外包含如下信息:
    1、blockid(long):属于该文件的block的blockid,
    2、numBytes(long):该block的大小
    3、genStamp(long):该block的时间戳

在namenode启动时,就需要对fsimage按照如下格式进行顺序的加载,以将fsimage中记录的HDFS元数据信息加载到内存中。

  • 第三步:继续导出,这是导出edits文件内容,命令:bin/hdfs oev -i /usr/local/hadoop_repo/name/current/edits_0000000000000003295-0000000000000003296 -o edits.xml
    导出的edits.xml文件
  1. 最大的节点是EDITS,下面就是版本信息EDITS_VERSION和很多的RECORD节点;
  2. 每个edits文件第一个RECORDRECORD都是以OP_START_LOG_SEGMENT开头;
  3. RECORD类型有很多,比如 OP_ADD、OP_TIMES、OP_DELETE、OP_ALLOCATE_BLOCK_ID、OP_ADD_BLOCK、OP_RENAME_OLD、OP_CLOSE等
  • 总结
  1. 从上面我们就可以看出,edits文件的信息特别详细,记录了每一步操作,所以文件大小增长也特别的快;
  2. fsimage文件内容就是edits文件详细步骤的浓缩。

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器