在 Hadoop 2.0.0 之前,一个集群只有一个Namenode,这将面临单点故障问题。如果 Namenode 机器挂掉了,整个集群就用不了了。只有重启 Namenode ,才能恢复集群。另外正常计划维护集群的时候,还必须先停用整个集群,这样没办法达到 7 * 24小时可用状态。Hadoop 2.0 及之后版本增加了 Namenode 高可用机制,下面详细介绍。
非高可用部署,可参考我之前的文章:大数据Hadoop原理介绍+安装+实战操作(HDFS+YARN+MapReduce)
我们知道 NameNode 上存储的是 HDFS 上所有的元数据信息,因此最关键的问题在于 NameNode 挂了一个,备份的要及时顶上,这就意味着我们要把所有的元数据都同步到备份节点。好,接下来我们考虑如何同步呢?每次 HDFS 写入一个文件,都要同步写 NameNode 和其备份节点吗?如果备份节点挂了就会写失败?显然不能这样,只能是异步来同步元数据。如果 NameNode 刚好宕机却没有将元数据异步写入到备份节点呢?那这部分信息岂不是丢失了?这个问题就自然要引入第三方的存储了,在 HA 方案中叫做“共享存储”。每次写文件时,需要将日志同步写入共享存储,这个步骤成功才能认定写文件成功。然后备份节点定期从共享存储同步日志,以便进行主备切换。
NameNode 主备切换主要由 ZKFailoverController、HealthMonitor 和 ActiveStandbyElector 这 3 个组件来协同实现:
过 去几年中 Hadoop 社区涌现过很多的 NameNode 共享存储方案,比如 shared NAS+NFS、BookKeeper、BackupNode 和 QJM(Quorum Journal Manager) 等等。目前社区已经把由 Clouderea 公司实现的基于 QJM 的方案合并到 HDFS 的 trunk 之中并且作为默认的共享存储实现,本部分只针对基于 QJM 的共享存储方案的内部实现原理进行分析。为了理解 QJM 的设计和实现,首先要对 NameNode 的元数据存储结构有所了解。
Active NameNode 和 StandbyNameNode 使用 JouranlNode 集群来进行数据同步的过程如下图 所示,Active NameNode 首先把 EditLog 提交到 JournalNode 集群,然后 Standby NameNode 再从 JournalNode 集群定时同步 EditLog:
处 于 Standby 状态的 NameNode 转换为 Active 状态的时候,有可能上一个 Active NameNode 发生了异常退出,那么 JournalNode 集群中各个 JournalNode 上的 EditLog 就可能会处于不一致的状态,所以首先要做的事情就是让 JournalNode 集群中各个节点上的 EditLog 恢复为一致。另外如前所述,当前处于 Standby 状态的 NameNode 的内存中的文件系统镜像有很大的可能是落后于旧的 Active NameNode 的,所以在 JournalNode 集群中各个节点上的 EditLog 达成一致之后,接下来要做的事情就是从 JournalNode 集群上补齐落后的 EditLog。只有在这两步完成之后,当前新的 Active NameNode 才能安全地对外提供服务。
对比一下就会看到,yarn集群的高可用架构比hdfs namenode的要简单太多了,没有zkfc,没有QJM集群,只需要一个zookeeper集群来负责选举出active的resourcemanager就好了。
为什么差别这么大?
如果在开始部署 Hadoop 集群的时候就启用 NameNode 的高可用的话,那么相对会比较容易。但是如果在采用传统的单 NameNode 的架构运行了一段时间之后,升级为 NameNode 的高可用架构的话,就要特别注意在升级的时候需要按照以下的步骤进行操作:
主机名 | NameNode | DataNode | Zookeeper | ZKFC | JournalNode | ResourceManager | NodeManager |
local-168-182-110 | * | * | * | * | * | ||
local-168-182-111 | * | * | * | * | |||
local-168-182-112 | * | * | * | * | |||
local-168-182-113 | * | * | * | * | * |
也可以参考我之前的文章:分布式开源协调服务——Zookeeper
下载地址:https://zookeeper.apache.org/releases.html
cd /opt/bigdata/wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.0/apache-zookeeper-3.8.0-bin.tar.gz --no-check-certificatetar -xf apache-zookeeper-3.8.0-bin.tar.gz
vi /etc/profileexport ZOOKEEPER_HOME=/opt/bigdata/apache-zookeeper-3.8.0-bin/export PATH=$ZOOKEEPER_HOME/bin:$PATH# 加载生效source /etc/profile
cd $ZOOKEEPER_HOMEcp conf/zoo_sample.cfg conf/zoo.cfgmkdir $ZOOKEEPER_HOME/datacat >conf/zoo.cfg<日志文件也保存在这个目录里。不要使用/tmp目录dataDir=/opt/bigdata/apache-zookeeper-3.8.0-bin/data# 端口,默认就是2181clientPort=2181# 集群中的follower服务器(F)与leader服务器(L)之间初始连接时能容忍的最多心跳数(tickTime的数量),超过此数量没有回复会断开链接initLimit=10# 集群中的follower服务器与leader服务器之间请求和应答之间能容忍的最多心跳数(tickTime的数量)syncLimit=5# 最大客户端链接数量,0不限制,默认是0maxClientCnxns=60# zookeeper集群配置项,server.1,server.2,server.3是zk集群节点;hadoop-node1,hadoop-node2,hadoop-node3是主机名称;2888是主从通信端口;3888用来选举leaderserver.1=local-168-182-110:2888:3888server.2=local-168-182-111:2888:3888server.3=local-168-182-112:2888:3888EOF
echo 1 > $ZOOKEEPER_HOME/data/myid
scp -r $ZOOKEEPER_HOME local-168-182-111:/opt/bigdata/scp -r $ZOOKEEPER_HOME local-168-182-112:/opt/bigdata/# 也需要添加环境变量和修改myid,local-168-182-111的myid设置2,local-168-182-112的myid设置3
cd $ZOOKEEPER_HOME# 启动./bin/zkServer.sh start# 查看状态./bin/zkServer.sh status
下载地址:https://dlcdn.apache.org/hadoop/common/
mkdir -p /opt/bigdata/hadoop && cd /opt/bigdata/hadoopwget https://dlcdn.apache.org/hadoop/common/hadoop-3.3.4/hadoop-3.3.4.tar.gz --no-check-certificate# 解压tar -zvxf hadoop-3.3.4.tar.gz
vi /etc/profileexport HADOOP_HOME=/opt/bigdata/hadoop/hadoop-3.3.4export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH# 加载生效source /etc/profile
# 在hadoop-env.sh文件末尾追加export JAVA_HOME=/opt/jdk1.8.0_212export HDFS_NAMENODE_USER=rootexport HDFS_DATANODE_USER=rootexport HDFS_SECONDARYNAMENODE_USER=rootexport YARN_RESOURCEMANAGER_USER=rootexport YARN_NODEMANAGER_USER=root
# 创建存储目录mkdir -p /opt/bigdata/hadoop/hadoop-3.3.4/data/namenodemkdir -p /opt/bigdata/hadoop/hadoop-3.3.4/data/journalnode
fs.defaultFS hdfs://myhdfs hadoop.tmp.dir /opt/bigdata/hadoop/hadoop-3.3.4/data/namenode ha.zookeeper.quorum local-168-182-110:2181,local-168-182-111:2181,local-168-182-112:2181 hadoop.http.staticuser.user root hadoop.proxyuser.root.hosts * hadoop.proxyuser.root.groups * hadoop.proxyuser.root.users * fs.trash.interval 1440
dfs.nameservices myhdfs dfs.ha.namenodes.myhdfs nn1,nn2 dfs.namenode.rpc-address.myhdfs.nn1 local-168-182-110:8082 dfs.namenode.rpc-address.myhdfs.nn2 local-168-182-113:8082 dfs.namenode.http-address.myhdfs.nn1 local-168-182-110:9870 dfs.namenode.http-address.myhdfs.nn2 local-168-182-113:9870 dfs.namenode.shared.edits.dir qjournal://local-168-182-110:8485;local-168-182-111:8485;local-168-182-112:8485/myhdfs dfs.client.failover.proxy.provider.myhdfs org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider dfs.ha.fencing.methods sshfence dfs.ha.fencing.ssh.private-key-files /root/.ssh/id_rsa dfs.journalnode.edits.dir /opt/bigdata/hadoop/hadoop-3.3.4/data/journalnode dfs.ha.automatic-failover.enabled true dfs.client.failover.proxy.provider.myhdfs org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider dfs.replication 3 dfs.permissions.enabled false
将下面内容覆盖文件,默认只有localhost,works配置的为 DataNode节点的主机名或IP,如果配置了works文件,并且配置ssh免密登录,可以使用 start-dfs.sh 启动 HDFS集群
local-168-182-111local-168-182-112local-168-182-113
yarn.resourcemanager.ha.enabled true yarn.resourcemanager.cluster-id myyarn yarn.resourcemanager.ha.rm-ids rm1,rm2 yarn.resourcemanager.hostname.rm1 local-168-182-110 yarn.resourcemanager.hostname.rm2 local-168-182-113 yarn.resourcemanager.webapp.address.rm1 local-168-182-110:8088 yarn.resourcemanager.webapp.address.rm2 local-168-182-113:8088 hadoop.zk.address local-168-182-110:2181,local-168-182-111:2181,local-168-182-112:2181 yarn.resourcemanager.recovery.enabled true yarn.resourcemanager.store.class org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore yarn.nodemanager.aux-services mapreduce_shuffle yarn.nodemanager.pmem-check-enabled false yarn.nodemanager.vmem-check-enabled false yarn.log-aggregation-enable true yarn.log.server.url http://local-168-182-110:19888/jobhistory/logs yarn.log-aggregation.retain-seconds 604880
mapreduce.framework.name yarn mapreduce.jobhistory.address local-168-182-110:10020 mapreduce.jobhistory.webapp.address local-168-182-110:19888 yarn.app.mapreduce.am.env HADOOP_MAPRED_HOME=${HADOOP_HOME} mapreduce.map.env HADOOP_MAPRED_HOME=${HADOOP_HOME} mapreduce.reduce.env HADOOP_MAPRED_HOME=${HADOOP_HOME}
scp -r $HADOOP_HOME local-168-182-111:/opt/bigdata/hadoop/scp -r $HADOOP_HOME local-168-182-112:/opt/bigdata/hadoop/scp -r $HADOOP_HOME local-168-182-113:/opt/bigdata/hadoop/# 注意在其它节点先创建/opt/bigdata/hadoop/和环境变量
# 在local-168-182-110、local-168-182-111、local-168-182-112机器上启动hdfs --daemon start journalnode
# 格式化(第一次配置情况下使用,已运行集群不能用),在local-168-182-110执行hdfs namenode -format
hdfs namenode -initializeSharedEdits
hdfs --daemon start namenode
hdfs namenode -bootstrapStandby
hdfs --daemon start namenode
# 在local-168-182-110上执行hdfs zkfc -formatZK
# 在local-168-182-110,local-168-182-113上执行,ZKFC远程杀死假死SNN使用的killall namenode命令属于psmisc软件中的。建议所有节点都安装psmisc。yum install -y psmisc
# 或者在start-dfs.sh,stop-dfs.sh(在hadoop安装目录的sbin里)两个文件顶部添加以下参数export HDFS_NAMENODE_USER=rootexport HDFS_DATANODE_USER=rootexport HDFS_JOURNALNODE_USER=rootexport HDFS_SECONDARYNAMENODE_USER=rootexport YARN_RESOURCEMANAGER_USER=rootexport YARN_NODEMANAGER_USER=rootexport HDFS_ZKFC_USER=root
# 在local-168-182-110节点上执行start-dfs.sh
jps
web地址:
http://local-168-182-110:9870/
http://local-168-182-113:9870/
start-yarn.shjps
web地址:
http://local-168-182-110:8088/cluster/cluster
http://local-168-182-113:8088/cluster/cluster
mapred --daemon start historyserver
hdfs haadmin -getServiceState nn1hdfs haadmin -getServiceState nn2
# 设置nn1为Standby,nn2为Active# 当HDFS的HA配置中开启了自动故障转移时,需加上--forcemanual参数(谨慎使用此参数)hdfs haadmin -transitionToStandby --forcemanual nn1hdfs haadmin -transitionToActive --forcemanual nn2# 查看#hdfs haadmin -getServiceState nn1#hdfs haadmin -getServiceState nn2# 查看所有节点状态hdfs haadmin -getAllServiceState# 设置nn1为Active,nn1为Standby# 当HDFS的HA配置中开启了自动故障转移时,需加上--forcemanual 参数(谨慎使用此参数)hdfs haadmin -transitionToActive --forcemanual nn1hdfs haadmin -transitionToStandby --forcemanual nn2# 查看#hdfs haadmin -getServiceState nn1#hdfs haadmin -getServiceState nn2# 查看所有NameNode节点状态hdfs haadmin -getAllServiceState
在active的NameNode节点上,kill掉NameNode进程:
jpsjps|grep NameNode|awk '{print $1}'|xargs kill -9jps# 再查看节点状态hdfs haadmin -getServiceState nn1hdfs haadmin -getServiceState nn2# 查看所有NameNode节点状态hdfs haadmin -getAllServiceState
# 启动namenodehdfs --daemon start namenodejps# 查看节点状态hdfs haadmin -getServiceState nn1hdfs haadmin -getServiceState nn2# 查看所有NameNode节点状态hdfs haadmin -getAllServiceState
yarn rmadmin -getServiceState rm1yarn rmadmin -getServiceState rm2
# 设置rm1为Standby,设置rm2为Active# 当YARN的HA配置中开启了自动故障转移时,需加上-forcemanual 参数(谨慎使用此参数)yarn rmadmin -transitionToStandby -forcemanual rm1yarn rmadmin -transitionToActive -forcemanual rm2# 查看#yarn rmadmin -getServiceState rm1#yarn rmadmin -getServiceState rm2yarn rmadmin -getAllServiceState# 设置rm1为Active,设置rm2为Standby# 当YARN的HA配置中开启了自动故障转移时,需加上-forcemanual 参数yarn rmadmin -transitionToActive -forcemanual rm1yarn rmadmin -transitionToStandby -forcemanual rm2# 查看所有ResourceManager节点状态yarn rmadmin -getAllServiceState
在active的ResourceManager节点上,kill掉ResourceManager进程:
yarn rmadmin -getAllServiceStatejpsjps|grep ResourceManager|awk '{print $1}'|xargs kill -9jps# 再查看节点状态#yarn rmadmin -getServiceState rm1#yarn rmadmin -getServiceState rm2# 查看所有ResourceManager节点状态yarn rmadmin -getAllServiceState
yarn --daemon start resourcemanagerjps# 查看所有ResourceManager节点状态yarn rmadmin -getAllServiceState
Hadoop 3.3.4 HA(高可用)原理与实现就先到这里了,有疑问的小伙伴欢迎给我留言哦,后面会持续更新关于大数据方面的文章,请小伙伴耐心等待~
页面更新:2024-04-30
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号