NN 与 2NN 工作机制
思考:NameNode 中的元数据是存储在哪里的?
- 假设存储在 NameNode 节点的硬盘中,因为经常需要随机访问和响应客户请求,必然效率太低,所以是存储在内存中的
- 但是,如果存储在内存中,一旦断电,元数据丢失,整个集群便无法工作,因此会在硬盘中产生备份元数据的 Fsimage
- 但是这样又会有新的问题出现,当内存中的元数据更新时,需要同时更新 Fsimage,否则会发生一致性的问题;
- 但要更新的话,又会导致效率过低
- 因此,又引入了 Edits 文件,用来记录客户端更新元数据的每一步操作(只进行追加操作,效率很高),每当元数据有更新时,就把更新的操作记录到 Edits 中,Edits 也存放在硬盘中
- 这样,一旦 NameNode 节点断电,可以通过 Fsimage 和 Edits 合并,生成最新的元数据
- 如果长时间一直添加操作数据到 Edits,会导致文件数据过大,效率降低,而一旦断电会造成恢复时间过长,因此需要对 Fsimage 与 Edits 定期合并
- 而如果这些操作都交给 NameNode 节点完成,则又会造成效率降低
- 因此引入了一个辅助 NameNode 的新的节点 SecondaryNameNode,专门用于 Fsimage 和 Edits 的合并
NN 与 2NN 工作机制
-
第一阶段:NameNode 启动
- 第一次启动 NameNode 格式化之后,创建 Fsimage,Edits 文件实在启动 NameNode 时生成的;如果不是第一次创建,会直接加载 Edits 和 Fsimage 到内存,在 HDFS 启动时会有一次 Edits 和 Fsimage 的合并操作,此时 NameNode 内存就持有最新的元数据信息
- 客户端对元数据发送增删改(不记录查询操作,因为查询不改变元数据)的请求
- NameNode 会首先记录操作日志,,更新滚动日志
- NameNode 在内存中对元数据进行增删改操作
-
第二阶段: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 解析
- 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 文件里的更新操作,保证内存中元数据的内容是最新的,同步的
- oiv 查看 Fsimage 文件
- 基本语法:
hdfs oiv -p 文件类型 -i 镜像文件 -o 转换后文件输出路径
- 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 文件中的操作丢失
集群安全模式
什么是安全模式
- NameNode 启动时,首先将 Fsimage 载入内存,再执行 Edits 中的各项操作,一旦在内存中成功建立文件系统元数据的映像,则创建一个新的 Fsimage 文件和一个空的编辑日志,然后开始监听 DataNode 请求,在这个过程期间,NameNode 一直运行在安全模式下,也就是 NameNode 对于客户端是只读的
- DataNode 启动时,系统中的数据块的位置并不是由 NameNode 维护的,而是由块列表的形式存储在 DataNode 中,在系统的正常操作期间,NameNode 会在内存中保留所有块的映射信息。在安全模式下,各个 DataNode 会向 NameNode 发送最新的块列表信息,NameNode 了解足够多的块列表信息后,即可高效运行文件系统
- 安全模式退出判断:如果满足 最小副本条件,NameNode 会在 30 秒之后退出安全模式。最小副本条件是指在整个文件系统中 99.9% 的块满足最小副本级别(默认为 1),即 99.9% 的块至少有一个副本存在。
- 在启动一个刚刚格式化的 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>