Hadoop High Availability

Hadoop High Availability

HA(High Available), 高可用,是保证业务连续性的有效解决方案, 通常通过设置备用节点的方式实现;
一般分为执行业务的称为活动节点(Active),和作为活动节点的一个备份的备用节点(Standby), 当活动节点出现问题, 导致正在运行的业务不能正常运行时, 备用节点此时就会侦测到, 并立即接替活动节点来执行业务, 从而实现业务的不中断或短
暂中断.

NameNode HA

在 Active NN 和 Standby NN 之间设置一个共享的存储日志的地方, Active NN把 edit Log 写到这个共享的存储日志的地方, Standby NN 去读取日志然后执行,这样 Active 和 Standby NN 内存中的 HDFS 元数据保持着同步。一旦发生主从切换 Standby NN 可以尽快接管 Active NN 的工作
hadoop2.x 之后, Clouera 提出了 QJM/Qurom Journal Manager,这是一个基于 Paxos 算法(分布式一致性算法) 实现的 HDFS HA 方案,它给出了一种较好的解决思路和方案,QJM 主要优势如下:
不需要配置额外的高共享存储,降低了复杂度和维护成本。
消除 spof(单点故障)。
系统鲁棒性(Robust)的程度可配置、可扩展。
基本原理就是用 2N+1 台 JournalNode 存储 EditLog,每次写数据操作有>=N+1返回成功时即认为该次写成功,数据不会丢失了。
图片来自网络
其中:

  • JournalNode
    JournalNode 的作用是存储Active NN 的 EditLog, 并供Standby NN读取;
    任何修改操作在 Active NN 上执行时, JournalNode 进程同时也会记录修改log到至少半数以上的 JN 中,这时 Standby NN 监测到 JN 里面的同步 log 发生变化了会读取 JN 里面的修改 log,然后同步到自己的目录镜像树里面,如下图:
    图片来自网络
    当发生故障时, Active 的 NN 挂掉后, Standby NN 会在它成为 Active NN前,读取所有的 JN 里面的修改日志,这样就能高可靠的保证与挂掉的 NN 的目录镜像树一致,然后无缝的接替它的职责,维护来自客户端请求,从而达到一个高可用的目的。
    在 HA 模式下, datanode 需要确保同一时间有且只有一个 NN 能命令 DN。 为此:
    每个 NN 改变状态的时候,向 DN 发送自己的状态和一个序列号。DN 在运行过程中维护此序列号,当 failover 时,新的 NN 在返回 DN 心跳时会返回自己的active 状态和一个更大的序列号。 DN 接收到这个返回则认为该 NN 为新的active。如果这时原来的 active NN 恢复,返回给 DN 的心跳信息包含 active 状态和原来的序列号,这时 DN 就会拒绝这个 NN 的命令。

  • Failover Controller
    FailoverController 部署在每个 NameNode 的节点上,作为一个单独的进程用来监视 NN 的健康状态。 FailoverController主要包括三个组件:
    HealthMonitor: 监控 NameNode 是否处于 unavailable 或 unhealthy 状态。前通过RPC 调用 NN 相应的方法完成。
    ActiveStandbyElector: 监控 NN 在 ZK 中的状态。
    ZKFailoverController: 订阅 HealthMonitor 和 ActiveStandbyElector 的事件,并管理 NN 的状态,另外 zkfc 还负责解决 fencing(也就是脑裂问题)。
    一个典型的 HA 集群,有两个 NN 组成,每个 NN 都有自己的 ZKFC 进程。
    图片源自网络
    ZKFailoverController 主要职责:
    健康监测: 周期性的向它监控的 NN 发送健康探测命令,从而来确定某个NameNode是否处于健康状态,如果机器宕机,心跳失败,那么 zkfc 就会标记它处于一个不健康的状态
    会话管理: 如果 NN 是健康的, zkfc 就会在 zookeeper 中保持一个打开的会话,如果 NameNode 同时还是 Active 状态的,那么 zkfc 还会在 Zookeeper 中占有一个类型为短暂类型的 znode,当这个 NN 挂掉时,这个 znode 将会被删除,然后备用的NN 将会得到这把锁,升级为主 NN,同时标记状态为 Active; 当宕机的 NN 新启动时,它会再次注册 zookeper,发现已经有 znode 锁了,便会自动变为 Standby 状态,如此往复循环,保证高可靠,需要注意, 目前仅仅支持最多配置 2 个 NN
    master 选举: 通过在 zookeeper 中维持一个短暂类型的 znode,来实现抢占式的锁机制,从而判断那个 NameNode 为 Active 状态

Yarn HA

ResourceManager(简写为 RM)作为 Yarn 系统中的主控节点,负责整个系统的资源管理和调度,内部维护了各个应用程序的 ApplictionMaster 信息、NodeManager(简写为 NM)信息、 资源使用等。一旦发生故障,恢复时间较长,且会导致正在运行的 Application 丢失,影响范围较大。
从 Hadoop 2.4.0版本开始, Yarn 实现了 ResourceManager HA,在发生故障时自动 failover, 大大提高了服务的可靠性
由于资源使用情况和 NodeManager 信息都可以通过 NodeManager 的心跳机制重新构建出来,因此只需要对 ApplicationMaster 相关的信息进行持久化存储即可。
在一个典型的 HA 集群中,两台独立的机器被配置成 ResourceManger。在任意时间,有且只允许一个活动的 ResourceManger,另外一个备用。 切换分为两种方式:
手动切换:在自动恢复不可用时,管理员可用手动切换状态,或是从Active 到 Standby,或是从 Standby 到 Active。
自动切换:基于 Zookeeper,但是区别于 HDFS 的 HA, 2 个节点间无需配置额外的 ZFKC守护进程来同步数据。
在这里插入图片描述

Hadoop HA 集群搭建

本次部署3节点Hadoop HA集群

前期准备

三台Linux主机需要:

  1. 修改主机名
    node1, node2, node3

  2. 修改hosts文件配置好主机名与IP地址的映射关系(包括windows主机的hosts文件)

  3. 关闭防火墙
    关闭防火墙: service iptables stop
    关闭防火墙开机自启: chkconfig iptables off

  4. 设置好互相之间的ssh免密登录
    生成密钥:

    ssh-keygen -t rsa
    按四下回车生成密钥

    拷贝公钥到到三台主机(包括自己):

    ssh-copy-id node1
    ssh-copy-id node2
    ssh-copy-id node3

    并使用ssh 主机名命令互相进行登录测试

  5. 同步时区(同步的阿里云)

    yum install -y ntp
    ntpdate ntp6.aliyun.com

  6. 安装好JDK, 配置好环境变量
    (默认已经安装配置)

  7. 安装配置zooekeeper集群
    (默认已经安装配置)

安装配置hadoop集群

  1. 上传并解压 hadoop-2.7.4-with-centos-6.7.tar.gz
    本次解压到了/export/server/下(路径可自定)
    并在/export下创建路径data/hadoopdata

  2. 设置环境变量

    vim /etc/profile

    添加下面内容:

    export HADOOP_HOME=/export/server/hadoop-2.7.4
    export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/sbin
    
    • 1
    • 2

    source /etc/profile

  3. 修改Hadoop配置文件
    Hadoop的配置文件在$HADOOP_HOME/etc/hadoop下

    cd /export/server/hadoop-2.7.4/etc/hadoop

    3.1 修改 hadoop-env.sh

    vim hadoop-env.sh

    配置JAVA_HOME:

    export JAVA_HOME=/export/server/jdk1.8.0_181
    
    • 1

    3.2 修改core-site.xml

    vim core-site.xml

    <configuration>
    <!-- 集群名称在这里指定!该值来自于hdfs-site.xml中的配置 -->
    <property>
    <name>fs.defaultFS</name>
    <value>hdfs://cluster1</value>
    </property>
    <!-- 这里的路径默认是NameNode、DataNode、JournalNode等存放数据的公共目录 -->
    <property>
    <name>hadoop.tmp.dir</name>
    <value>/export/data/hadoopdata</value>
    </property>
    <!-- ZooKeeper集群的地址和端口。注意,数量一定是奇数,且不少于三个节点-->
    <property>
    <name>ha.zookeeper.quorum</name>
    <value>node1:2181,node2:2181,node3:2181</value>
    </property>
    </configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    3.3 修改hdfs-site.xml

    vim hdfs-site.xml

    <configuration>
    <!--指定hdfs的nameservice为cluster1,需要和core-site.xml中的保持一致 -->
    <property>
    <name>dfs.nameservices</name>
    <value>cluster1</value>
    </property>
    <!-- cluster1下面有两个NameNode,分别是nn1,nn2 -->
    <property>
    <name>dfs.ha.namenodes.cluster1</name>
    <value>nn1,nn2</value>
    </property>
    <!-- nn1的RPC通信地址 -->
    <property>
    <name>dfs.namenode.rpc-address.cluster1.nn1</name>
    <value>node1:9000</value>
    </property>
    <!-- nn1的http通信地址 -->
    <property>
    <name>dfs.namenode.http-address.cluster1.nn1</name>
    <value>node1:50070</value>
    </property>
    <!-- nn2的RPC通信地址 -->
    <property>
    <name>dfs.namenode.rpc-address.cluster1.nn2</name>
    <value>node2:9000</value>
    </property>
    <!-- nn2的http通信地址 -->
    <property>
    <name>dfs.namenode.http-address.cluster1.nn2</name>
    <value>node2:50070</value>
    </property>
    <!-- 指定NameNode的edits元数据在JournalNode上的存放位置 -->
    <property>
    <name>dfs.namenode.shared.edits.dir</name>
    <value>qjournal://node1:8485;node2:8485;node3:8485/cluster1</value>
    </property>
    <!-- 指定JournalNode在本地磁盘存放数据的位置 -->
    <property>
    <name>dfs.journalnode.edits.dir</name>
    <value>/export/data/hadoopdata/journaldata</value>
    </property>
    <!-- 开启NameNode失败自动切换 -->
    <property>
    <name>dfs.ha.automatic-failover.enabled</name>
    <value>true</value>
    </property>
    <!-- 指定该集群出故障时,哪个实现类负责执行故障切换 -->
    <property>
    <name>dfs.client.failover.proxy.provider.cluster1</name>
    <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>
    <!-- 配置隔离机制方法,多个机制用换行分割,即每个机制暂用一行-->
    <property>
    <name>dfs.ha.fencing.methods</name>
    <value>
    sshfence
    </value>
    </property>
    <!-- 使用sshfence隔离机制时需要ssh免登陆 -->
    <property>
    <name>dfs.ha.fencing.ssh.private-key-files</name>
    <value>/root/.ssh/id_rsa</value>
    </property>
    <!-- 配置sshfence隔离机制超时时间 -->
    <property>
    <name>dfs.ha.fencing.ssh.connect-timeout</name>
    <value>30000</value>
    </property>
    </configuration>
  4. 3.4 修改mapred-site.xml

    cp mapred-site.xml.template mapred-site.xml
    vim mapred-site.xml

    <configuration>
    <!-- 指定mr框架为yarn方式 -->
    <property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
    </property>
    </configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3.5 修改yarn-site.xml

    vim yarn-site.xml

    <configuration>
    <!-- 开启RM高可用 -->
    <property>
    <name>yarn.resourcemanager.ha.enabled</name>
    <value>true</value>
    </property>
    <!-- 指定RM的cluster id -->
    <property>
    <name>yarn.resourcemanager.cluster-id</name>
    <value>yrc</value>
    </property>
    <!-- 指定RM的名字 -->
    <property>
    <name>yarn.resourcemanager.ha.rm-ids</name>
    <value>rm1,rm2</value>
    </property>
    <!-- 分别指定RM的地址 -->
    <property>
    <name>yarn.resourcemanager.hostname.rm1</name>
    <value>node1</value>
    </property>
    <property>
    <name>yarn.resourcemanager.hostname.rm2</name>
    <value>node2</value>
    </property>
    <!-- 指定zk集群地址 -->
    <property>
    <name>yarn.resourcemanager.zk-address</name>
    <value>node1:2181,node2:2181,node3:2181</value>
    </property>
    <property>
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle</value>
    </property>
    </configuration>
  5. 3.6 修改slaves(slaves是指定子节点的位置)

    vim slaves

    node1
    node2
    node3
    
    • 1
    • 2
    • 3
  6. 将配置好的hadoop拷贝到其他主机

    scp -r /export/server/hadoop-2.7.4 root@node2:/export/server/
    scp -r /export/server/hadoop-2.7.4 root@node3:/export/server/

  7. 格式化及启动
    5.1 首先分别在三台主机上启动zookeeper集群

    /export/server/zookeeper-3.4.7/bin/zkServer.sh start

    查看集群状态:

    /export/server/zookeeper-3.4.7/bin/zkServer.sh status

    一个leader,两个follower, 启动正常

    5.2 分别在三台主机上手动启动journalnode

    hadoop-daemon.sh start journalnode

    运行jps命令检验, node1、node2、node3上多了JournalNode进程

    5.3 格式化namenode
    在node1上执行命令:

    hdfs namenode -format

    格式化后会在根据core-site.xml中的hadoop.tmp.dir配置生成个文件,这里我配置的是/export/data/hadoopdata
    然后将/hadoop/hadoop-2.6.4/tmp拷贝到node2的/export/data/下。

    scp -r /export/data/hadoopdata root@node2:/export/data/

    5.4 格式化ZKFC(在node1上执行即可)

    hdfs zkfc -formatZK

    5.5 启动HDFS(在node1上执行)

    start-dfs.sh

    日志:

    Starting namenodes on [node1 node2]
    node1: starting namenode, logging to /export/server/hadoop-2.7.4/logs/hadoop-root-namenode-node1.out
    node2: starting namenode, logging to /export/server/hadoop-2.7.4/logs/hadoop-root-namenode-node2.out
    node3: starting datanode, logging to /export/server/hadoop-2.7.4/logs/hadoop-root-datanode-node3.out
    node2: starting datanode, logging to www.yongshiyule178.com  /export/server/hadoop-2.7.4/logs/hadoop-root-datanode-node2.out
    node1: starting datanode, logging to www.fengshen157.com/ /export/server/hadoop-2.7.4/logs/hadoop-root-datanode-node1.out
    Starting journal nodes [node1 node2 node3]
    node3: journalnode running as process 2804. Stop it first.
    node2: journalnode running www.thd540.com as process 2998. Stop it first.
    node1: journalnode running as process www.dfgjpt.com/ 4281. Stop it first.
    Starting ZK Failover Controllers on NN hosts [node1 node2]
    node1: starting zkfc, logging to /export/server/hadoop-2.7.4/logs/hadoop-root-zkfc-node1.out
    node2: starting zkfc, logging to /export/server/hadoop-2.7.4/logs/hadoop-root-zkfc-node2.ou
  8. 可以看到在
    node1上启动了namenode, datanode, journalnode, zkfc
    node2上启动的有namenode, datanode, journalnode, zkfc
    node3上启动的有datanode, journalnode

    5.6 启动yarn
    在node1上执行:

    start-yarn.sh

    日志:

    starting yarn daemons
    starting resourcemanager, logging to /export/server/hadoop-2.7.4/logs/yarn-root-resourcemanager-node1.out
    node3: starting nodemanager, logging to /export/server/hadoop-2.7.4/logs/yarn-root-nodemanager-node3.out
    node2: starting nodemanager, logging to /export/server/hadoop-2.7.4/logs/yarn-root-nodemanager-node2.out
    node1: starting nodemanager, logging to /export/server/hadoop-2.7.4/logs/yarn-root-nodemanager-node1.out
  9. 还有一个备用节点启动yarn,在node2上执行:

    yarn-daemon.sh start resourcemanager

    日志:

    starting resourcemanager, logging to /export/server/hadoop-2.7.4/logs/yarn-root-resourcemanager-node2.out
    
    • 1

    5.7 运行jps命令检验进程
    node1:

     2402 QuorumPeerMain
     8243 ResourceManager
     8360 NodeManager
     4281 JournalNode
     7673 DataNode
     9930 Jps
     7530 NameNode
     8076 DFSZKFailoverController
  10. node2:

     5168 Jps
     3696 DFSZKFailoverController
     3540 DataNode
     3477 NameNode
     2998 JournalNode
     2059 QuorumPeerMain
     3773 NodeManager
     4670 ResourceManage
  11. node3:

     2049 QuorumPeerMain
     2804 JournalNode
     4341 Jps
     4073 DataNode
     4201 NodeManager
  12. 启动正常!

  13. 验证HDFS HA

    首先向hdfs上传一个文件

    hadoop fs -put /root/1.txt /

    查看

    hadoop fs -ls /

    -rw-r--r-- 3 root supergroup 1 2018-09-22 14:39 /1.txt

--------------------- 作者:微信用户_43167990 来源:CSDN 原文:https://blog.csdn.net/weixin_43167990/article/details/82821136?utm_source=copy 版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自www.cnblogs.com/qwangxiao/p/9765768.html