浅谈HDFS二之NameNode与SecondaryNameNode

31次阅读

共计 4271 个字符,预计需要花费 11 分钟才能阅读完成。

NN 与 2NN 工作机制

思考:NameNode 中的元数据是存储在哪里的?

  • 假设存储在 NameNode 节点的硬盘中,因为经常需要随机访问和响应客户请求,必然效率太低,所以是存储在内存中的
  • 但是,如果存储在内存中,一旦断电,元数据丢失,整个集群便无法工作,因此会在硬盘中产生备份元数据的 Fsimage
  • 但是这样又会有新的问题出现,当内存中的元数据更新时,需要同时更新 Fsimage,否则会发生一致性的问题;
  • 但要更新的话,又会导致效率过低
  • 因此,又引入了 Edits 文件,用来记录客户端更新元数据的每一步操作(只进行追加操作,效率很高),每当元数据有更新时,就把更新的操作记录到 Edits 中,Edits 也存放在硬盘中
  • 这样,一旦 NameNode 节点断电,可以通过 Fsimage 和 Edits 合并,生成最新的元数据
  • 如果长时间一直添加操作数据到 Edits,会导致文件数据过大,效率降低,而一旦断电会造成恢复时间过长,因此需要对 Fsimage 与 Edits 定期合并
  • 而如果这些操作都交给 NameNode 节点完成,则又会造成效率降低
  • 因此引入了一个辅助 NameNode 的新的节点 SecondaryNameNode,专门用于 Fsimage 和 Edits 的合并

NN 与 2NN 工作机制

  1. 第一阶段:NameNode 启动

    • 第一次启动 NameNode 格式化之后,创建 Fsimage,Edits 文件实在启动 NameNode 时生成的;如果不是第一次创建,会直接加载 Edits 和 Fsimage 到内存,在 HDFS 启动时会有一次 Edits 和 Fsimage 的合并操作,此时 NameNode 内存就持有最新的元数据信息
    • 客户端对元数据发送增删改(不记录查询操作,因为查询不改变元数据)的请求
    • NameNode 会首先记录操作日志,,更新滚动日志
    • NameNode 在内存中对元数据进行增删改操作
  2. 第二阶段:SecondaryNameNode 工作

    • SecondaryNameNode 定期询问 NameNode 是否需要 CheckPoint,直接带回 NameNode 是否检查的结果
    • 当 CheckPoint 定时时间到了或者 Edits 中的数据满了,SecondaryNameNode 请求执行 CheckPoint
    • NameNode 滚动正在写的 Edits,并生成新的空的 edits.inprogress_002,滚动的目的是给 Edits 打个标记,以后所有更新操作都写入 edits.inprogress_002 中
    • 原来的 Fsimage 和 Edits 文件会拷贝到 SecondaryNameNode 节点,SecondaryNameNode 会将它们加载到内存合并,生成新的镜像文件 fsimage.chkpoint
    • 然后将新的镜像文件 fsimage.chkpoint 拷贝给 NameNode,重命名为 Fsimage,替换原来的镜像文件
    • 因此,最后当 NameNode 启动时,只需要加载之前未合并的 Edits 和 Fsimage 即可更新到最新的元数据信息

Fsimage 与 Edits 解析

  1. NameNode 在格式化之后,将在 /opt/module/hadoop-2.7.2/data/tmp/dfs/name/current/ 目录下产生如下文件:
-rw-rw-r--. 1 kocdaniel kocdaniel     945 9 月  25 20:27 fsimage_0000000000000000000
-rw-rw-r--. 1 kocdaniel kocdaniel      62 9 月  25 20:27 fsimage_0000000000000000000.md5
-rw-rw-r--. 1 kocdaniel kocdaniel       4 9 月  25 20:27 seen_txid
-rw-rw-r--. 1 kocdaniel kocdaniel     205 9 月  25 10:25 VERSION
  • fsimage:HDFS 文件系统元数据的一个永久性的检查点,其中包含 HDFS 文件系统的所有目录和文件 inode 的序列化信息
  • Edits(启动 NameNode 时生成):存放 HDFS 文件系统所有更新操作,文件系统客户端执行的写操作首先会被记录到 Edits 文件中
  • seen_txis:保存的时一个数字,是最新的 edits_后的数字
  • 每次 NameNode 启动的时候都会将 Fsimage 文件读入内存,加载 Edits 文件里的更新操作,保证内存中元数据的内容是最新的,同步的
  1. oiv 查看 Fsimage 文件
  • 基本语法:hdfs oiv -p 文件类型 -i 镜像文件 -o 转换后文件输出路径
  1. oev 查看 Edits 文件
  • 基本语法:hdfs oev -p 文件类型 -i 编辑日志 -o 转换后文件输出路径

Checkpoint 时间设置

默认情况下,SecondaryNameNode 每隔一个小时或者当操作次数超过 100 万次时执行一次,但是操作次数的统计 SecondaryNameNode 自己做不到,需要借助 NameNode,所以还有一个参数设置是 namenode 每隔一分钟检查一次操作次数,当操作次数达到 100 万时 SecondaryNameNode 开始执行 Checkpoint,三个参数的设置都在 hdfs_site.xml 配置文件中,配置如下:

# SecondaryNameNode 每隔一个小时执行一次
<property>
  <name>dfs.namenode.checkpoint.period</name>
  <value>3600</value>
</property>

# SecondaryNameNode 当操作次数超过 100 万次时执行一次
<property>
  <name>dfs.namenode.checkpoint.txns</name>
  <value>1000000</value>
<description> 操作动作次数 </description>
</property>

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

NameNode 故障处理

NameNode 故障后有两种处理方式:

NameNode 故障处理方式一:直接将 SecondaryNameNode 目录下的数据直接拷贝到 NameNode 目录下,然后重新启动 NameNode

NameNode 故障处理方式二:使用 -importCheckpoint 选项启动 NameNode 守护进程,从而将 SecondaryNameNode 目录下的数据直接拷贝到 NameNode 目录下

  • 首先需要在 hdfs_site.xml 文件中添加如下配置
# SecondaryNameNode 每隔两分钟执行一次
<property>
  <name>dfs.namenode.checkpoint.period</name>
  <value>120</value>
</property>

# 指定 namenode 生成的文件目录
<property>
  <name>dfs.namenode.name.dir</name>
  <value>/opt/module/hadoop-2.7.2/data/tmp/dfs/name</value>
</property>
  • 然后,如果 SecondaryNameNode 和 NameNode 不在一个主机节点上,需要将 SecondaryNameNode 存储数据的目录拷贝到 NameNode 存储数据的平级目录,并删除 in_use.lock 文件
  • 最后导入检查点数据(等待一会儿 ctrl + c 结束掉)
[kocdaniel@hadoop102 hadoop-2.7.2]$ bin/hdfs namenode -importCheckpoint
  • 注意:执行完该命令后,观察 namenode 已经启动(临时启动),而且每 2 分钟检查一次,如果确定已经恢复了数据,我们 ctrl+ c 停止,然后自己手动起 namenode
  • ctrl+ c 之后,重启 namenode 即可恢复数据,但是并不能完全恢复,可能会将最新的 Edits 文件中的操作丢失

集群安全模式

什么是安全模式

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

基本语法

  • 集群处于安全模式时,不能执行任何重要操作(写操作)。
  • 集群启动完成后,自动退出安全模式
(1)bin/hdfs dfsadmin -safemode get(功能描述:查看安全模式状态)(2)bin/hdfs dfsadmin -safemode enter(功能描述:进入安全模式状态)(3)bin/hdfs dfsadmin -safemode leave(功能描述:离开安全模式状态)# wait 是指,如果在脚本中写入此命令,则脚本将等待安全模式退出后自动执行(4)bin/hdfs dfsadmin -safemode wait(功能描述:等待安全模式状态)

NameNode 多目录配置

  • NameNode 的本地目录可以配置成多个,且每个目录存放 内容相同 ,增加了可靠性,提高 高可用性
  • 具体需要在 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>

正文完
 0