8、NameNode和SecondaryNameNode工作原理

Fsimage和Edits解析

相关概念

namenode被格式化之后,将在/opt/module/hadoop-2.8.3/data/tmp/dfs/name/current目录中产生如下文件

 

13274599-b56f53ec11f10779.png

namenode格式化后文件.png

  1. Fsimage文件:HDFS文件系统元数据的一个永久性的检查点,其中包含HDFS文件系统的所有目录和文件idnode的序列化信息。
  2. Edits文件:存放HDFS文件系统的所有更新操作的路径,文件系统客户端执行的所有写操作首先会被记录到edits文件中。
  3. seen_txid文件保存的是一个数字,就是最后一个edits_的数字

每次NameNode启动的时候都会将最新的fsimage文件读入内存,并合并edits里面的更新操作,保证内存中的元数据信息是最新的、同步的,可以看成NameNode启动的时候就将fsimage和edits文件进行了合并。
NameNode会把最新的fsimage后缀和seen_txid 之间的edits合并。

使用OIV查看fsimage文件

hdfs oiv -p 文件类型 -i镜像文件 -o 转换后文件输出路径
hdfs oiv -p XML -i fsimage_0000000000000000294 -o fsimage.xml
文件内容如下

<?xml version="1.0"?>
<fsimage>
    <version>
        <layoutVersion>-63</layoutVersion>
        <onDiskVersion>1</onDiskVersion>
        <oivRevision>b3fe56402d908019d99af1f1f4fc65cb1d1436a2</oivRevision>
    </version>
    <NameSection>
        <namespaceId>1560614512</namespaceId>
        <genstampV1>1000</genstampV1>
        <genstampV2>1040</genstampV2>
        <genstampV1Limit>0</genstampV1Limit>
        <lastAllocatedBlockId>1073741862</lastAllocatedBlockId>
        <txid>294</txid>
    </NameSection>
    <INodeSection>
        <lastInodeId>16407</lastInodeId>
        <numInodes>6</numInodes>
        <inode>
            <id>16385</id>
            <type>DIRECTORY</type>
            <name></name>
            <mtime>1536189784686</mtime>
            <permission>hadoop:supergroup:0755</permission>
            <nsquota>9223372036854775807</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16403</id>
            <type>DIRECTORY</type>
            <name>user</name>
            <mtime>1536189784687</mtime>
            <permission>hadoop:supergroup:0755</permission>
            <nsquota>-1</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16404</id>
            <type>DIRECTORY</type>
            <name>hadoop</name>
            <mtime>1536190852299</mtime>
            <permission>hadoop:supergroup:0755</permission>
            <nsquota>-1</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16405</id>
            <type>FILE</type>
            <name>client</name>
            <replication>3</replication>
            <mtime>1536189786438</mtime>
            <atime>1536320623173</atime>
            <preferredBlockSize>134217728</preferredBlockSize>
            <permission>hadoop:supergroup:0644</permission>
            <blocks>
                <block>
                    <id>1073741858</id>
                    <genstamp>1036</genstamp>
                    <numBytes>36667596</numBytes>
                </block>
            </blocks>
            <storagePolicyId>0</storagePolicyId>
        </inode>
    </INodeSection>
    <INodeReferenceSection></INodeReferenceSection>
    <SnapshotSection>
        <snapshotCounter>0</snapshotCounter>
        <numSnapshots>0</numSnapshots>
    </SnapshotSection>
    <INodeDirectorySection>
        <directory>
            <parent>16385</parent>
            <child>16403</child>
        </directory>
        <directory>
            <parent>16403</parent>
            <child>16404</child>
        </directory>
        <directory>
            <parent>16404</parent>
            <child>16405</child>
            <child>16406</child>
        </directory>
        <directory>
            <parent>16406</parent>
            <child>16407</child>
        </directory>
    </INodeDirectorySection>
    <FileUnderConstructionSection></FileUnderConstructionSection>
    <SecretManagerSection>
        <currentId>0</currentId>
        <tokenSequenceNumber>0</tokenSequenceNumber>
        <numDelegationKeys>0</numDelegationKeys>
        <numTokens>0</numTokens>
    </SecretManagerSection>
    <CacheManagerSection>
        <nextDirectiveId>1</nextDirectiveId>
        <numDirectives>0</numDirectives>
        <numPools>0</numPools>
    </CacheManagerSection>
</fsimage>

从上面的文件中可以看出,fsimage中并没有记录块所对应的datenode,这是因为没有必要在fsimage文件中记录,在内存中维护就可以了,datenode像namenode汇报。

oev查看edits文件

hdfs oev -p 文件类型 -i编辑日志 -o 转换后文件输出路径
hdfs oev -p XML -i edits_inprogress_0000000000000000336 -o edits_inprogress_0000000000000000336.xml
内容如下

<?xml version="1.0" encoding="UTF-8"?>
<EDITS>
  <EDITS_VERSION>-63</EDITS_VERSION>
  <RECORD>
    <OPCODE>OP_START_LOG_SEGMENT</OPCODE>
    <DATA>
      <TXID>303</TXID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_MKDIR</OPCODE>
    <DATA>
      <TXID>304</TXID>
      <LENGTH>0</LENGTH>
      <INODEID>16408</INODEID>
      <PATH>/user/hadoop/test</PATH>
      <TIMESTAMP>1536562302682</TIMESTAMP>
      <PERMISSION_STATUS>
        <USERNAME>hadoop</USERNAME>
        <GROUPNAME>supergroup</GROUPNAME>
        <MODE>493</MODE>
      </PERMISSION_STATUS>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_ADD</OPCODE>
    <DATA>
      <TXID>305</TXID>
      <LENGTH>0</LENGTH>
      <INODEID>16409</INODEID>
      <PATH>/user/hadoop/test/cpHello.txt._COPYING_</PATH>
      <REPLICATION>3</REPLICATION>
      <MTIME>1536562302831</MTIME>
      <ATIME>1536562302831</ATIME>
      <BLOCKSIZE>134217728</BLOCKSIZE>
      <CLIENT_NAME>DFSClient_NONMAPREDUCE_1326850463_1</CLIENT_NAME>
      <CLIENT_MACHINE>192.168.114.102</CLIENT_MACHINE>
      <OVERWRITE>true</OVERWRITE>
      <PERMISSION_STATUS>
        <USERNAME>hadoop</USERNAME>
        <GROUPNAME>supergroup</GROUPNAME>
        <MODE>420</MODE>
      </PERMISSION_STATUS>
      <RPC_CLIENTID>424e8401-aa20-4dd2-83ae-cedd762158f0</RPC_CLIENTID>
      <RPC_CALLID>7</RPC_CALLID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE>
    <DATA>
      <TXID>306</TXID>
      <BLOCK_ID>1073741863</BLOCK_ID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_SET_GENSTAMP_V2</OPCODE>
    <DATA>
      <TXID>307</TXID>
      <GENSTAMPV2>1041</GENSTAMPV2>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_ADD_BLOCK</OPCODE>
    <DATA>
      <TXID>308</TXID>
      <PATH>/user/hadoop/test/cpHello.txt._COPYING_</PATH>
      <BLOCK>
        <BLOCK_ID>1073741863</BLOCK_ID>
        <NUM_BYTES>0</NUM_BYTES>
        <GENSTAMP>1041</GENSTAMP>
      </BLOCK>
      <RPC_CLIENTID></RPC_CLIENTID>
      <RPC_CALLID>-2</RPC_CALLID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_CLOSE</OPCODE>
    <DATA>
      <TXID>309</TXID>
      <LENGTH>0</LENGTH>
      <INODEID>0</INODEID>
      <PATH>/user/hadoop/test/cpHello.txt._COPYING_</PATH>
      <REPLICATION>3</REPLICATION>
      <MTIME>1536562304777</MTIME>
      <ATIME>1536562302831</ATIME>
      <BLOCKSIZE>134217728</BLOCKSIZE>
      <CLIENT_NAME></CLIENT_NAME>
      <CLIENT_MACHINE></CLIENT_MACHINE>
      <OVERWRITE>false</OVERWRITE>
      <BLOCK>
        <BLOCK_ID>1073741863</BLOCK_ID>
        <NUM_BYTES>1116</NUM_BYTES>
        <GENSTAMP>1041</GENSTAMP>
      </BLOCK>
      <PERMISSION_STATUS>
        <USERNAME>hadoop</USERNAME>
        <GROUPNAME>supergroup</GROUPNAME>
        <MODE>420</MODE>
      </PERMISSION_STATUS>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_RENAME_OLD</OPCODE>
    <DATA>
      <TXID>310</TXID>
      <LENGTH>0</LENGTH>
      <SRC>/user/hadoop/test/cpHello.txt._COPYING_</SRC>
      <DST>/user/hadoop/test/cpHello.txt</DST>
      <TIMESTAMP>1536562304822</TIMESTAMP>
      <RPC_CLIENTID>424e8401-aa20-4dd2-83ae-cedd762158f0</RPC_CLIENTID>
      <RPC_CALLID>12</RPC_CALLID>
    </DATA>
  </RECORD>
</EDITS>

上述是往hdfs上传文件的一个完成过程
首先创建文件夹,添加文件(不是真正的添加,只是占个位置),分配块ID,生成时间戳,真正上传文件,关闭流,重命名文件。

NameNode和SecondaryNameNode工作机制

13274599-b41c03dba43a093d.png

namenode和secondardnamenode工作流程.png

 

该图可以分成两个阶段看

  1. 第一阶段:NameNode启动
    1). 第一次启动NameNode格式化后,创建fsimage和edits文件。如果不是第一次启动,直接加载编辑日志和镜像文件到内存。
    2). 客户端对元数据进行增删改的请求。
    3). NameNode记录操作日志,更新滚动日志。
    4). NameNode在内存中对数据进行增删改查。

  2. 第二阶段:Secondary NameNode工作
    1). Secondary NameNode询问NameNode是否需要checkpoint。直接带回NameNode是否检查结果。
    2). Secondary NameNode请求执行checkpoint。
    3). NameNode滚动正在写的edits日志。
    4). 将滚动前的编辑日志和镜像文件拷贝到Secondary NameNode。
    5). Secondary NameNode加载编辑日志和镜像文件到内存,并合并。
    6). 生成新的镜像文件fsimage.ckpt。
    7). 拷贝fsimage.chkpoint到NameNode。
    8). NameNode将fsimage.chkpoint重新命名成fsimage。

checkpoint时间设置

  1. 通常情况下,SecondaryNameNode每隔一小时执行一次。如果修改在hdfs-site中
    在hdfs-default.xml中值如下
<property>
  <name>dfs.namenode.checkpoint.period</name>
  <value>3600</value>
  <description>The number of seconds between two periodic checkpoints.
  </description>
</property>
  1. 一分钟检查一次操作次数,当操作次数达到1百万时,SecondaryNameNode执行一次。
    在hdfs-default.xml配置如下
<property>
  <name>dfs.namenode.checkpoint.txns</name>
  <value>1000000</value>
  <description>The Secondary NameNode or CheckpointNode will create a checkpoint
  of the namespace every 'dfs.namenode.checkpoint.txns' transactions, regardless
  of whether 'dfs.namenode.checkpoint.period' has expired.
  </description>
</property>

<property>
  <name>dfs.namenode.checkpoint.check.period</name>
  <value>60</value>
  <description>The SecondaryNameNode and CheckpointNode will poll the NameNode
  every 'dfs.namenode.checkpoint.check.period' seconds to query the number
  of uncheckpointed transactions.
  </description>
</property>

NameNode故障处理

方法一

将SecondaryNameNode中数据拷贝到NameNode存储数据的目录

  1. kill -9 NameNode对应的进程
  2. 删除NameNode存储数据
    rm -rf /opt/module/hadoop-2.8.3/data/tmp/dfs/name/
  3. 拷贝SecondaryNameNode中数据到原NameNode存储数据目录
    scp -r hadoop@hadoop-102:/opt/module/hadoop-2.8.3/data/tmp/dfs/namesecondary/* ./name
  4. 重新启动NameNode

方法二

使用-importCheckpoint选项启动NameNode守护进程,从而将SecondaryNameNode中数据拷贝到NameNode目录中

  1. 修改hdfs-site.xml
<property>
 <name>dfs.namenode.checkpoint.period</name>
 <value>120</value>
</property>

<property>
 <name>dfs.namenode.name.dir</name>
 <value>/opt/module/hadoop-2.7.2/data/tmp/dfs/name</value>
</property>
  1. kill -9 namenode进程
  2. 删除NameNode存储的数据
    rm -rf /opt/module/hadoop-2.8.3/data/tmp/dfs/name/
  3. 如果SecondaryNameNode不和NameNode在一个主机节点上,需要将SecondaryNameNode存储数据的目录拷贝到NameNode存储数据的平级目录,并删除in_use.lock文件
    在dfs目录下执行
    scp -r hadoop@hadoop-102:/opt/module/hadoop-2.8.3/data/tmp/dfs/namesecondary ./
    进入namesecondary目录,删除in_use.lock文件
    cd namesecondary
    rm -rf in_use.lock
  4. 导入检查点数据(等待一会ctrl+c结束掉)
    hdfs namenode -importCheckpoint
  5. 启动namenode
    hadoop-daemon.sh start namenode

集群安全模式

概述

NameNode启动时,首先将映像文件(fsimage)载入内存,并执行编辑日志(edits)中的各项操作。一旦在内存中成功建立文件系统元数据的映像,则创建一个新的fsimage文件和一个空的编辑日志。此时,NameNode开始监听DataNode请求。但是此刻,NameNode运行在安全模式,即NameNode的文件系统对于客户端来说是只读的。
系统中的数据块的位置并不是由NameNode维护的,而是以块列表的形式存储在DataNode中。在系统的正常操作期间,NameNode会在内存中保留所有块位置的映射信息。在安全模式下,各个DataNode会向NameNode发送最新的块列表信息,NameNode了解到足够多的块位置信息之后,即可高效运行文件系统。
如果满足“最小副本条件”,NameNode会在30秒钟之后就退出安全模式。所谓的最小副本条件指的是在整个文件系统中99.9%的块满足最小副本级别(默认值:dfs.replication.min=1)。在启动一个刚刚格式化的HDFS集群时,因为系统中还没有任何块,所以NameNode不会进入安全模式。

基本语法

集群处于安全模式,不能执行重要操作(写操作)。集群启动完成后,自动退出安全模式。

  1. bin/hdfs dfsadmin -safemode get (功能描述:查看安全模式状态)
  2. bin/hdfs dfsadmin -safemode enter (功能描述:进入安全模式状态)
  3. bin/hdfs dfsadmin -safemode leave (功能描述:离开安全模式状态)
  4. bin/hdfs dfsadmin -safemode wait (功能描述:等待安全模式状态,监控安全模式)

模拟等待安全模式

  1. 先进入安全模式
    hdfs dfsadmin -safemode enter
  2. 编写并执行下面脚本
    vim testWait.sh
    输入如下内容
#!/bin/bash
hdfs dfsadmin -safemode wait
hdfs dfs -put test.txt /

给执行权限
chmod +x testWait.sh
执行
./testWait.sh

  1. 新打开一个窗口,离开安全模式
    hdfs dfsadmin -safemode leave
    观察结果,是否上传成功

NameNode多目录配置

NameNode的本地目录可以配置成多个,且每个目录存放内容相同,增加了可靠性
具体步骤如下

  1. 在hdfs-site.xml文件中增加如下内容
<property>
 <name>dfs.namenode.name.dir</name>
<value>file:///${hadoop.tmp.dir}/dfs/name1,file:///${hadoop.tmp.dir}/dfs/name2</value>
</property>
  1. 停止集群
    stop-dfs.sh
  2. 删除date和logs中所有数据
    rm -rf /data /logs
  3. 格式化集群并启动
    hdfs namenode -format
    start-dfs.sh
  4. 查看结果

     

    13274599-7e05d5e7c2b3af45.png

    namenode多级目录.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值