Hadoop学习(十一)——hadoop下的HA机制

笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值,找寻数据的秘密,笔者认为,数据的价值不仅仅只体现在企业中,个人也可以体会到数据的魅力,用技术力量探索行为密码,让大数据助跑每一个人,欢迎直筒们关注我的公众号,大家一起讨论数据中的那些有趣的事情。

我的公众号为:livandata

前言:正式引入HA机制是从hadoop2.0开始,之前的版本中没有HA机制。

1.1 HA的运作机制

(1)hadoop-HA集群运作机制介绍

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

实现高可用最关键的是消除单点故障

hadoop-ha严格来说应该分成各个组件的HA机制——HDFS的HA、YARN的HA

(2)HDFS的HA机制详解

通过双namenode消除单点故障

双namenode协调工作的要点:

    A、元数据管理方式需要改变:

    内存中各自保存一份元数据

    Edits日志只能有一份,只有Active状态的namenode节点可以做写操作

    两个namenode都可以读取edits

    共享的edits放在一个共享存储中管理(qjournal和NFS两个主流实现)

    B、需要一个状态管理功能模块

    实现了一个zkfailover,常驻在每一个namenode所在的节点

    每一个zkfailover负责监控自己所在namenode节点,利用zk进行状态标识

    当需要进行状态切换时,由zkfailover来负责切换

    切换时需要防止brain split现象的发生

1.2 HDFS-HA图解:

常用的架构为:

Fsnamesystem:内存结构,主要用来进行数据运算;

Fsimage:用于持久化存储的空间;

Edits:更新操作;

1)当客户端要做数据操作时,导致原数据要发生变化,此时这些操作会先记录在日志里面,操作成功了再进入到内存中;

2)此时,edits中的内容与fsimage中的内容便不一致,此时snn就会出场,他隔一段时间 就会将nn中的edits与fsimage下载下来,然后合并成一个文件,再形成一个全面的fsimage文件,然后替换掉nn中的fsimage;

此时存在一个问题,一旦nn宕机,便不会对外提供服务了,可用性比较低;

如何做成高可用:

需要将nn复制一个出来,做成双活机制,然后用keepalived做监视;

服务器通过将自身的IP,绑定到可用的服务器的网卡上,以实现服务器的可用性,对外提供同一的IP,对内不停的更换,保证有持续的服务器可用;

但有个问题,这样的操作,很难实现多个服务器的状态同步的问题,因为多个服务器之间没有数据同步;

因此需要更好的方法来实现:

即使用一个第三方来进行协调:

Nn的操作流程是先到edits中,记录操作日志,然后再在内存中按照edits中的操作步骤实现一步步的操作,然后存储在fsimage中:

 

Edits是一些小文件,因此,可以将一些edits拿出来放在一个第三方中,然后多个nn到第三方去取,snn从第三方中取下来进行同步操作,此时,多个服务器之间只差一条记录,即正在写的那条记录;

 

但如果这个第三方挂掉,也会存在问题,此时需要第三方也是高可用,因此需要第三方也是一个多台服务器的集群,每台服务器都保留edits内容,

有公司为这个系统开发了一个qjournal系统,专门进行高可用的第三方系统,即zookeeper的集群,挂掉其中一台也没有影响,此时可用性很高,但是数据一致性变差了;

其功能即为edits日志管理;

分布式数据库中存在一个三角形:

可用性、可靠性和数据一致性三者未必能够统一,会存在一定的处理;

Zookeeper中是协调用的,主要是对不同的服务器进行处理,但是不存储服务器中的内容,上面的edits日志管理部署时需要有个zookeeper集群,用zk来进行分布式管理,edits不会存在zk中,zk只是作为机器协调、分布式锁、上下线动态感知等功能;

步骤:

1)  当客户端进行数据操作时,通过一个线程池,同步存储操作步骤到本地的edits和远端的edits中,在远端由于需要多台服务器同时写入,因此只要多数台写入成功就可以;

2)  edits与standby的状态需要一个人来管理,谁是主,谁是从,谁出了问题,谁来切换,感知这些的进程,每一台nn中写一个程序,这个程序专门来进行状态管理,这个程序叫zkfc,是做失败切换的,这个zkfc也是用zk的,主要是用rpc的接口去掉用服务器,如果调用不返回则表示nn死了,返回表示正常;

3)  一旦zkfc发现nn死了,他就会通知zk,zk会删掉nn的节点,另外一个zkfc在监控这个节点,这个节点删除后,snn上的zkfc就会启动snn,让snn成为active状态,如果切换成功,standby就会变成active,同时在zk中建立一个锁,进行监控;

4)  有时服务器中会存在炸死,即nn有可能暂时死掉,一段时间后又活过来了,就会存在两个active,为防止这种情况发生,zkfc会在启动snn之前会丢出一个命令,干死nn;

5)  Zkfc为了让对方死透,如果第四步中丢出命令,长时间没有返回值,可以自定义一个脚本,脚本返回一个值给zkfc,则表示已经杀死了,zkfc放心开始切换。

上面即为hdfs的高可用,接下来有yarn的高可用:

Yarn如果死了,可以直接重启,高可用不是那么迫切:

1)  主要是在zk中注册一把锁,各注册一个节点,如果其中一个死了,则可以直接启动后面的yarn;

当数据量比较大,文件较多时,nn中的内存有可能不够用,此时需要一个新的机制:

Namenode容量的水平扩展,即同时多个对外提供服务,而且两个持有不同的数据:

此时具体的步骤为:

1)  分目录:第一个服务器中为/janpan/;第二个服务器中为/art-x/,如果没有则报错;此时的nn就会变成federation(联邦),这两个服务器也存在主备之分;

此时客户端访问时该访问谁:此时两个nn会有一个逻辑名称,叫名称服务nameservice,一对nn有一个逻辑名称,叫ns1,这个逻辑名称下包含两个nn,客户端api可以通过配置文件知道这个名字下有娜两台namenode,并且通过查看zk,可以知道哪台是active;

此时在访问nn时,就可以找到对应的ns1名称:

假设hdfs://ns 1和hdfs://ns2为内存组的名称,可以将他们作为各个内存组的名称,然后再在他们的上级,即根目录的位置设立访问路径:

Viewfs://japanese即访问hdfs://ns1;

Viewfs://art-x即访问hdfs://ns2;

Datanode没比较分开,可以实现公用,在联邦机制下,两个namenode的clusterID必须一样,这样可以共享DataNode,dn中每台机器就会有两个block块的目录,一个目录为ns1,另一个目录为ns2;

当存在active和standby只有,就没有snn这个结构了;

Namenode的safemode是什么?

一个集群刚起时经常看到,namenode中记录了元数据,即块的信息(块的ID、副本数量等信息),但是他的镜像(fsimage)中只记录了blockID,而block真正的业务信息都在datanode中,他们持有block块,刚启动集群的时候namenode中是没有块信息的,启动时,datanode就会向namenode汇报,汇报自身有哪些数据块,当有些datanode还没有汇报完成的时候,namenode就会进入到safemode模式,等所有datanode汇报结束后,再结束safemode模式;

如何调用HA的机制:

1.2  HA集群的安装部署

1.2.1 集群节点规划                                 

集群部署节点角色的规划(10节点):

server01   namenode   zkfc    > start-dfs.sh

server02   namenode   zkfc

 

server03   resourcemanager    > start-yarn.sh

server04   resourcemanager

 

server05   datanode   nodemanager    

server06   datanode   nodemanager    

server07   datanode   nodemanager    

 

server08   journal node    zookeeper

server09   journal node    zookeeper

server10   journal node    zookeeper

集群部署节点角色的规划(3节点)

server01   namenode    resourcemanager  zkfc   nodemanager  datanode   zookeeper   journal node

server02   namenode    resourcemanager  zkfc   nodemanager  datanode   zookeeper   journal node

server05   datanode    nodemanager     zookeeper    journal node

1.2.2 环境准备

1、环境准备

a/linux系统准备

    ip地址配置

    hostname配置

    hosts映射配置

    防火墙关闭

init启动级别修改

sudoers加入hadoop用户

ssh免密登陆配置

b/java环境的配置

上传jdk,解压,修改/etc/profile

c/zookeeper集群的部署

1.2.3 配置文件

core-site.xml

                <configuration>

                    <!-- 指定hdfs的nameservice为ns1 -->

                    <property>

                        <name>fs.defaultFS</name>

                        <value>hdfs://ns1/</value>

                    </property>

                    <!-- 指定hadoop临时目录 -->

                    <property>

                        <name>hadoop.tmp.dir</name>

                        <value>/home/hadoop/app/hadoop-2.4.1/tmp</value>

                    </property>

                   

                    <!-- 指定zookeeper地址 -->

                    <property>

                        <name>ha.zookeeper.quorum</name>

                        <value>weekend05:2181,weekend06:2181,weekend07:2181</value>

                    </property>

                </configuration>

hdfs-site.xml

configuration>

<!--指定hdfs的nameservice为ns1,需要和core-site.xml中的保持一致 -->

<property>

    <name>dfs.nameservices</name>

    <value>ns1</value>

</property>

<!-- ns1下面有两个NameNode,分别是nn1,nn2 -->

<property>

    <name>dfs.ha.namenodes.ns1</name>

    <value>nn1,nn2</value>

</property>

<!-- nn1的RPC通信地址 -->

<property>

    <name>dfs.namenode.rpc-address.ns1.nn1</name>

    <value>weekend01:9000</value>

</property>

<!-- nn1的http通信地址 -->

<property>

    <name>dfs.namenode.http-address.ns1.nn1</name>

    <value>weekend01:50070</value>

</property>

<!-- nn2的RPC通信地址 -->

<property>

    <name>dfs.namenode.rpc-address.ns1.nn2</name>

    <value>weekend02:9000</value>

</property>

<!-- nn2的http通信地址 -->

<property>

    <name>dfs.namenode.http-address.ns1.nn2</name>

    <value>weekend02:50070</value>

</property>

<!-- 指定NameNode的edits元数据在JournalNode上的存放位置 -->

<property>

    <name>dfs.namenode.shared.edits.dir</name>

    <value>qjournal://weekend05:8485;weekend06:8485;weekend07:8485/ns1</value>

</property>

<!-- 指定JournalNode在本地磁盘存放数据的位置 -->

<property>

    <name>dfs.journalnode.edits.dir</name>

    <value>/home/hadoop/app/hadoop-2.4.1/journaldata</value>

</property>

<!-- 开启NameNode失败自动切换 -->

<property>

    <name>dfs.ha.automatic-failover.enabled</name>

    <value>true</value>

</property>

<!-- 配置失败自动切换实现方式 -->

<property>

    <name>dfs.client.failover.proxy.provider.ns1</name>

    <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>

</property>

<!-- 配置隔离机制方法,多个机制用换行分割,即每个机制暂用一行-->

<property>

    <name>dfs.ha.fencing.methods</name>

    <value>

        sshfence

        shell(/bin/true)

    </value>

</property>

<!-- 使用sshfence隔离机制时需要ssh免登陆 -->

<property>

    <name>dfs.ha.fencing.ssh.private-key-files</name>

    <value>/home/hadoop/.ssh/id_rsa</value>

</property>

<!-- 配置sshfence隔离机制超时时间 -->

<property>

    <name>dfs.ha.fencing.ssh.connect-timeout</name>

    <value>30000</value>

</property>

/configuration>

1.2.4 集群运维测试

1、Datanode动态上下线

Datanode动态上下线很简单,步骤如下:

a)  准备一台服务器,设置好环境

b)  部署hadoop的安装包,并同步集群配置

c)  联网上线,新datanode会自动加入集群

d)  如果是一次增加大批datanode,还应该做集群负载重均衡

2、Namenode状态切换管理

使用的命令上hdfs  haadmin

可用 hdfs  haadmin –help查看所有帮助信息

可以看到,状态操作的命令示例:

查看namenode工作状态  

hdfs haadmin -getServiceState nn1

将standby状态namenode切换到active

hdfs haadmin –transitionToActive nn1

将active状态namenode切换到standby

hdfs haadmin –transitionToStandby nn2

3、数据块的balance

启动balancer的命令:

start-balancer.sh-threshold 8

运行之后,会有Balancer进程出现:

上述命令设置了Threshold为8%,那么执行balancer命令的时候,首先统计所有DataNode的磁盘利用率的均值,然后判断如果某一个DataNode的磁盘利用率超过这个均值Threshold,那么将会把这个DataNode的block转移到磁盘利用率低的DataNode,这对于新节点的加入来说十分有用。Threshold的值为1到100之间,不显示的进行参数设置的话,默认是10。

1.2.5 HA下hdfs-api变化

客户端需要nameservice的配置信息,其他不变

/**

 * 如果访问的是一个ha机制的集群

 * 则一定要把core-site.xml和hdfs-site.xml配置文件放在客户端程序的classpath下

 * 以让客户端能够理解hdfs://ns1/中  “ns1”是一个ha机制中的namenode对——nameservice

 * 以及知道ns1下具体的namenode通信地址

 * @author

 *

 */

public class UploadFile {

         public static void main(String[] args) throws Exception  {

                   Configuration conf = new Configuration();

                   conf.set("fs.defaultFS", "hdfs://ns1/");

                   FileSystem fs = FileSystem.get(new URI("hdfs://ns1/"),conf,"hadoop");

                   fs.copyFromLocalFile(new Path("g:/eclipse-jee-luna-SR1-linux-gtk.tar.gz"), new Path("hdfs://ns1/"));

                   fs.close();

         }

}

Federation下 mr程序运行的staging提交目录问题

<property>

 <name>yarn.app.mapreduce.am.staging-dir</name>

 <value>/bi/tmp/hadoop-yarn/staging</value>

  <description>The staging dir used whilesubmitting jobs.

  </description>

</property>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值