若发现文章有误或有任何建议,敬请指教,感谢
一、Hadoop-HA 概述
HA,即High Availablity,高可用,指的是集群能7 * 24 小时不中断服务。
实现高可用最关键的策略是消除单点故障。HA严格来说应该分成各个组件的HA机制:HDFS的HA和YARN的HA。
NameNode主要在以下两个方面影响HDFS集群:
- NameNode机器发生以外,如宕机,集群将无法使用,直到管理员重启
- NameNode机器需要升级,包括软件、硬件升级,此时集群也将无法使用
HDFS HA 功能通过配置多个NameNodes(Activity / Standby)实现在集群中对NameNode的热备来解决上述问题。
如果出现故障,如机器崩溃或机器需要升级维护,这时可通过该方法将NameNode很快的切换到另一台机器。
1.1 HDFS-HA 集群搭建
原始HDFS集群的规划:
节点1 | 节点2 | 节点3 |
---|---|---|
NameNode | \ | SecondaryNameNode |
DataNode | DataNode | DataNode |
HA的主要目的是消除NameNode的单点故障,HDFS-HA的节点分配:
节点1 | 节点2 | 节点3 |
---|---|---|
NameNode | NameNode | NameNode |
DataNode | DataNode | DataNode |
1.2 HDFS-HA 核心问题
1)如何保证三台NameNode的数据一致?
a. FsImage:让一台NN生成数据,让其他机器NN同步
b. Edits:需要引进新的模块 JournalNode 来保证 edits文件的数据一致性
2)怎么让同时只有一台NN是active,其他的NN为standby模式?
a.手动分配
b.自动分配
3) 2NN 在 HA架构中并不存在,谁来定期合并 fsImage 和 edits?
由standby的NN处理
4)若当前NN出现了故障,怎么切换到其他的NN?(Zookeeper)
a.手动故障转移
b.自动故障转移
二、HDFS-HA 手动模式
节点1 | 节点2 | 节点3 |
---|---|---|
NameNode | NameNode | NameNode |
JournalNode | JournalNode | JournalNode |
DataNode | DataNode | DataNode |
笔者是通过之前的Hadoop集群迁移过来的,这里将原先的hadoop文件夹拷贝一份,删除里面的日志logs,和NN、DN的信息,然后分发给其他两个节点。
若是第一次安装hadoop,则可通过清华大学镜像站下载:hadoop3.3.1.tar.gz
2.1 配置Hadoop
提示:配置文件都在hadoop根目录下的/etc/hadoop里
注:由于笔者是用Docker容器的root用户测试的,在运行时,显示未指定用户,所以这里笔者先在hadoop-env.sh里添加了一些报错提示的用户。同时指定JDK
hadoop-env.sh
export JAVA_HOME=/opt/java/jdk8
export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root
export HDFS_JOURNALNODE_USER=root
export HDFS_ZKFC_USER=root
1.core-site.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!-- 把多个NameNode的地址组装成一个集群cluster -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://cluster</value>
</property>
<!-- 指定hadoop运行时产生的存储目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/module/hadoopha/data</value>
</property>
</configuration>
2.hdfs-site.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!--1. NameNode数据存储目录 -->
<property>
<name>dfs.namenode.name.dir</name>
<value>file://${hadoop.tmp.dir}/name</value>
</property>
<!--2. DataNode数据存储目录 -->
<property>
<name>dfs.datanode.data.dir</name>
<value>file://${hadoop.tmp.dir}/data</value>
</property>
<!--3. JournalNode数据存储目录 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>${hadoop.tmp.dir}/jn</value>
</property>
<!--4. 完全分布式集群名称 -->
<property>
<name>dfs.nameservices</name>
<value>cluster</value>
</property>
<!--5. 指定集群中的NameNode节点 -->
<property>
<name>dfs.ha.namenodes.cluster</name>
<value>nn1,nn2,nn3</value>
</property>
<!--6. 每个NameNode节点的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.cluster.nn1</name>
<value>hadoop101:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.cluster.nn2</name>
<value>hadoop102:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.cluster.nn3</name>
<value>hadoop103:8020</value>
</property>
<!--7. 每个NameNode节点的HTTP Web访问地址 -->
<property>
<name>dfs.namenode.http-address.cluster.nn1</name>
<value>hadoop101:9870</value>
</property>
<property>
<name>dfs.namenode.http-address.cluster.nn2</name>
<value>hadoop102:9870</value>
</property>
<property>
<name>dfs.namenode.http-address.cluster.nn3</name>
<value>hadoop103:9870</value>
</property>
<!--8. 指定NameNode 元数据在JournalNode上的存储位置-->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop101:8485;hadoop102:8485;hadoop103:8485/cluster</value>
</property>
<!--9. 访问代理类: client用于确定哪个NameNode为Active状态-->
<property>
<name>dfs.client.failover.proxy.provider.cluster</name