大数据学习之路(7):NameNode和SecondNameNode是怎样工作的?

575 阅读5分钟

一、提出问题

在前面的学习中,我们知道namenode 是负责对整改HDFS中数据的元数据进行管理的,而Secnodnamenode是辅助namenode的作用,定期合并fsimage和edits文件。namenode是负责管理的数据块的映射信息,那么它本身也是要存储数据的,那么它的数据存储在哪呢?

关于磁盘和内存的区别是这样的:

1、内存是保存cpu运算的中间数据和计算结果

2、磁盘是硬盘,处理数据速度比内存慢很多,但是空间大很多。

问题1 :namenode的数据存储在哪?

如果这样存储,那么因为经常要对数据进行随机访问,还有相应客户端请求,效率过低,因此,元数据需要存放在内存中;但是如果内存中的数据丢失,那么集群就无法正常工作了。因此,nameNode采用的策略就是都存,利用Fsimage+edits的方案来解决这个问题。fsimage是某个时刻对内存中元数据的一个快照。edits记录hdfs对数据的改操作(类似redis的aof),只做追加操作,效率高。

问题2:edits文件是不是一直追加,那么会无限大呢?

不是的,edits记录的改操作,隔一端时间secondnamenode就会过来合并fsimage和edits文件,然和生成新的fsimag文件,旧的edits文件会被保留,然后把后续的改操作记录到新的edits文件中。

二、工作机制

clipboard.png

该图的分为两个阶段:namenode工作和secondarynamenode工作。

1)namenode启动:

1、第一次启动namenode格式化后,会创建FSimage和edits文件,如果不是第一次启动,直接加载edits文件和镜像文件到内存。

2、客户端发来的增删改请求被时刻记录到操作日志中

3、记录完成后,开始对内存中的元数据进行增删改。

2)secondaryNameNode工作过程

1、secondarynamenode去namenode询问是否需要checkpoint,返回询问结果。

2、Secondary namenode 请求执行CheckPoint

3、NameNode滚动读取当前的edits文件和fsimage,读取到secondarynamenode中

4、secondary NameNode 加载编辑日志和镜像文件到内存,并合并。

5、生成新的FSimage.chkpoint文件,并拷贝到namenode文件中,然后重命名为fsimage。

【注意】:checkpoint的触发需要满足两个条件之一即可:

1、定时时间到了

2、edits文件满了。

三、查看编辑日志和镜像文件

3.1 oiv查看Fsimage文件

1)查看oiv(查看fsimage文件)和oev(查看edit文件)命令,基本语法:

hdfs oiv -p 文件类型  -i 镜像文件   -o 转换后文件输出路径

2)实例操作:

oot@hadoop100 current]# hdfs oiv -p XML -i fsimage_0000000000000000356 -o /opt/module/hadoop-3.1.3/fsimage.xml
2020-09-02 14:28:57,531 INFO offlineImageViewer.FSImageHandler: Loading 4 strings
[root@hadoop100 current]# cd /opt/module
[root@hadoop100 module]# cd hadoop-3.1.3/
[root@hadoop100 hadoop-3.1.3]# ls
bin  data  etc  fsimage.xml  lib  libexec  LICENSE.txt  logs  NOTICE.txt  README.txt  sbin  share  wcinput
[root@hadoop100 hadoop-3.1.3]# cat fsimage.xml 

3)作用:记录元数据

问题1:HDFS的目录结构是怎么维护的?

在fsimage中通过< inode >进行维护,目录与目录的上下级关系通过< INodeDirectorySection >维护。

<INodeDirectorySection>
    <directory>
        <parent>16385</parent>
            <child>16473</child>
            <child>16472</child>
            <child>16390</child>
            <child>16386</child>
    </directory>
    <directory>
        <parent>16386</parent>
        <child>16387</child>
    </directory>

问题2:fsimage并不维护datanode节点,那么namenode如何与datanode节点交互?

每隔文件的块在哪些datanode节点上,这是由datanode主动上报给namenode的,因此在namenode的内存中是有记录的,但是在磁盘的fsimage中是没有记录的。

3.2 oev查看edits文件

1、基本语法:

hdfs oev -p 文件类型 -i编辑日志 -o 转换后文件输出路径

2、案例实操

[root@hadoop100 current]# hdfs oev -p XML -i edits_0000000000000000326-0000000000000000327 -o /opt/module/hadoop-3.1.3/edits.xml
[root@hadoop100 current]# cat /opt/module/hadoop-3.1.3/edits.xml 

3、下载后查看,作用就是记录操作信息,从头开始到end结束

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<EDITS>
  <EDITS_VERSION>-64</EDITS_VERSION>
  <RECORD>
    <OPCODE>OP_START_LOG_SEGMENT</OPCODE>
    <DATA>
      <TXID>326</TXID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_END_LOG_SEGMENT</OPCODE>
    <DATA>
      <TXID>327</TXID>
    </DATA>
  </RECORD>
</EDITS>

四、checkpoint时间设置

1、在hdfs-default.xml中配置,默认1小时

<property>
  <name>dfs.namenode.checkpoint.period</name>
  <value>3600</value>
</property>

2、在hdfs-default.xml,一分钟检测一次操作次数,当操作次数达到一百万时,secondarynamenode执行一次

<property>
  <name>dfs.namenode.checkpoint.txns</name>
  <value>1000000</value>
<description>操作动作次数</description>
</property>
 
<property>
  <name>dfs.namenode.checkpoint.check.period</name>
  <value>60</value>
<description> 1分钟检查一次操作次数</description>
</property >

五、集群安全模式

5.1 为什么会有集群安全模式?

在分布式文件系统启动的时候就会有安全模式。当分布式文件系统处于安全模式的情况下,文件系统的内容不允许修改也不允许删除,直到安全模式结束。安全模式主要是为了系统启动的时候检查各个DataNode上数据块的有效性,同时根据策略必要的复制或删除部分数据块。运行期间通过命令也能进入安全模式,系统在安全模式下,会校验数据块的完整性。

5.2 集群启动过程中的安全模式

1、namenode启动

NameNode 启动时,首先将镜像文件载入内存,并执行编辑日志中的各项操作。一旦在内存中成功建立文件系统元数据的映像,则创建新的fsimage和edits日志,此时NameNode开始监听DataNode请求。这个过程期间,NameNode开始监听DataNode的上报请求,期间namenode处于安全模式,对于客户端来说不可只读。

2、DataNode启动

系统中的数据的位置并不是由NameNode维护的,而是以块的列表存储在DataNode,在安全模式下,DdataNode会向namenode上报节点的块列表信息。Namenode大哥在了解到足够多的块位置后就可以高效运行文件系统。

3、安全模式退出判断

如果满足“最小副本条件”,namenode 就会在30秒之后退出安全模式。所谓最小副本条件指的是整个文件系统中的99.9%的块满足最小副本级别(默认值:dfs.replication.min=1)。在启动一个刚刚格式化的HDFS集群时,因为系统中还没有任何块,所以Namenode不会进入安全模式。加入一个块有三个副本,找到一个副本就可以退出安全模式了。