在Ubuntu上实现HDFS高可用的核心步骤
HDFS高可用(HA)通过双NameNode互备、JournalNode同步元数据、ZooKeeper自动故障转移等机制,解决单点故障问题,确保集群持续提供服务。以下是Ubuntu环境下的具体实现流程:
环境配置
节点角色规划
nn1、nn2),分别运行Active和Standby状态的NameNode;jn1、jn2、jn3),负责同步NameNode元数据(需奇数台,确保容错);修改Hadoop配置目录(如/opt/hadoop/etc/hadoop)下的core-site.xml和hdfs-site.xml文件:
core-site.xml配置HDFS默认文件系统和ZooKeeper集群地址(用于自动故障转移):
<configuration>
<!-- 指定HDFS集群名称(需与hdfs-site.xml中的dfs.nameservices一致) -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<!-- 指定ZooKeeper集群地址(用于自动故障转移) -->
<property>
<name>ha.zookeeper.quorum</name>
<value>zk1:2181,zk2:2181,zk3:2181</value>
</property>
</configuration>
hdfs-site.xml配置HDFS高可用相关参数(关键参数说明见注释):
<configuration>
<!-- 指定HDFS集群名称(与core-site.xml中的fs.defaultFS一致) -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<!-- 定义NameNode节点列表(逗号分隔) -->
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<!-- Active NameNode的RPC地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>nn1_host:8020</value>
</property>
<!-- Standby NameNode的RPC地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>nn2_host:8020</value>
</property>
<!-- Active NameNode的HTTP地址(Web UI) -->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>nn1_host:50070</value>
</property>
<!-- Standby NameNode的HTTP地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>nn2_host:50070</value>
</property>
<!-- 元数据共享存储路径(JournalNode集群地址) -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://jn1:8485;jn2:8485;jn3:8485/mycluster</value>
</property>
<!-- 客户端故障转移代理(自动选择Active NameNode) -->
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<!-- 防脑裂机制:SSH强制杀死故障NameNode -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<!-- SSH私钥路径(用于故障转移时的SSH登录) -->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/hadoop/.ssh/id_rsa</value>
</property>
<!-- JournalNode数据存储路径 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/opt/hadoop/journalnode/data</value>
</property>
</configuration>
ZooKeeper用于监控NameNode状态并协调自动故障转移,需先部署并启动ZooKeeper集群:
安装ZooKeeper
在3台ZooKeeper节点上执行:
sudo apt-get update
sudo apt-get install zookeeper zookeeperd -y
配置ZooKeeper
修改/etc/zookeeper/conf/zoo.cfg文件,添加集群节点信息:
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/var/lib/zookeeper
clientPort=2181
server.1=zk1:2888:3888
server.2=zk2:2888:3888
server.3=zk3:2888:3888
server.x:x为节点ID(需在dataDir目录下创建myid文件,内容为对应ID,如zk1节点的myid内容为1)。启动ZooKeeper
在每台ZooKeeper节点上执行:
sudo systemctl start zookeeper
sudo systemctl enable zookeeper
# 验证状态(需看到Leader和Follower)
zkServer.sh status
JournalNode负责同步Active NameNode的元数据到Standby NameNode,需先启动JournalNode:
创建数据目录
在所有JournalNode节点上创建数据存储目录:
mkdir -p /opt/hadoop/journalnode/data
chown -R hadoop:hadoop /opt/hadoop/journalnode
启动JournalNode服务
在所有JournalNode节点上执行:
hdfs --daemon start journalnode
# 验证状态(需看到3个JournalNode进程)
jps | grep JournalNode
在**其中一台NameNode(如nn1)**上执行以下操作,初始化共享元数据:
格式化NameNode
(首次配置需执行,格式化会清除NameNode数据,谨慎操作):
hdfs namenode -format
初始化共享编辑日志
将nn1的元数据同步到JournalNode集群:
hdfs namenode -initializeSharedEdits
同步元数据到Standby NameNode
在nn2上执行,将nn1的元数据复制到nn2:
hdfs namenode -bootstrapStandby
格式化ZooKeeper中的HA状态
在nn1上执行(仅首次配置需执行,用于初始化ZooKeeper中的HA状态):
hdfs zkfc -formatZK
启动HDFS服务
在任意节点上执行(启动所有HDFS进程,包括NameNode、DataNode、JournalNode):
start-dfs.sh
验证NameNode状态
使用haadmin命令查看NameNode状态(Active和Standby状态应分别为不同节点):
hdfs haadmin -getServiceState nn1 # 应返回Standby或Active
hdfs haadmin -getServiceState nn2 # 应返回Standby或Active
或通过Web UI(如http://nn1_host:9870、http://nn2_host:9870)查看状态。
模拟Active NameNode故障
在nn1上找到NameNode进程并杀死:
jps | grep NameNode | awk '{print $1}' | xargs kill -9
验证自动故障转移
等待10-30秒(ZooKeeper检测超时时间),再次检查NameNode状态:
hdfs haadmin -getServiceState nn1 # 应返回Standby
hdfs haadmin -getServiceState nn2 # 应返回Active
此时nn2已自动切换为Active状态,集群继续提供服务。
在客户端节点(如提交MapReduce任务的机器)上,配置core-site.xml和hdfs-site.xml(内容与集群节点一致),客户端会自动检测并连接到Active NameNode。
通过以上步骤,即可在Ubuntu上实现HDFS高可用,确保NameNode节点故障时自动切换,保障集群持续运行。