大数据基础学习-3.Hadoop2.0、Yarn

在Hadoop1.0中JobTracker必须不断跟踪和监控所有TaskTracker和所有map、 reduce任务,TaskTracker上的任务都是JobTracker来分配的,因此JobTracker的权限非常大,节点的压力也很大。

在Hadoop2.0中减少了单个JobTracker的职责,将部分职责委派给TaskTracker,因为集群中有许多TaskTracker。在新设计中,这个概念通过将 JobTracker 的双重职责(集群资源管理任务监督)分开为两种不同类型的进程(RM和AM)。因此集群中不再拥有JobTracker,而是引入集群管理器(RM),负责跟踪集群中的活动节点和可用资源,并给它们分配任务。并且对于提交给集群的每个作业,会启动一个专用的、短暂的 JobTracker(AM)来控制该作业中任务的执行,这个AM由从节点上运行的 TaskTracker 来启动。接下来先通过对yarn的学习,来理解Hadoop2.0的新特性。

一、Yarn基础

1.Yarn概述


在Hadoop2.0中增加了Yarn,Yarn是Hadoop集群的资源管理系统,负责集群的资源管理和调度,为应用程序提供了基础服务来更好地利用大的、动态的、并行的基础设施资源,使得多种计算框架可以运行在一个集群中。【Hadoop2.0对MapReduce框架做了彻底的重构,MapReduce成为MRv2,成为了Yarn上的1个插件】Yarn中,Job的概念换成了application。

• 特点:

– 良好的扩展性(其他应用程序作为插件)、高可用(利用zookeeper避免了单点故障)

– 自带了多种用户调度器,适合共享集群环境

– 相比传统模式,提高了资源利用率、降低运维成本和数据共享成本

扫描二维码关注公众号,回复: 1072915 查看本文章

2.Yarn架构


Yarn有3个关键进程:ResourceManager、ApplicationMaster和NodeManager。

• ResourceManager(RM) 代替JobTracker的集群资源管理功能。

• ApplicationMaster(AM) 代替JobTracker的集群任务管理功能。

• NodeManager(NM)      代替TaskTracker。

• 重构的根本思想:将 JobTracker 两个主要的功能分离成单独的组件,这两个功能是资源管理(RM)和任务调度 / 监控(AM),这样从节点上进行的任务就不用再向主节点汇报,直接向AM节点汇报即可,将集群的负载平均化,减小主节点的压力。

3.ResourceManager

ResourceManager是全局的资源管理器,整个集群只有一个,负责集群资源的统一管理和调度分配。

• RM处理客户端请求,接收JobSubmitter提交的作业,按照作业的上下文(Context) 信息,以及从 NodeManager(NM)收集来的状态信息,启动调度过程,分配一个Container作为ApplicationMaster。

• RM拥有为系统中所有应用分配资源的决定权,是中心服务,做的事情就是调度、启动每一个Job所属的Application,另外监控Application的运行情况。

• RM与运行在每个节点上的NM进程交互,通过心跳通信,达到监控NM的目的。但是RM不负责应用程序的监控和状态跟踪,不保证应用程序失败或者硬件失败的情况下对Task的重启。

【注:在hadoop2.4之后,支持RM的高可用】

4.NodeManager

NodeManager是slave进程,类似TaskTracker的角色,是每个机器的框架代理,在单节点上进行资源管理和任务管理,处理来自RM的任务请求。

• NM接收并处理来自ApplicationMaster的Container启动、停止等各种请求。

• 负责启动应用程序的Container(执行应用程序的容器),并监控他们的资源使用情况(CPU、内存、磁盘和网络),并报告给RM。

5.Application Master

ApplicationMaster是应用程序的管理者,每一个Job都有一个AM,运行在RM以外的机器上,在用户提交一个应用程序时,一个AM的轻量型进程实例会启动,AM负责一个Job生命周期内的所有工作,类似Hadoop1.0中的JobTracker,AM的生命周期即这个Job的生命周期。

• AM向RM请求资源,RM再与Scheduler协商,选择合适的Container。

• 与NM协同工作,与Scheduler协商合适的Container运行job,并对这些Container进行监控。

• AM本质上也是一个Container,管理着其他Container。

6.Container

Container是任务运行环境的抽象封装,描述任务的运行资源(内存、cpu、节点)、启动命令和运行环境,实际的job就是运行在Container所指定的资源中。Container由Nodemanager启动。AM必须向NM提供更多的信息来启动Container,Container中运行的可能是map也可能是reduce。Container需要和AM通信,报告任务情况。

7.Yarn框架对于旧的MapReduce框架的优势

• 减小了 JobTracker(也就是现在的 RM)的资源消耗,并且让监测每一个 Job子任务 (tasks) 状态的程序分布式化了,更安全、更优美,在老的框架中,JobTracker 一个很大的负担就是监控 job 下的 tasks 的运行状况,现在这个部分扔给ApplicationMaster。

• AM是一个可变更的部分,允许多类型的编程模型运行在 Hadoop 集群中,用户可以编写自己的 AM

• Hadoop1.0中资源以剩余 slot 数目表示,Hadoop2.0中资源的表示以内存为单位,资源表示成内存量,就没有了 map slot/reduce slot 分开造成集群资源闲置的尴尬情况。

二、Yarn深入

1.运行过程

• Client请求Resource Manager运行一个Application Master实例(step 1);

• ResourceManager选择一个NodeManager,启动一个Container并运行Application Master实例(step 2a、 step 2b);

• ApplicationMaster根据实际需要向ResourceManager请求更多的Container资源(step 3);

• ApplicationMaster通过获取到的Container资源执行分布式计算(step 4a、 step 4b)。

2.Yarn容错能力

• RM挂掉:单点故障,可以基于Zookeeper实现HA高可用集群,通过配置设置主RM和备用RM,主RM提供服务,备用RM同步主RM的信息,一旦主RM挂掉,备用RM立即做切换,接替主RM进行服务。

• NM挂掉:当一个挂了,会通过心跳方式通知RM,RM将情况通知对应AM,AM作进一步处理。

• AM挂掉:RM负责重启,其实RM上有一个RMApplicationMaster,是AM的AM,上面保存着已经完成的task信息,若重启AM,无需重新运行已经完成的task。

3.Schedule

Schedule是Yarn的可插拔资源调度器,可以简单快速地切换调度形式,负责给运行的各种应用分配资源(即分配Container),但是不负责应用程序的监控和状态监督。主要有3种资源调度方式。

• FIFO Scheduler:按提交顺序,最简单,大应用占用所有集群资源,会导致小应用必须等待大应用的结束,不适合共享集群。

• Capacity Scheduler:有专门的队列运行小任务,预先占一定集群资源,导致大任务执行时间落后于FIFO。

• Fair Scheduler:不需要预占,动态调整,公平共享,某个任务一旦完成就会释放资源给其他任务。

三、Hadoop2.0

1.Hadoop2.0的新特性

• NameNode HA,解决了namenode的单点故障问题

• NameNode Federation,采用多个namenode共同管理HDFS,解决了namenode扩展受限的问题。

• HDFS 快照

• HDFS 缓存

• HDFS ACL

• 异构层级存储结构

2.NameNode HA

• Hadoop 1.0中NameNode在整个HDFS中只有一个,存在单点故障风险,一旦NameNode挂掉,整个集群无法使用,HDFS的高可用通过在同一个集群中运行两个NameNode(active NameNode & standbyNameNode )来解决。

• 在任何时间,只有一台namenode机器处于Active状态;另一台namenode机器是处于Standby状态。

• Active NN负责集群中所有客户端的操作;Standby NN用于备用,可以提供快速的故障恢复。Standby NN需要与 Active NN保持同步,JournalNodes(JN)负责命名空间同步,DN负责数据同步,这两个保证了Standby NN与Active NN保持一致。任何情况下,NameNode只有一个Active状态,否则会导致数据的丢失及其它不正确的结果,JNs只允许一个 NN充当writer。在故障恢复期间,将要变成Active 状态的NN将取得writer的角色,并阻止另外一个NN继续处于Active状态。


• Active NN和Standby NN同步机制

转:https://blog.csdn.net/carl810224/article/details/52160418

基于QJM的HDFS HA方案如上图所示,其处理流程为:集群启动后一个NameNode处于Active状态,并提供服务,处理客户端和DataNode的请求,并把editlog写到本地和share editlog(这里是QJM)中。另外一个NameNode处于Standby状态,它启动的时候加载fsimage,然后周期性的从share editlog中获取editlog,保持与Active节点的状态同步。为了实现Standby在Active挂掉后迅速提供服务,需要DataNode同时向两个NameNode汇报,使得Stadnby保存block to DataNode信息,因为NameNode启动中最费时的工作是处理所有DataNode的blockreport,DN向两个NN同时汇报,是在block-DataNode层面,还需要JN保持文件名-block的同步。为了实现热备,增加FailoverController和Zookeeper,FailoverController与Zookeeper通信,通过Zookeeper选举机制,FailoverController通过RPC让NameNode转换为Active或Standby。

• HDFS的自动故障转移主要由Zookeeper和ZKFC两个组件组成。

Zookeeper集群作用主要有:一是故障监控。每个NameNode将会和Zookeeper建立一个持久session,如果NameNode失效,那么此session将会过期失效,此后Zookeeper将会通知另一个Namenode,然后触发Failover;二是NameNode选举。ZooKeeper提供了简单的机制来实现Acitve Node选举,如果当前Active失效,Standby将会获取一个特定的排他锁,那么获取锁的Node接下来将会成为Active。

ZKFC是一个Zookeeper的客户端,它主要用来监测和管理NameNodes的状态,每个NameNode机器上都会运行一个ZKFC程序,它的职责主要有:一是健康监控。ZKFC间歇性的ping NameNode,得到NameNode返回状态,如果NameNode失效或者不健康,那么ZKFS将会标记其为不健康;二是Zookeeper会话管理。当本地NaneNode运行良好时,ZKFC将会持有一个Zookeeper session,如果本地NameNode为Active,它同时也持有一个“排他锁”znode,如果session过期,那么持lock锁对应的znode也将被删除;三是选举。当集群中其中一个NameNode宕机,Zookeeper会自动将另一个激活。

• QJM

Hadoop 2.0官方提供了两种HDFS HA的解决方案,一种是NFS(成本高),另一种是QJM。

最低法定人数管理机制,原理:用2n+1台JN机器存储editlog,每次写数据操作,如果大多数(>=n+1)返回成功,就会认为该次写成功。QJM本质也是一个小集群,QJM的好处:

  (1)不需要额外配置共享存储,降低了复杂度、维护成本(相比NFS)

  (2)没有单点问题

  (3)JN不会因为某一个台机器延迟,影响整体的延迟,也不会因为JN的数量增多而影响性能(NN向JN发送的日志是并行的)

   (4)只需要系统配置就可以完成

• 节点配置

– NameNode machines:运行Active NN和Standby NN的机器需要相同的硬件配置

– JournalNode machines:也就是运行JN的机器。 JN守护进程相对来说比较轻量,所以这些守护进程可以和其他守护线程(比如NN,Yarn ResourceManager)运行在同一台机器上,在一个集群中,最少要运行3个JN守护进程,这将使得系统有一定的容错能力。

• 在HA集群中,Standby NN也执行namespace状态的checkpoints,作用和secondary namenode相似,所以不必要运行Secondary NN、CheckpointNode和BackupNode;事实上,运行这些守护进程是错误的。

• HA配置

参考:https://blog.csdn.net/w13770269691/article/details/24457241

YARN的ResourceManager也存在单点故障问题,这个问题在hadoop-2.4.1得到了解决:有两个ResourceManager,一个是Active,一个是Standby,状态由zookeeper进行协调。YARN的HA架构和HDFSHA类似,需要启动两个ResourceManager,这两个ResourceManager会向ZooKeeper集群注册,通过ZooKeeper管理它们的状态(Active或Standby)并进行自动故障转移。所以Zookeeper的作用是负责HDFS中NameNode主备节点的选举,和YARN框架下ResourceManaer主备节点的选举。


节点规划:

主机名 IP地址 安装的软件 JPS
masteractive 192.168101.101         jdk/hadoop/zk
Namenode/zkfc/resourcemanager/JobHistoryServer
/WebProxyServer
masterstandby 192.168101.102 jdk/hadoop/zk

Namenode/zkfc/resourcemanager/Datanode/nodemanager

/journalnode/quorumPeerMain

slave1 192.168101.103 jdk/hadoop/zk
Datanode/journalnode/nodemanager/quorumPeerMain
slave2 192.168101.104 jdk/hadoop/zk
Datanode/journalnode/nodemanager/quorumPeerMain

• 集群时间同步

如果集群节点时间不同步,可能会出现节点宕机或引发其它异常问题,所以在生产环境中一般通过配置NTP服务器实现集群时间同步。这个对于HA的关系不是很大,但是在执行作业时,就会有影响。所以在这里一并配置好。

参考:https://www.cnblogs.com/zjp719325616/p/6530705.html

• 安装zookeeper

可以先学习大数据基础学习-zookeeper博客内容后,再接下去。

https://blog.csdn.net/qq_25560849/article/details/80087097

安装好zookeeper-3.4.5-cdh5.7.0,配置~/.bashrc,再source生效一下。

export ZOOKEEPER_HOME=/usr/local/src/zookeeper-3.4.5-cdh5.7.0
export PATH=$PATH:$ZOOKEEPER_HOME/bin

进入conf目录,对zoo.cfg进行配置,增加如下的内容。

dataDir=/usr/local/src/zookeeper-3.4.5-cdh5.7.0/data
dataLogDir=/usr/local/src/zookeeper-3.4.5-cdh5.7.0/data/log
server.1=masterstandby:2888:3888
server.2=slave1:2888:3888
server.3=slave2:2888:3888

创建data和log目录

# mkdir -p data/log

在data目录下,创建myid文件,并根据不同的节点,写入不同的数字,数字的值即zoo.cfg中server.后面跟的值。

修改zookeeper的日志输出路径

if [ "x${ZOO_LOG_DIR}" = "x" ]
then
   ZOO_LOG_DIR="$ZOOKEEPER_HOME/logs"
fi
if [ "x${ZOO_LOG4J_PROP}" = "x" ]
then
   ZOO_LOG4J_PROP="INFO,ROLLINGFILE"
fi

修改zookeeper的日志配置文件

# vim conf/log4j.properties
zookeeper.root.logger=INFO,ROLLINGFILE

创建日志目录

# mkdir logs

将zookeeper分发到masterstandby、slave1和slave2节点上,并修改myid和配置~/.bashrc,最后在masterstandby、slave1和slave2节点上启动zookeeper。一定要检查zookeeper的状态。

[root@masterstandby data]# zkServer.sh status

这时候会有1个leader和2个follower。如果出现问题,查看是否已经正确关闭防火墙。

• 配置Hadoop文件

首先创建几个文件夹,这在配置中会提到。

$ mkdir -p data/tmp
$ mkdir -p data/journal
$ mkdir -p data/namenode
$ mkdir -p data/datanode

1)core-site.xml

<configuration>
    <!-- 指定hdfs的nameservices名称为mycluster,与hdfs-site.xml的HA配置相同 -->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://mycluster</value>
    </property> 
    <!-- 指定缓存文件存储的路径 -->
    <property>
        <name>hadoop.tmp.dir</name> 
        <value>/usr/local/src/hadoop-2.6.0-cdh5.7.0/data/tmp</value>
    </property> 
    <!-- 配置hdfs文件被永久删除前保留的时间(单位:分钟),默认值为0表明垃圾回收站功能关闭 -->
    <property> 
        <name>fs.trash.interval</name> 
        <value>1440</value> 
    </property> 
    <!-- 指定zookeeper地址,配置HA时需要 -->
    <property>
    	<name>ha.zookeeper.quorum</name> 
	<value>masterstandby:2181,slave1:2181,slave2:2181</value>
    </property>
</configuration>

2)hdfs-site.xml

<configuration>  
  <!-- 指定hdfs元数据存储的路径 -->  
  <property>  
    <name>dfs.namenode.name.dir</name>  
    <value>/usr/local/src/hadoop-2.6.0-cdh5.7.0/data/namenode</value>  
  </property>  
  
  <!-- 指定hdfs数据存储的路径 -->  
  <property>  
    <name>dfs.datanode.data.dir</name>  
    <value>/usr/local/src/hadoop-2.6.0-cdh5.7.0/data/datanode</value>  
  </property>  
    
  <!-- 数据备份的个数 -->  
  <property>  
    <name>dfs.replication</name>  
    <value>3</value>  
  </property>  
  
  <!-- 关闭权限验证 -->  
  <property>  
    <name>dfs.permissions.enabled</name>  
    <value>false</value>  
  </property>  
    
  <!-- 开启WebHDFS功能(基于REST的接口服务) -->  
  <property>  
    <name>dfs.webhdfs.enabled</name>  
    <value>true</value>  
  </property>  
    
  <!-- //////////////以下为HDFS HA的配置////////////// -->  
  <!-- 指定hdfs的nameservices名称为mycluster -->  
  <property>  
    <name>dfs.nameservices</name>  
    <value>mycluster</value>  
  </property>  
  
  <!-- 指定mycluster的两个namenode的名称分别为nn1,nn2 -->  
  <property>  
    <name>dfs.ha.namenodes.mycluster</name>  
    <value>nn1,nn2</value>  
  </property>  
  
  <!-- 配置nn1,nn2的rpc通信端口 -->  
  <property>  
    <name>dfs.namenode.rpc-address.mycluster.nn1</name>  
    <value>masteractive:9000</value>  
  </property>  
  <property>  
    <name>dfs.namenode.rpc-address.mycluster.nn2</name>  
    <value>masterstandby:9000</value>  
  </property>  
  
  <!-- 配置nn1,nn2的http通信端口 -->  
  <property>  
    <name>dfs.namenode.http-address.mycluster.nn1</name>  
    <value>masteractive:50070</value>  
  </property>  
  <property>  
    <name>dfs.namenode.http-address.mycluster.nn2</name>  
    <value>masterstandby:50070</value>  
  </property>  
  
  <!-- 指定namenode元数据存储在journalnode中的路径 -->  
  <property>  
    <name>dfs.namenode.shared.edits.dir</name>  
    <value>qjournal://masterstandby:8485;slave1:8485;slave2:8485/mycluster</value>  
  </property>  
    
  <!-- 指定journalnode日志文件存储的路径 -->  
  <property>  
    <name>dfs.journalnode.edits.dir</name>  
    <value>/usr/local/src/hadoop-2.6.0-cdh5.7.0/data/journal</value>  
  </property>  
  
  <!-- 指定HDFS客户端连接active namenode的java类 -->  
  <property>  
    <name>dfs.client.failover.proxy.provider.mycluster</name>  
    <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>  
  </property>  
  
  <!-- 配置隔离机制为ssh -->  
  <property>  
    <name>dfs.ha.fencing.methods</name>  
    <value>sshfence</value>  
  </property>  
  
  <!-- 指定秘钥的位置 -->  
  <property>  
    <name>dfs.ha.fencing.ssh.private-key-files</name>  
    <value>/root/.ssh/id_rsa</value>  
  </property>  
    
  <!-- 开启自动故障转移 -->  
  <property>  
    <name>dfs.ha.automatic-failover.enabled</name>  
    <value>true</value>  
  </property>  
</configuration>

3)mapred-site.xml

<configuration>  
  <!-- 指定MapReduce计算框架使用YARN -->  
  <property>  
    <name>mapreduce.framework.name</name>  
    <value>yarn</value>  
  </property>  
  
  <!-- 指定jobhistory server的rpc地址 -->  
  <property>  
    <name>mapreduce.jobhistory.address</name>  
    <value>masteractive:10020</value>  
  </property>  
  
  <!-- 指定jobhistory server的http地址 -->  
  <property>  
    <name>mapreduce.jobhistory.webapp.address</name>  
    <value>masteractive:19888</value>  
  </property>  
  
  <!-- 开启uber模式(针对小作业的优化) -->  
  <property>  
    <name>mapreduce.job.ubertask.enable</name>  
    <value>true</value>  
  </property>  
  
  <!-- 配置启动uber模式的最大map数 -->  
  <property>  
    <name>mapreduce.job.ubertask.maxmaps</name>  
    <value>9</value>  
  </property>  
  
  <!-- 配置启动uber模式的最大reduce数 -->  
  <property>  
    <name>mapreduce.job.ubertask.maxreduces</name>  
    <value>1</value>  
  </property>  
</configuration>

4)yarn-site.xml

<configuration>  
  <!-- NodeManager上运行的附属服务,需配置成mapreduce_shuffle才可运行MapReduce程序 -->  
  <property>  
    <name>yarn.nodemanager.aux-services</name>  
    <value>mapreduce_shuffle</value>  
  </property>  
  
  <!-- 配置Web Application Proxy安全代理(防止yarn被攻击) -->  
  <property>  
    <name>yarn.web-proxy.address</name>  
    <value>masteractive:8888</value>  
  </property>  
    
  <!-- 开启日志 -->  
  <property>  
    <name>yarn.log-aggregation-enable</name>  
    <value>true</value>  
  </property>  
  
  <!-- 配置日志删除时间为7天,-1为禁用,单位为秒 -->  
  <property>  
    <name>yarn.log-aggregation.retain-seconds</name>  
    <value>604800</value>  
  </property>  
  
  <!-- 修改日志目录 -->  
  <property>  
    <name>yarn.nodemanager.remote-app-log-dir</name>  
    <value>/logs</value>  
  </property>  
  
  <!-- 配置nodemanager可用的资源内存 -->  
  <property>  
    <name>yarn.nodemanager.resource.memory-mb</name>  
    <value>2048</value>  
  </property>  
  
  <!-- 配置nodemanager可用的资源CPU -->  
  <property>  
    <name>yarn.nodemanager.resource.cpu-vcores</name>  
    <value>2</value>  
  </property>  
    
  <!-- //////////////以下为YARN HA的配置////////////// -->  
  <!-- 开启YARN HA -->  
  <property>  
    <name>yarn.resourcemanager.ha.enabled</name>  
    <value>true</value>  
  </property>  
  
  <!-- 启用自动故障转移 -->  
  <property>  
    <name>yarn.resourcemanager.ha.automatic-failover.enabled</name>  
    <value>true</value>  
  </property>  
  
  <!-- 指定YARN HA的名称 -->  
  <property>  
    <name>yarn.resourcemanager.cluster-id</name>  
    <value>yarncluster</value>  
  </property>  
  
  <!-- 指定两个resourcemanager的名称 -->  
  <property>  
    <name>yarn.resourcemanager.ha.rm-ids</name>  
    <value>rm1,rm2</value>  
  </property>  
  
  <!-- 配置rm1,rm2的主机 -->  
  <property>  
    <name>yarn.resourcemanager.hostname.rm1</name>  
    <value>masteractive</value>  
  </property>  
  <property>  
    <name>yarn.resourcemanager.hostname.rm2</name>  
    <value>masterstandby</value>  
  </property>  
  
  <!-- 配置YARN的http端口 -->  
  <property>  
    <name>yarn.resourcemanager.webapp.address.rm1</name>  
    <value>masteractive:8088</value>  
  </property>   
  <property>  
    <name>yarn.resourcemanager.webapp.address.rm2</name>  
    <value>masterstandby:8088</value>  
  </property>  
  
  <!-- 配置zookeeper的地址 -->  
  <property>  
    <name>yarn.resourcemanager.zk-address</name>  
    <value>masterstandby:2181,slave1:2181,slave2:2181</value>  
  </property>  
  
  <!-- 配置zookeeper的存储位置 -->  
  <property>  
    <name>yarn.resourcemanager.zk-state-store.parent-path</name>  
    <value>/rmstore</value>  
  </property>  
  
  <!-- 开启yarn resourcemanager restart -->  
  <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>  
  
  <!-- 开启yarn nodemanager restart -->  
  <property>  
    <name>yarn.nodemanager.recovery.enabled</name>  
    <value>true</value>  
  </property>  
  
  <!-- 配置nodemanager IPC的通信端口 -->  
  <property>  
    <name>yarn.nodemanager.address</name>  
    <value>0.0.0.0:45454</value>  
  </property>  
</configuration>

5)slaves

masterstandby
slave1
slave2

Hadoop集群的初始化

// 启动zookeeper集群(分别在slave1、slave2和masterstandby上执行)
$ zkServer.sh start
// 格式化ZKFC(在masteractive上执行,其他机子也可以),这个时候会在zookeeper上生成一个节点 hadoop-ha,这就是自动故障转移会用到的
$ hdfs zkfc -formatZK
// 启动journalnode(分别在slave1、slave2和masterstandby上执行)
$ hadoop-daemon.sh start journalnode
// 格式化HDFS(在masteractive上执行)
$ hdfs namenode -format
将格式化后,启动masteractive上的namenode
$ hadoop-deamon.sh start namenode
//在masterstandby上执行下面的命令,同步namenode的数据
$ hdfs namenode -bootstrapStandby
//接下来关闭所有的进程,在masteractive上执行
$ stop-dfs.sh 

Hadoop集群的启动

// 启动HDFS(在masteractive执行)
$ start-dfs.sh
备注:此命令分别在masteractive/masterstandby节点启动了NameNode和ZKFC,分别在masterstandby/slave1/slave2节点启动了DataNode和JournalNode。
// 启动YARN(在masterstandby执行)
$ start-yarn.sh
备注:此命令在masterstandby节点启动了ResourceManager,分别在masterstandby/slave1/slave2节点启动了NodeManager。
// 启动YARN的另一个ResourceManager(在masteractive执行,用于容灾)
$ yarn-daemon.sh start resourcemanager
// 启动YARN的安全代理(在mastersactive执行)
$ yarn-daemon.sh start proxyserver
备注:proxyserver充当防火墙的角色,可以提高访问集群的安全性
// 启动YARN的历史任务服务(在masteractive执行)
$ mr-jobhistory-daemon.sh start historyserver

现在集群就已经成功启动,就有上面表中显示的各个进程。当你stop namenode或者resourcemanager时候,可以查看到50070和8088页面active或者standby状态将会自动切换。这就实现了高可用。

【注:如果没有实现自动切换,查看hadoop-root-zkfc-masteractive(或者masterstandby).log日志会发现缺少一个fuser命令,执行命令yum install -y psmisc 即可解决该问题】

3.NameNodeFederation

• 集群中提供多个NameNode,每个NameNode负责管理一部分DataNode。

• 一个namenode对应一个block pool,block pool是同一个namenode下面所有的block集合。

• 实现命名空间的横向扩展,使得Hadoop集群的规模可以达到上万台,提升性能,同时可以资源隔离。

• 节点规划

节点 NN JN ZK DN 所属集群
masteractive Y       cluster1
masterstandby Y Y Y Y cluster1
slave1 Y Y Y Y cluster2
slave2 Y Y Y Y cluster2

下面我们就对HA和Federation进行整合。

• 配

其实就是在dfs.nameservices中多加了1个集群,用来管理namenode。

1)core-site.xml

<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://cluster1</value>
        </property>
    <property>
         <name>hadoop.tmp.dir</name>
         <value>/home/admin/hadoop-2.2.0/tmp</value>
    </property>
    <property>
         <name>ha.zookeeper.quorum</name>
         <value>masterstandby:2181,slave1:2181,slave2:2181</value>
    </property>
</configuration>

2)hdfs-sixt.xml

<configuration>
    <property>  
        <name>dfs.namenode.name.dir</name>  
        <value>/usr/local/src/hadoop-2.6.0-cdh5.7.0/data/namenode</value>  
    </property>  
    <property>  
	<name>dfs.datanode.data.dir</name>  
	<value>/usr/local/src/hadoop-2.6.0-cdh5.7.0/data/datanode</value>  
    </property>  
    <property>
   	<name>dfs.replication</name>
	<value>3</value>
    </property>
    <property>  
    	<name>dfs.permissions.enabled</name>  
	<value>false</value>  
    </property> 	
    <property>  
	<name>dfs.webhdfs.enabled</name>  
	<value>true</value>  
    </property> 
    <property>
       	<name>dfs.nameservices</name>
       	<value>cluster1, cluster2</value>
    </property>
    <property>
    	<name>dfs.ha.namenodes.cluster1</name>
    	<value>nn1,nn2</value>
    </property>

    <property>
       	<name>dfs.ha.namenodes.cluster2</name>
	<value>nn3,nn4</value>
    </property>
    <property>
    	<name>dfs.namenode.rpc-address.cluster1.nn1</name>
        <value>masteractive:9000</value>
    </property>
    <property>
        <name>dfs.namenode.http-address.cluster1.nn1</name>
        <value>masteractive:50070</value>
    </property>
    <property>
        <name>dfs.namenode.rpc-address.cluster1.nn2</name>
        <value>masterstandby:9000</value>
    </property>
    <property>
        <name>dfs.namenode.http-address.cluster1.nn2</name>
        <value>masterstandby:50070</value>
    </property>

    <property>
        <name>dfs.namenode.rpc-address.cluster2.nn3</name>
    	<value>slave1:9000</value>
    </property>
    <property>
        <name>dfs.namenode.http-address.cluster2.nn3</name>
        <value>slave1:50070</value>
    </property>
    <property>
        <name>dfs.namenode.rpc-address.cluster2.nn4</name>
        <value>slave2:9000</value>
    </property>
    <property>
        <name>dfs.namenode.http-address.cluster2.nn4</name>
       <value>slave2:50070</value>
    </property>

    <property>
	<name>dfs.namenode.shared.edits.dir</name>
        <value>qjournal://masterstandby:8485;slave1:8485;slave2:8485/cluster1</value>
    </property>
    <property>
	<name>dfs.namenode.shared.edits.dir</name>
        <value>qjournal://masterstandby:8485;slave1:8485;slave2:8485/cluster2</value>
    </property>
    <property>
        <name>dfs.journalnode.edits.dir</name>
        <value> /usr/local/src/hadoop-2.6.0-cdh5.7.0/data/journal</value>
    </property>
    <property>
        <name>dfs.ha.fencing.methods</name>
        <value>sshfence</value>
    </property>
    <property>
        <name>dfs.ha.fencing.ssh.private-key-files</name>
        <value>/root/.ssh/id_rsa</value>
    </property>
    <property>  
    	<name>dfs.ha.automatic-failover.enabled.cluster1</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.automatic-failover.enabled.cluster2</name>  
    	<value>true</value>  
    </property>  
    <property>
	<name>dfs.client.failover.proxy.provider.cluster2</name>
        <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>
</configuration>

其他的配置文件和HA中所配置的一模一样。

• 启动

这里要注意的是,如果经过了HA的配置,在格式化之前,要将data目录清空,并重新创建,否则会出现问题,因为clusterID会产生冲突。

//在masterstandby、slave1、slave2上启动zk
# bin/zkServer.sh start
//在masterstandby、slave1、slave2上启动JournalNode

# sbin/hadoop-daemon.sh start journalnode
//在ZooKeeper集群中初始化HA的状态(仅第一次需要执行),在masteractive、slave1上执行
# bin/hdfs zkfc -formatZK
//在创建Federation环境的时候,需要注意保持${CLUSTER_ID}的值,以确保所有NN能共享同一个集群的存储资源,具体做法是在格式化第一台NN之后,取得其${CLUSTER_ID}的值,然后用如下命令格式化其他NN:hdfs namenode -format -clusterid ${CLUSTER_ID}

//在masteractive节点上执行格式化(只有在第一次启动时需要进行格式化):
# hdfs namenode -format -clusterId hadoop(自己指定名称或者由集群自己生成)
# sbin/hadoop-daemon.sh start namenode
//生成的hadoop-cluster这个ID是整个集群共用的。保证两个NameService可以共享所有的DataNodes,否则两个NameService在format之后,生成的clusterid不一致,DataNode会随机注册到不同的NameNode上。
//masterstandby(备用NN)节点同步主NN的元数据信息:
# bin/hdfs namenode -bootstrapStandby
//启动备NN:
# sbin/hadoop-daemon.sh start namenode
//在masteractive、masterstandby上启动zkfc,执行后,masteractive和masterstandby中有一个节点就会变为active状态。
# sbin/hadoop-daemon.sh start zkfc
//在slave1节点上执行格式化(只有在第一次启动时需要进行格式化):
# hdfs namenode -format -clusterId hadoop(与上面保持一致)
# sbin/hadoop-daemon.sh start namenode
//slave2(备用NN)节点同步主NN的元数据信息:
# bin/hdfs namenode -bootstrapStandby
//启动备NN:
# sbin/hadoop-daemon.sh start namenode
//在slave1、slave2上启动zkfc,执行后,slave1、slave2中有一个节点就会变为active状态。
# sbin/hadoop-daemon.sh start zkfc
启动之后,就会发现登录50070界面,四个界面中有2个是处于active状态、2个是standby状态。说明启动成功。【如果启动失败,namenode突然消失,或者datanode无法启动,可以试着清空data目录,再重新创建目录,然后再从头执行一遍】

4.HDFS快照

参考:https://blog.csdn.net/androidlushangderen/article/details/51282612

• HDFS快照是一个只读的基于时间点文件系统拷贝,只记录block列表和大小。

• 快照可以是整个文件系统的也可以是一部分。常用来作为数据备份,防止用户错误操作和容灾恢复。

• Snapshot 并不会影响HDFS 的正常操作:修改会按照时间的反序记录,这样可以直接读取到最新的数据。

• 快照数据是当前数据减去修改的部分计算出来的。

• 快照会存储在snap shot table的目录下。

• HDFS快照是对目录进行设定,是某个目录的某一个时刻的镜像

• 对于一个snap shot table文件夹,“.snapshot” 被用于记录他的快照, /foo 是一个snapshottable目录,/foo/bar是一个/foo下面的文件目录,/foo有一个快照s0,那么路径就是:/foo/.snapshot/s0/bar

5.HDFS缓存

• 允许用户指定要缓存的HDFS路径

• 明确的锁定可以阻止频繁使用的数据被从内存中清除

• 集中化缓存管理对于重复访问的文件很有用

• 可以换成目录或文件,但目录是非递归的,子目录以下的就不行了

6.HDFS ACL

• Hadoop从2.4.0开始支持

• 首先参数上要开启基本权限和访问控制列表功能

    – dfs.permissions.enabled

    – dfs.namenode.acls.enabled

• 常用命令:

    – hadoop fs -getfacl /input/acl

    – hdfs dfs -setfacl -m user:mapred:r-- /input/acl

    – hdfs dfs -setfacl -x user:mapred /input/acl

7.异构层级存储结构

• Hadoop2.6.0开始支持

• 一个集群中,有多种不同的存储介质,比如有SSD、 RAM等

• 由于一个Hadoop集群中有多种类型的任务,不同的任务对数据访问速度要求不一样,于是通过相应配置,控制目录和文件写到什么样的介质上去,并且具备配额控制要求。

猜你喜欢

转载自blog.csdn.net/qq_25560849/article/details/80086249
今日推荐