目录
4. SecondayNamenode的⼯作机制(检查点机制)
1. 开机启动Namenode过程
1.1. ⾮第⼀次启动集群的启动流程
我们应该知道,在启动namenode 之前,内存⾥是没有任何有关于元数据的信息的。那么启动集群的过程是怎样的呢?下⾯来叙述⼀下:第⼀步: Namenode 在启动时,会先加载 name ⽬录下最近的 fsimage ⽂件 . 将 fsimage ⾥保存的元数据加载到内存当中,这样内存⾥就有了之前检查点⾥存储的所 有元数据。但是还少了从最近⼀次检查时间点到关闭系统时的部分数据,也就是edit ⽇ 志⽂件⾥存储的数据。 第⼆步: 加载剩下的 edit ⽇志⽂件 将从最近⼀次检查点到⽬前为⽌的所有的⽇志⽂件加载到内存⾥,重演⼀次客户端的操 作,这样,内存⾥就是最新的⽂件系统的所有元数据了。 第三步: 进⾏检查点设置(满⾜条件会进⾏) namenode 会终⽌之前正在使⽤的 edit ⽂件 , 创建⼀个空的 edit ⽇志⽂件。然后将所有 的未合并过的edit ⽇志⽂件和 fsimage ⽂件进⾏合并,产⽣⼀个新的 fsimage. 第四步: 处于安全模式下,等待 datanode 节点的⼼跳反馈,当收到 99.9% 的块的⾄少⼀个副本 后,退出安全模式,开始转为正常状态。
不是第⼀次启动,直接加载编辑⽇志和edits⽂件的情况展示:
执⾏流程
1.2. 第⼀次启动集群的启动流程
第⼀次启动 namenode 格式化后的情况展示 : 注意:格式化集群后,第⼀次启动集群的特点,参考下图
2. 安全模式介绍
Namenode启动时,⾸先要加载 fsimage ⽂件到内存,并逐条执⾏ editlog ⽂件⾥的事 务操作,在这个期间⼀但在内存中成功建⽴⽂件系统元数据的映像,就会新创建⼀个 fsimage⽂件 ( 该操作不需要 SecondaryNamenode) 和⼀个空的 editlog ⽂件。在这个 过程中,namenode 是运⾏在安全模式下的, Namenode 的⽂件系统对于客户端来说是只 读的,⽂件修改操作如写,删除,重命名等均会失败。 系统中的数据块的位置并不是由namenode 维护的,⽽是以块列表的形式存储在 datanode中。在系统的正常操作期间, namenode 会在内存中保留所有块位置的映射信 息。在安全模式下,各个datanode 会向 namenode 发送最新的块列表信息,如果满⾜ “最⼩副本条件 ” , namenode 会在 30 秒钟之后就退出安全模式 , 开始⾼效运⾏⽂件系统 . 所谓的最⼩副本条件指的是在整个⽂件系统中99.9% 的块满⾜最⼩副本级别(默认值: dfs.replication.min=1)。 PS:启动⼀个刚刚格式化完的集群时, HDFS 还没有任何操作呢,因此 Namenode 不会进⼊安全模式。 1 系统离开安全模式,需要满⾜哪些条件? 当 namenode 收到来⾃ datanode 的状态报告后, namenode 根据配置确定1) 可⽤的 block 占总数的⽐例 2) 可⽤的数据节点数量符合要求之后,离开安全模式。 3) 1 、 2 两个条件满⾜后维持的时间达到配置的要求。 注意:如果有必要,也可以通过命令强制离开安全模式 。2 与安全模式相关的主要配置在hdfs-site.xml⽂件中,主要有下⾯⼏个属性
1) dfs.namenode.replication.min: 最⼩的⽂件 block 副本数量,默认为 1. 2) dfs.namenode.safemode.threshold-pct: 副本数达到最⼩要求的 block 占系统总 block 数的百分⽐,当实际⽐例超过该配置后, 才能离开安全模式(但是还需要其他 条件也满⾜)。默认为0.999f ,也就是说符合 最⼩副本数要求的block 占⽐超过 99.9% 时,并且其他条件也满⾜才能离开 安全模 式。如果为⼩于等于0 ,则不会等待任何副本达到要求即可离开。如果⼤于 1 ,则永 远处于安全模式。 3) dfs.namenode.safemode.min.datanodes: 离开安全模式的最⼩可⽤( alive ) datanode 数量要求,默认为 0. 也就是即使所有datanode都不可⽤,仍然可以离开安全 模式。 4) dfs.namenode.safemode.extension: 当集群可⽤ block ⽐例,可⽤ datanode 都达到要求之后,如果在 extension 配置的时 间段之后依然能满⾜要求,此时集群 才离开安全模式。单位为毫秒,默认为1. 也就是 当满⾜条件并且能够维持1 毫秒之后,离开安全模式。 这个配置主要是对集群的稳定 程度做进⼀步的确认。避免达到要求后⻢上⼜不符合安全标准。
3 相关命令
1 查看 namenode 是否处于安全模式[root@hadoop01 current]# hdfs dfsadmin -safemode get Safe mode is ON2 管理员可以随时让 Namenode 进⼊或离开安全模式,这项功能在维护和升级集群 时⾮常关键
[root@hadoop01 current]# hdfs dfsadmin -safemode enter Safe mode is ON [root@hadoop01 current]# hdfs dfsadmin -safemode leave Safe mode is OFF
3 将下⾯的属性的值设置为⼤于1,将永远不会离开安全模式
<property>
<name>dfs.namenode.safemode.threshold-pct</name>
<value>0.999f</value>
</property>
4
有时,在安全模式下,⽤户想要执⾏某条命令,特别是在脚本中,此时可以先让 安全模式进⼊等待状态
[root@hadoop01 current]# hdfs dfsadmin -safemode wait # command to read or write a file
3. DataNode与NameNode通信(⼼跳机制)
1. hdfs 是 qianfeng01/slave 结构, qianfeng01 包括 namenode 和 resourcemanager, slave 包括 datanode 和 nodemanager 2. qianfeng01 启动时会开启⼀个 IPC 服务,等待 slave 连接 3. slave 启动后,会主动连接 IPC 服务,并且每隔 3 秒链接⼀次,这个时间是可以调整 的,设置heartbeat ,这个每隔⼀段时间连接⼀次的机制,称为⼼跳机制。 Slave 通过 ⼼跳给qianfeng01 汇报⾃⼰信息, qianfeng01 通过⼼跳下达命令。 4. Namenode 通过⼼跳得知 datanode 状态。 Resourcemanager 通过⼼跳得知 nodemanager状态 5. 当 qianfeng01 ⻓时间没有收到 slave 信息时,就认为 slave 挂掉了。
注意:超⻓时间计算结果:默认为10分钟30秒
属性: dfs.namenode.heartbeat.recheck-interval 的默认值为 5 分钟 #Recheck 的时间单位为毫秒 属性: dfs.heartbeat.interval 的默认值时 3 秒 #heartbeat 的时间单位为秒 计算公式 :2*recheck+10*heartbeat
4. SecondayNamenode的⼯作机制(检查点机制)
SecondaryNamenode,是 HDFS 集群中的重要组成部分,它可以辅助 Namenode 进 ⾏fsimage 和 editlog 的合并⼯作,减⼩ editlog ⽂件⼤⼩,以便缩短下次 Namenode 的重启时间,能尽快退出安全模式。 两个⽂件的合并周期,称之为检查点机制( checkpoint ),是可以通过 hdfsdefault.xml配置⽂件进⾏修改的:<property>
<name>dfs.namenode.checkpoint.period</name>
<value>3600</value>
<description>两次检查点间隔的秒数,默认是1个⼩时</description>
</property>
<property>
<name>dfs.namenode.checkpoint.txns</name>
<value>1000000</value>
<description>txid执⾏的次数达到100w次,也执⾏checkpoint</description>
</property>
<property>
<name>dfs.namenode.checkpoint.check.period</name>
<value>60</value>
<description>60秒⼀检查txid的执⾏次数</description>
</property>
通过上图,可以总结如下:
1. SecondaryNamenode请求Namenode停⽌使⽤正在编辑的editlog⽂件, Namenode会创建新的editlog⽂件(⼩了吧),同时更新seed_txid⽂件。
2. SecondaryNamenode通过HTTP协议获取Namenode上的fsimage和editlog⽂ 件。
3. SecondaryNamenode 将 fsimage 读进内存当中,并逐步分析 editlog ⽂件⾥的数据,进⾏合并操作,然后写⼊新⽂件fsimage_x.ckpt ⽂件中。 4. SecondaryNamenode将新⽂件 fsimage_x.ckpt 通过 HTTP 协议发送回 Namenode。 5. Namenode 再进⾏更名操作。
5. ⽹络拓扑
在进⾏副本冗余策略时,我们是否应该考虑⽹络带宽问题呢?答案是肯定的,⽹络带 宽是很稀缺的资源。( 希望 5G 时代能解决这个问题 ) 。因此在副本冗余时,这些副本存 储在哪个⼯作节点上,存储在哪个机架上?HDFS ⼜怎么知道哪个机架远,哪个机架 近呢。 衡量不同节点之间的带宽,实际上很难实现,HDFS 采⽤了⼀个较为简单的⽅式:把 ⽹络看成⼀颗树,两个节点之间的距离是他们到最近共同祖先的距离总和。假设有两个数据中⼼,如下图:
距离有这四种情况: Distance(/d1/r1/n1, /d1/r1/n1)=0 (同⼀节点上的进程) Distance(/d1/r1/n1, /d1/r1/n2)=2 (同⼀机架上的不同节点 ) Distance(/d1/r1/n1, /d1/r2/n3)=4 (同⼀数据中⼼不同机架上的节点) Distance(/d1/r1/n1, /d2/r3/n4)=6 (不同数据中⼼的节点) 带宽依次递减。
6. 机架感知
如何想让HDFS 知道⾃⼰的⽹络拓扑情况,那就是另外⼀个配置策略了,即机架感知。默认情况下,机架感知策略是关闭的。需要进⾏对net.topology.script.file.name 进⾏设置。如果不设置, namenode 就会将datanode注册属于 /default-rack 机架。使⽤了机架感知策略的副本存放:
第⼀个副本在 client 所处的节点上。如果客户端在集群外,随机选⼀个。 第⼆个副本与第⼀个副本不相同机架,随机⼀个节点进⾏存储 第三个副本与第⼆个副本相同机架,不同节点。
7. 节点动态上线
7.1. 属性说明
<!--在hdfs-site.xml⾥有⼀个属性,⽤于指定所有在线主机名和要上线的主机名的⽂件-->
<property>
<name>dfs.hosts</name>
<value></value>
<description>命名包含允许连接到namenode的主机列表的⽂件。必须指定⽂件的完整路径名。如果值为空,则允许所有主机</description>
</property>
7.2. 动态上线步骤
准备⼯作:准备⼀台配置了jdk和hadoop的新主机qianfeng04。如果克隆的话,别忘 记删除${hadoop.tmp.dir}指定的⽬录和logs⽬录
1. 修改dfs.hosts属性,指定⽂件include的全路径
<!--注意:include这个⽂件名,可以⾃定义-->
<property>
<name>dfs.hosts</name>
<value>/usr/local/hadoop/etc/hadoop/include</value>
</property>
2.
将待上线的主机名
(qianfeng04)
添加到
dfs.hosts
指定的⽂件内
[root@hadoop01 hadoop] # touch include # 创建⽂件 [root@hadoop01 hadoop] # vi include hadoop01 hadoop02 hadoop03 slave3 # 将要上线的主机名 注意: dfs.hosts 指定的⽂件中必须存储所有的在线主机名
3. 在namenode上刷新节点
[root@hadoop01 hadoop]# hadoop dfsadmin -refreshNodes
4. 在要上线的节点上重启 datanode
[root@hadoop01 hadoop]# hadoop-daemon.sh start datanode
5. 通过hadoop dfsadmin -report 或者web界⾯,可以看到, 节点已经上线。
6. 最后修改 slaves ,添加上新主机名。以便集群重启时,带上此节点[root@hadoop01 hadoop] # vi slaves hadoop01 hadoop02 hadoop03 slave3 # 添加此节点
8. 节点动态下线
8.1. 属性说明
<!--在hdfs-site.xml⾥有⼀个属性,⽤于指定存储将要退役的主机名的⽂件-->
<property>
<name>dfs.hosts.exclude</name>
<value></value>
<description>命名包含不允许连接到namenode的主机列表的⽂件。必须指定⽂件的完整路径名。如果该值为空,则不排除任何主机</description>
</property>
8.2. 下线步骤
1. 修改 dfs.hosts.exclude 属性,指定⽂件 exclude 的全路径<!--注意:dexclude这个⽂件名,可以⾃定义-->
<property>
<name>dfs.hosts.exclude</name>
<value>/usr/local/hadoop/etc/hadoop/exclude</value>
</property>
2.
将待下线的主机名
(qianfeng01)
加⼊到
dfs.hosts.exclude
指定的⽂件中
[root@hadoop01 hadoop] # touch exclude # 创建 exclude ⽂件 [root@hadoop01 hadoop] # vi exclude3. 在 namenode 节点上刷新节点hadoop01
[root@hadoop01 hadoop] # hadoop dfsadmin -refreshNodes4. 通过 hadoop dfsadmin -report 或者 web 界⾯,进⾏查看。
此时,该 datanode 状态转化为 Decommission In Progress 。表示该 datanode正在退役中,进⾏数据块的转移。 因此会花上⼀段时间。需要等待 ...... 当 decommission 进程完成数据移动, datanode 状态会转变为 Decommissioned, 然后 datanode 会⾃动停⽌ datanode 进程。 然后你可以看 ⻅dead nodes 下多了⼀个你想要下线的节点。5. 然后删除 include 和 exclude 中该节点的 hosts , 重新刷新 hadoop dfsadmin - refreshNodes 6. 最后别忘了删除 slaves 中该节点的配置,防⽌下次集群重启时, namenode 傻乎 乎的启动这个退役的节点。
注意 : 当你下线⼀个 datanode 节点,有可能该节点⻓时间处于 Decommission In Progress 状态,⼀直不能转变成 Decommissioned 。请你⽤ hadoop fsck / 检查下 是否有些块少于指定的块数,特别注意那些mapreduce 的临时⽂件。将这些删除, 并且从垃圾箱移除,该节点就可以顺利下线,这是我想到的解决办法。