Cris 玩转大数据系列之 Hadoop HA 实现

本文详细介绍了Cris在Hadoop高可用(HA)方面的实践,涵盖HDFS和YARN的HA原理、手动与自动故障转移过程,以及Federation架构设计。通过学习,读者将能理解和实施Hadoop HA解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

零、序

强烈建议看完 Cris 小哥哥的 Linux 学习笔记以及 ZooKeeper 和 Hadoop 的学习笔记再来看这篇笔记,否则你几乎不可能看懂~

1. Hadoop 实现 HA 原理

1.1 什么是 HA?

1)所谓HA(high available),即高可用(7*24小时不中断服务)。

2)实现高可用最关键的策略是消除单点故障(single point of failure,SPOF)。单点故障是一个组件发生故障,就会导致整个系统无法运行。HA严格来说应该分成各个组件的HA机制:HDFS的HA和YARN的HA。

3)Hadoop2.0之前,在HDFS集群中NameNode存在单点故障。

4)NameNode主要在以下两个方面影响HDFS集群
​ NameNode机器发生意外,如宕机,集群将无法使用,直到管理员重启
​ NameNode机器需要升级,包括软件、硬件升级,此时集群也将无法使用

HDFS HA功能通过配置Active/Standby两个nameNodes实现在集群中对NameNode的热备来解决上述问题。如果出现故障,如机器崩溃或机器需要升级维护,这时可通过此种方式将NameNode很快的切换到另外一台机器

1.2 HA 工作机制

​ 配置两个 namenode,通过双 namenode 消除单点故障

2. HDFS-HA 手动故障转移(了解)

实际生产中,都是使用自动故障转移,这里给出手动故障转移的操作流程是希望大家知其所以然~

2.1 要点

1)元数据管理方式需要改变:
​ 内存中各自保存一份元数据;
Edits 日志只有 Active 状态的 namenode 节点可以做写操作;
​ 两个 namenode 都可以读取 edits
​ 共享的 edits 放在一个共享存储中管理(qjournalNFS 两个主流实现);

2)必须保证两个 NameNode 之间能够 ssh 无密码登录。

3)隔离(Fence),即同一时刻仅仅有一个 NameNode 对外提供服务,防止脑裂(split-brain)

2.2 环境准备

  1. 修改 IP
  2. 修改主机名及主机名和 IP 地址的映射
  3. 关闭防火墙
  4. ssh 免密登录
  5. 安装 JDK,配置环境变量等

如果不会的同学请参考 Cris 小哥哥的 Hadoop 学习笔记

2.3 测试集群规划

hadoop101hadoop102hadoop103
HDFSNameNode DataNode JournalNodeNameNode DataNode JournalNodeDataNode JournalNode
YARNNodeManagerResourceManager NodeManagerNodeManager

2.4 配置 HDFS-HA 集群

  1. 首先应该做好虚拟机的快照!!! 防止出现问题随时回滚 ?

  2. /opt/module/ 目录下创建一个 HA 文件夹

    mkdir HA
    

    然后将我们之前就装好的 Hadoop 的文件夹拷贝到 HA 目录里去

    cp -r zookeeper-3.4.10/ HA/
    

mark

  1. 确保配置 hadoop-env.sh 中的 JAVA_HOME 变量为 Linux 安装的 jdk 目录

    mark

  2. 配置 core-site.xml,具体配置参数如下

    <configuration>
    <!-- 把两个NameNode的地址组装成一个集群mycluster -->
            <property>
                    <name>fs.defaultFS</name>
                    <value>hdfs://mycluster</value>
            </property>
    
            <!-- 声明journalnode服务本地文件系统存储目录-->
            <property>
                    <name>dfs.journalnode.edits.dir</name>
                    <value>/opt/module/HA/hadoop-2.7.2/data/jn</value>
            </property>
    
            <!-- 指定hadoop运行时产生文件的存储目录 -->
            <property>
                    <name>hadoop.tmp.dir</name>
                    <value>/opt/module/HA/hadoop-2.7.2/data/tmp</value>
            </property>
    </configuration>
    
  3. 配置 hdfs-site.xml

    <configuration>
    <!-- 完全分布式集群名称 -->
            <property>
                    <name>dfs.nameservices</name>
                    <value>mycluster</value>
            </property>
    
            <!-- 该nameservice下NameNode节点都有哪些 -->
            <property>
                    <name>dfs.ha.namenodes.mycluster</name>
                    <value>nn1,nn2</value>
            </property>
    
            <!-- nn1的RPC通信地址 -->
            <property>
                    <name>dfs.namenode.rpc-address.mycluster.nn1</name>
                    <value>hadoop101:8020</value>
            </property>
    
            <!-- nn2的RPC通信地址 -->
            <property>
                    <name>dfs.namenode.rpc-address.mycluster.nn2</name>
                    <value>hadoop102:8020</value>
            </property>
    
            <!-- nn1的http通信地址 -->
            <property>
                    <name>dfs.namenode.http-address.mycluster.nn1</name>
                    <value>hadoop101:50070</value>
            </property>
    
            <!-- nn2的http通信地址 -->
            <property>
                    <name>dfs.namenode.http-address.mycluster.nn2</name>
                    <value>hadoop102:50070</value>
            </property>
    
            <!-- 指定NameNode元数据在JournalNode上的存放位置 -->
            <property>
                    <name>dfs.namenode.shared.edits.dir</name>
    				<value>qjournal://hadoop101:8485;hadoop102:8485;hadoop103:8485/mycluster</value>
            </property>
    
            <!-- 配置隔离机制,即同一时刻只能有一台服务器对外响应 -->
            <property>
                    <name>dfs.ha.fencing.methods</name>
                    <value>sshfence</value>
            </property>
    
            <!-- 使用隔离机制时需要ssh无秘钥登录-->
            <property>
                    <name>dfs.ha.fencing.ssh.private-key-files</name>
                    <value>/home/cris/.ssh/id_rsa</value>
            </property>
    
            <!-- 关闭权限检查-->
            <property>
                    <name>dfs.permissions.enable</name>
                    <value>false</value>
            </property>
    
            <!-- 客户端访问代理类:客户端通过该类判断哪个namenode是active -->
            <property>
                    <name>dfs.client.failover.proxy.provider.mycluster</name>
            <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
            </property>
        
        </configuration>
    
  4. 接下来所有操作默认是在 /opt/module/HA/hadoop-2.7.2 下进行

  5. 删除以前的 logsdata 文件夹

    rm -rf data/ logs/
    

    如果这两个文件夹不存在就不删

  6. 分发同步文件到另外的两台机子上

xsync /opt/module/HA/hadoop-2.7.2/

2.5 启动 HDFS-HA 集群

  • 接下来所有操作默认是在 /opt/module/HA/hadoop-2.7.2 下进行

  • 在各个 JournalNode 节点上,输入以下命令启动 journalnode 服务

    sbin/hadoop-daemon.sh start journalnode
    

    确保三台虚拟机可以正常启动 journalnode 服务

  • nn1 上,对其进行格式化,并启动(配置文件设置 101 节点为 nn1

    bin/hdfs namenode -format
    sbin/hadoop-daemon.sh start namenode
    
  • nn2 上,同步 nn1 的元数据信息

    bin/hdfs namenode -bootstrapStandby
    
  • 启动 nn2

    sbin/hadoop-daemon.sh start namenode
    
  • 观察结果

    浏览器打开 http://hadoop102:50070http://hadoop101:50070,可以发现当前 nameNode 服务均为 standby

    mark

  • nn1 上,启动所有 datanode

    sbin/hadoop-daemons.sh start datanode
    
  • nn2 切换为 Active

    bin/hdfs haadmin -transitionToActive nn2
    
  • 查看是否 Active

    bin/hdfs haadmin -getServiceState nn2
    

    mark

2.6 手动模拟故障并转移

此时我们杀掉 102 上的 nn2 进程,然后手动输入命令指定 101 上的 nn1 进程顶上

这里的 nn2nn1 都是指的 nameNode 进程

kill -9 1982
bin/hdfs haadmin -failover nn2 nn1

可以发现 http://hadoop102:50070 无法访问,但是 http://hadoop101:50070 成为了 active 节点对外提供服务

3. HDFS-HA 自动故障转移(重点)

3.1 原理

​ 前面学习了使用命令hdfs haadmin -failover手动进行故障转移,在该模式下,即使现役NameNode已经失效,系统也不会自动从现役NameNode转移到待机NameNode,下面学习如何配置部署HA自动进行故障转移。
自动故障转移为HDFS部署增加了两个新组件:ZooKeeper和ZKFailoverController(ZKFC)进程。ZooKeeper是维护少量协调数据,通知客户端这些数据的改变和监视客户端故障的高可用服务。
HA的自动故障转移依赖于ZooKeeper的以下功能:

1)故障检测:集群中的每个NameNode在ZooKeeper中维护了一个持久会话,如果机器崩溃,ZooKeeper中的会话将终止,ZooKeeper通知另一个NameNode需要触发故障转移。

2)现役NameNode选择:ZooKeeper提供了一个简单的机制用于唯一的选择一个节点为active状态。如果目前现役NameNode崩溃,另一个节点可能从ZooKeeper获得特殊的排外锁以表明它应该成为现役NameNode。

ZKFC是自动故障转移中的另一个新组件,是ZooKeeper的客户端,也监视和管理NameNode的状态。每个运行NameNode的主机也运行了一个ZKFC进程,ZKFC负责:

1)健康监测:ZKFC使用一个健康检查命令定期地ping与之在相同主机的NameNode,只要该NameNode及时地回复健康状态,ZKFC认为该节点是健康的。如果该节点崩溃,冻结或进入不健康状态,健康监测器标识该节点为非健康的。

2)ZooKeeper会话管理:当本地NameNode是健康的,ZKFC保持一个在ZooKeeper中打开的会话。如果本地NameNode处于active状态,ZKFC也保持一个特殊的znode锁,该锁使用了ZooKeeper对短暂节点的支持,如果会话终止,锁节点将自动删除。

3)基于ZooKeeper的选择:如果本地NameNode是健康的,且ZKFC发现没有其它的节点当前持有znode锁,它将为自己获取该锁。如果成功,则它已经赢得了选择,并负责运行故障转移进程以使它的本地NameNode为active。故障转移进程与前面描述的手动故障转移相似,首先杀掉之前active 状态的NameNode,然后本地NameNode转换为active状态。

3.2 原理图

mark

3.3 规划集群

hadoop102hadoop103hadoop104
HDFSNameNode DataNode JournalNode ZKFCNameNode DataNode JournalNode ZKFCDataNode JournalNode
YARNNodeManagerResourceManager NodeManagerNodeManager
ZookeeperZookeeperZookeeperZookeeper

3.4 配置HDFS-HA自动故障转移

注意:确保 ZooKeeper 集群配置完毕以后才能进行这一步操作,详情参考 Cris 的 ZooKeeper 学习笔记

  1. 具体配置

    (1)在 hdfs-site.xml 中增加

    <property>
    	<name>dfs.ha.automatic-failover.enabled</name>
    	<value>true</value>
    </property>
    

    (2)在 core-site.xml 文件中增加

    <property>
    	<name>ha.zookeeper.quorum</name>
    	<value>hadoop101:2181,hadoop102:2181,hadoop103:2181</value>
    </property>
    
  2. 然后使用 xsync 同步修改后的配置文件

  3. 启动(在 101 服务器),以下操作均在 /opt/module/HA/hadoop-2.7.2 下进行

    (1)关闭所有 HDFS 服务:

    sbin/stop-dfs.sh
    

    (2)启动 ZooKeeper 集群:

    startall_zk
    

    这里使用的是 Cris 写的 ZooKeeper 群起脚本,详情参考之前笔记,这里不再细说

    (3)初始化 HAZookeeper 中状态:

    bin/hdfs zkfc -formatZK
    

    (4)启动 HDFS 服务:

    sbin/start-dfs.sh
    
  4. 此时如果我们使用 kill 杀掉 active 状态的 nameNode 节点,那么 ZooKeeper 将会自动通知 standby 状态的 nameNodeZKFC,将该台 nameNode 节点设置为 active,然后运维人员就开始抢救挂掉的 nameNode 节点了~

4. YARN-HA 配置

4.1 YARN-HA工作机制

官方文档:http://hadoop.apache.org/docs/r2.7.2/hadoop-yarn/hadoop-yarn-site/ResourceManagerHA.html

mark

4.2 集群规划

hadoop101hadoop102hadoop103
HDFSNameNode DataNode JournalNode ZKFCNameNode DataNode JournalNode ZKFCDataNode JournalNode
YARNResourceManager NodeManagerResourceManager NodeManagerNodeManager
ZookeeperZookeeperZookeeperZookeeper

4.3 配置 yarn-site.xml

mark

<configuration>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>

    <!--启用resourcemanager ha-->
    <property>
        <name>yarn.resourcemanager.ha.enabled</name>
        <value>true</value>
    </property>

    <!--声明两台resourcemanager的地址-->
    <property>
        <name>yarn.resourcemanager.cluster-id</name>
        <value>cluster-yarn1</value>
    </property>

    <property>
        <name>yarn.resourcemanager.ha.rm-ids</name>
        <value>rm1,rm2</value>
    </property>

    <property>
        <name>yarn.resourcemanager.hostname.rm1</name>
        <value>hadoop101</value>
    </property>

    <property>
        <name>yarn.resourcemanager.hostname.rm2</name>
        <value>hadoop102</value>
    </property>

    <!--指定zookeeper集群的地址-->
    <property>
        <name>yarn.resourcemanager.zk-address</name>
        <value>hadoop101:2181,hadoop102:2181,hadoop103:2181</value>
    </property>

    <!--启用自动恢复-->
    <property>
        <name>yarn.resourcemanager.recovery.enabled</name>
        <value>true</value>
    </property>

    <!--指定resourcemanager的状态信息存储在zookeeper集群-->
    <property>
        <name>yarn.resourcemanager.store.class</name>
 	<value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
    </property>

        <!-- 日志聚集功能使能 -->
        <property>
                <name>yarn.log-aggregation-enable</name>
                <value>true</value>
        </property>

        <!-- 日志保留时间设置7天 -->
        <property>
                <name>yarn.log-aggregation.retain-seconds</name>
                <value>604800</value>
        </property>
    
</configuration>

然后使用 xsync 同步到其他服务器

4.4 启动yarn

(1)在 hadoop101中执行:

mark

(2) 在 hadoop102 中执行:

mark

(3)查看服务状态

mark

网页版

mark

可以故意杀掉 101resourcemanager 进程,此时 102resourcemanager 将会自动顶上,感兴趣的可以试试,这里不再赘述

5. HDFS Federation架构设计(了解)

1) NameNode架构的局限性

  1. Namespace(命名空间)的限制
    由于NameNode在内存中存储所有的元数据(metadata),因此单个namenode所能存储的对象(文件+块)数目受到namenode所在JVM的heap size的限制。50G的heap能够存储20亿(200million)个对象,这20亿个对象支持4000个datanode,12PB的存储(假设文件平均大小为40MB)。随着数据的飞速增长,存储的需求也随之增长。单个datanode从4T增长到36T,集群的尺寸增长到8000个datanode。存储的需求从12PB增长到大于100PB。
  2. 隔离问题
    由于HDFS仅有一个namenode,无法隔离各个程序,因此HDFS上的一个实验程序就很有可能影响整个HDFS上运行的程序。
  3. 性能的瓶颈
    ​ 由于是单个namenode的HDFS架构,因此整个HDFS文件系统的吞吐量受限于单个namenode的吞吐量。

2)HDFS Federation架构设计:能不能有多个NameNode?

NameNode NameNode NameNode
元数据 元数据 元数据
Log machine 电商数据/话单数据

简易架构图

mark

3)HDFS Federation应用思考:不同应用可以使用不同NameNode进行数据管理;例如:图片业务、爬虫业务、日志审计业务,而在Hadoop生态系统中,不同的框架使用不同的namenode进行管理namespace(隔离性)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值