原生Hadoop3.X高可用配置方式

Hadoop3.X版本,在2017年左右就有了第一个alpha版本,但是那个时候刚出来,所以没有人使用,到2018年3.0.0版本作为第一个3,X正式发布,截止当前本文书写时间,3.X版本已经发展到了3.4,在Hadoop的顶层设计上最大的区别就是在2.X的时候,高可用机制只允许一个在工作中,一个在备用,但是3.X的hadoop允许最多存在五套高可用节点。当然,官方推荐最多三套,自带的MR计算框架也由原来的纯磁盘运算加入了内存运算的设计。

在给大家介绍3.X如何搭建集群之前,要先给大家说一些理论上的东西,当你要把Hadoop运行在商业硬件上。可以选择普通硬件供应商生产的标准化的、广泛有效的硬件来构建集群,无需使用特定供应商生产的昂贵、专有的硬件设备。但要注意商业硬件并不等同于低端硬件。低端机器常常使用便宜的零部件,其故障率远高于更贵一些,但仍是商业级别的机器。当管理几十台、上百台,甚至几千台机器时,选择便宜的零部件并不划算,因为更高的故障率推高了维护成本。也不推荐使用大型的数据库级别的机器,因为这类机器的性价比太低了。

在国内,很多互联网小作坊,可能会考虑使用少数几台数据库级别的机器来构建一个集群,使其性能达到一个中等规模的商业机器集群。然而,这会埋下很大的一个坑洞,当大比例的集群由于硬件故障无法使用,或者硬件规格过时后,会对整个集群产生更大的负面影响。

这里举例说明,在2010 年年中,运行Hadoop的datanode和tasktracker的典型机器具有以下规格:

处理器,两个四核2~2.5 GHz CPU
内存,16~24 GB ECC RAM  (使用ECC内存能够有效减少Hadoop的效验错误)
存储器,4x1TB SATA 硬盘
网络,千兆以太网

按照上面这种条件来说,在实际实施中,尽管各个集群采用的硬件规格肯定有所不同,但是就现在最新的服务器而言,肯定都比这个配置高,即使有的节点可能很垃,属于十多年以前的机子,但是Hadoop使用多CPU和多磁盘,分而治之的方法,可以充分利用硬件组成一个强大的集群功能。

在搭建的途中,有一点要注意的是,按照官方的说法,Hadoop本身尽管建议采用RAID作为 namenode的存储器以保护元数据,但是!不推荐直接使用RAID作为datanode的存储设备,因为它不会给HDFS带来其他益处。HDFS所提供的节点间数据复制技术已可满足数据备份需求,无需使用RAID的冗余机制。

尽管RAID条带化技术(RAID0)被广泛用于提升性能,但是其速度仍然比用在HDFS 里的JBOD(Just a Bunch Of Disks)技术慢。JBOD可以在所有磁盘之间循环调度HDFS数据块。而RAID0的读写操作受限于磁盘阵列中最慢盘片的速度,而JBOD的磁盘操作均独立,因而平均读写速度高于最慢盘片的读写速度。需要强调的是,各个磁盘的性能在实际使用中总存在相当大的差异,即使对于相同型号的磁盘。雅虎集群曾经有过一个评测报告(http://markmail.org/message/xmzc45zi25htr7ry)表明,在一个测试(Gridmix)中,JBOD 比RAID0快10%,在另一测试(HDFS写吞吐量)中,JBOD 比 RAID 0 快 30%。最后,若JBOD配置的某一磁盘出现故障,HDFS可以忽略该磁盘,继续工作。而 RAID 的某一盘片故障会导致整个磁盘阵列不可用,进而使相应节点失效。

此外,Hadoop 的主体由Java语言写成,能够在任意一个安装了JVM的平台上运行。但由于仍有部分代码(例如控制脚本)需在Unix环境下执行,因而Hadoop 并不适宜以最终产品的形态运行在非Unix平台上。

而至于一个 Hadoop 集群到底应该有多大?这个问题并无确切答案。但是,Hadoop的魅力在于用户可以在初始阶段构建一个小集群(大约10个节点),并随存储与计算需求增长持续扩充。从某种意义上讲,更恰当的问题是:你的集群需要增长得多快?通过以下一个关于存储的例子可以体会更深。

假如数据每周增长1TB。如果采用三路HDFS复制技术(就是数据块的备份数+本身),则每周需要增加3 TB 存储能力。再加上一些中间文件和日志文件(约占30%),基本上相当于每周添设一台机器(2010年的典型机器)。当然在实际上,一般不会每周去购买一台新机器并将其加入集群。类似这样的粗略计算意义在于了解集群的规模:既,在本例中,保存两年数据大致需要100台机器。

而对于一个小集群(几十个节点)而言,理论上最极端时,在一台master机器上同时运行 namenode 和jobtracker(这个组件是yarn的前身,但是很多外语文献任然会使用这个名称),一般没问题,但需确保至少一份namenode的元数据被另存在远程文件系统中,当然这是极端情况下,正儿八经使用中,没有谁会给自己找麻烦,老老实实的搭完全分布式就可以,就算自己本地的测试环境,搭建单节点也不要把namenode和yarn搭在一个节点上。

在2.x,甚至是更早的版本中hadoop存在着一个角色叫secondarynamenode,在1.x的时候它是用来作为备用namenode存在的一个角色,说白了就是一个暂时解决单namenode宕机的方案,以及辅助主namenode做一些日志聚合等操作。而在2.x的时候hadoop提供了namenode的ha,既高可用解决方案后,secondarynamenode就只剩下伪分布式或者单namenode搭建时为主namenode提供日志聚合之类的辅助能力,ha的时候集群中就没有使用它的必要。现在到了3.x,请大家彻底忘掉secondarynamenode这个角色,因为3.x最多允许集群存在5个namenode。

理论知识的最后,和大家说一个有意思的事情,在早期,人们通常这样认为,集群应该配备的是32位机器,以避免大指针引起的存储开销。Sun公司的Java 6 update 14的特色之一“压缩的普通对象指针”显著降低了这类开销,因而说白了现在在64位硬件上运行 Hadoop是会降低它的性能的。

在这里插入图片描述

在网络策略上,Hadoop 集群架构通常包含两级网络拓扑,如上图所示。一般来说,各机架装配30~40个服务器,共享一个1GB的交换机(该图中各机架只画了3个服务器),各机架的交换机又通过上行链路与一个核心交换机或路由器(通常为1GB或更高)互联。该架构的突出特点是同一机架内部的节点之间的总带宽要远高于不同机架上的节点间的带宽。

在机架选择上,为了达到Hadoop的最佳性能,配置Hadoop系统以让其了解网络拓扑状况就极为关键。如果集群只包含一个机架,就无需做什么,因为这是默认配置。但是对于多机架的集群来说,描述清楚节点-机架间的映射关系就很有必要。这样的话,当Hadoop将MapReduce任务分配到各个节点时,会倾向于执行机架内的数据传输(拥有更多带宽),而非跨机架数据传输。HDFS将能够更加智能地放置复本(replica),以取得性能和弹性的平衡。

诸如节点和机架等的网络位置以树的形式来表示,从而能够体现出各个位置之间的网络“距离”。namenode使用网络位置来确定在哪里放置块的复本,MapReduce的调度器根据网络位置来查找最近的复本,将它作为map任务的输入。

在上面的网络拓扑图中,机架拓扑由两个网络位置来描述,即/switchl/rack1和/switchl/rack2。由于该集群只有一个顶层路由器,这两个位置可以简写为/rack1 和/rack2。

Hadoop 配置需要通过一个Java接口DNSToSwitchMapping来指定节点地址和网络位置之间的映射关系。该接口定义如下:

public interface DNSToSwitchMapping {
	public List<String> resolve(List<String> names);
}

resolve()函数的输入参数names 描述IP地址列表,返回相应的网络位置字符串列表。topology.node.switch.mapping.impl配置属性实现了 DNSToSwitchMapping接口,namenode和jobtracker均采用它来解析工作节点的网络位置。

在上例的网络拓扑中,可将node1、node2 和node3映射到/rack1,将 node4、node5 和node6 映射到/rack2 中。

但是,大多数安装并不需要额外实现新的接口,只需使用默认的 ScriptBasedMapping实现即可,它运行用户定义的脚本来描述映射关系。脚本的存放路径由属性topology.script.file.name控制。脚本接受一系列输入参数,描述带映射的主机名称或IP地址,再将相应的网络位置以空格分开,输出到标准输出。可以参考Hadoop wiki的一个例子,网址为http://wiki.apache.org/hadoop/topology_rack_awareness_scripts。如果没有指定脚本位置,默认情况下会将所有节点映射到单个网络位置,即/default-rack。


开始正式安装

注意:安装所需的服务器SSH免密互信、JavaJDK、时间同步、域名映射、静态IP、关闭防火墙、修改主机名称这些环境准备,这里就不演示了,有需要,去我主页找原生大数据集群搭建二里面看。

第一步:本次操作的版本是3.3.6,上传Hadoop安装包解压即可,这里有一个坑要注意,按照试错经验以及官网的一些资料,发现默认情况下3.x的hadoop是不允许root用户启动的,但是如果你用更改用户的方式搭建3.x就会发现在启动的时候,无论你关闭SELinux安全模块也好,还是用sudo也好,都无法越过Linux的线程优先级拦截,所以我们需要搭建的时候通过在配置文件里面追加新配置的方式,替换掉默认的用户启动限制。

cd /opt
tar -zxvf hadoop-3.3.6.tar.gz

第二步:进入配置文件所在的路径${HADOOP_HOME}/etc/hadoop,修改所有*-env.sh中存在的JAVA_HOEM值

第三步:打开hadoop-env.sh文件修改如下配置项,指定root用户为运行这些组件的用户,注意除了HDFS_NAMENODE_USER使原本就有的配置,其他的都是直接追加就行。

export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
export HDFS_JOURNALNODE_USER=root
export HDFS_ZKFC_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root

第四步:修改配置文件core-site.xml

<configuration>
   <!-- 在ha模式中指定hdfs集群的逻辑名称,把多个NameNode的地址组装成一个组序列,hdp是自定义的名字你可以改其他的 -->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://hdp</value>
    </property>
    
     <!-- 声明hadoop运行时产生文件的所用到的本地存储目录 -->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/opt/hadoop-3.1.3/hdpData/tmp</value>
    </property>
    
     <!-- 配置HDFS网页登录使用的静态用户:Root,你如果不设置这个那么你就需要把hdfs的所有文件全选改为777不然操作不了web页面-->
    <property>
        <name>hadoop.http.staticuser.user</name>
        <value>root</value>
    </property>
    
     <!-- 指定zookeeper集群的地址:zkfc要连接的zkServer地址,用于管理hdfs集群 -->
    <property>
        <name>ha.zookeeper.quorum</name>
        <value>node001:2181,node002:2181,node003:2181</value>
    </property>

    <!--修改ipc参数,防止出现连接journalnode服务ConnectException,默认10s-->
    <property>
        <name>ipc.client.connect.max.retries</name>
        <value>100</value>
    </property>
    <property>
        <name>ipc.client.connect.retry.interval</name>
        <value>10000</value>
    </property>
</configuration>

第五步:修改配置文件hdfs-site.xml配置的时候注意3.x允许最多存在5个namenode,但是官方建议3个位最佳,可以节省很多不必要的网络IO

<configuration>
    <!-- 这里是在core中设置的namenode逻辑组名称,自动寻找NameNode节点 -->
    <property>
        <name>dfs.nameservices</name>
        <value>hdp</value>
    </property>
    
    <!-- 把定义的逻辑名称指向各个namenode的别名,即集群中NameNode节点,3.x最多5个 -->
    <property>
        <name>dfs.ha.namenodes.hdp</name>
        <value>nn1,nn2</value>
    </property>
    
    <!-- NameNode RPC通信地址 -->
    <property>
        <name>dfs.namenode.rpc-address.hdp.nn1</name>
        <value>node001:8020</value>
    </property>
    
    <property>
        <name>dfs.namenode.rpc-address.hdp.nn2</name>
        <value>node002:8020</value>
    </property>
    
    <!-- NameNode的http通信地址-->
    <property>
        <name>dfs.namenode.http-address.hdp.nn1</name>
        <value>node001:9870</value>
    </property>
    
    <property>
        <name>dfs.namenode.http-address.hdp.nn2</name>
        <value>node002:9870</value>
    </property>
    
    <!-- 配置JournalNode集群的地址,指定编辑日志的共享目录 -->
    <property>
        <name>dfs.namenode.shared.edits.dir</name>
        <value>qjournal://node001:8485;node002:8485;node003:8485/hdp</value>
    </property>
    
    <!-- 指定JouralNode节点存放编辑日志的本地存储路径 -->
    <property>
        <name>dfs.journalnode.edits.dir</name>
        <value>/opt/hadoop-3.1.3/hdpData/journaldata</value>
    </property>
    
    <!-- 开启自动故障转移功能 -->
    <property>
        <name>dfs.ha.automatic-failover.enabled</name>
        <value>true</value>
    </property>
    
    <!-- 指定那个类用于确定哪个NameNode为Active -->
    <property>
        <name>dfs.client.failover.proxy.provider.hdp</name>
        <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>
    
    <!-- 指定ha出现故障时的隔离方法 -->
    <property>
        <name>dfs.ha.fencing.methods</name>
        <value>sshfence</value>
        <value>shell(true)</value>
    </property>
    
    <!-- 指定隔离主机的私钥路径(主备节点间相互免密钥,指定私匙地址)-->
    <property>
        <name>dfs.ha.fencing.ssh.private-key-files</name>
        <value>/root/.ssh/id_rsa</value>
    </property>
    
    <!--副本数量,默认3个-->
    <property>
        <name>dfs.replication</name>
        <value>2</value>
    </property>

    <!-- 配置sshfence隔离机制超时时间,单位毫秒 -->
    <property>
        <name>dfs.ha.fencing.ssh.connect-timeout</name>
        <value>30000</value>
    </property>
    
    <!-- datanode和namenode数据存放的本地路径,多个路径用逗号隔开 -->
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file:///opt/hadoop-3.1.3/hdpData/tmp/dfs/data</value>
    </property>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file:///opt/hadoop-3.1.3/hdpData/tmp/dfs/name</value>
    </property>
    <!-- 多路径的写入策略 -->
    <property>
        <name>dfs.datanode.fsdataset.volume.choosing.policy</name>
        <value>org.apache.hadoop.hdfs.server.datanode.fsdataset.AvailableSpaceVolumeChoosingPolicy</value>
    </property>
</configuration>

第六步:修改配置文件mapred-site.xml

<configuration>
    <!-- 指定MapReduce程序运行在Yarn上 -->
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
    
    <!-- 指定mapreduce jobhistory地址:历史服务器端地址 -->
    <property>
        <name>mapreduce.jobhistory.address</name>
        <value>node003:10020</value>
    </property>
    
    <!-- 任务历史服务器的web地址 -->
    <property>
        <name>mapreduce.jobhistory.webapp.address</name>
        <value>node003:19888</value>
    </property>
    
    <property>
        <name>yarn.app.mapreduce.am.staging-dir</name>
        <value>/hisdata/staging</value>
    </property>
    
    <!-- 配置运行过的日志存放在hdfs上的存放路径 -->
    <property>
        <name>mapreduce.jobhistory.done-dir</name>
        <value>/history/done</value>
    </property>
    
    <!-- 配置正在运行中的日志在hdfs上的存放路径 -->
    <property>
        <name>mapreudce.jobhistory.intermediate.done-dir</name>
        <value>/history/done_intermediate</value>
    </property>
    
    <!--以下必须配置,否则运行MapReduce会提示检查是否配置-->
    <property>
        <name>yarn.app.mapreduce.am.env</name>
        <value>HADOOP_MAPRED_HOME=/opt/hadoop-3.3.6</value>
    </property>
    
    <property>
        <name>mapreduce.map.env</name>
        <value>HADOOP_MAPRED_HOME=/opt/hadoop-3.3.6</value>
    </property>
    
    <property>
        <name>mapreduce.reduce.env</name>
        <value>HADOOP_MAPRED_HOME=/opt/hadoop-3.3.6</value>
    </property>
</configuration>

这里说明一点,yarn.app.mapreduce.am.staging-dir、mapreduce.jobhistory.done-dir、mapreduce.jobhistory.intermediate-done-dir这三个路径都是一个hdfs路径,默认在hdfs的/tmp路径下,你可以不配置,单独放出来是为了某些特殊情况下需要查这些文件,但是开发基本不会遇到这些问题

yarn.app.mapreduce.am.staging-dir:MapReduce应用程序管理器也就是AM的暂存目录,其实就是MR提交以后资源jar、任务配置、所需文件等打包成task后的暂存目录
mapreduce.jobhistory.done-dir:这个目录用于存放MapReduce作业完成后的历史记录文件。这些文件通常包含了作业运行的摘要信息、状态、计数器等,但并不包含详细的运行时日志。这些历史记录文件用于后续分析作业的执行情况,但并不用于实时监控或诊断问题。是一个hdfs路径,在这个路径里最有用的是.jobhist结尾的文件,里面包含的就是任务状态和部分运行日志摘要
mapreduce.jobhistory.intermediate-done-dir:这个目录用于存放MapReduce作业在运行过程中产生的中间历史记录文件。这些文件通常包含了作业运行到某个阶段时的状态、计数器等信息。这些中间历史记录文件主要用于监控作业的执行进度和状态,但并不包含详细的运行时日志。当作业完成后,这些中间历史记录文件可能会被移动到mapreduce.jobhistory.done-dir目录下,作为作业完成后的历史记录

第七步:修改yarn-site.xml配置文件

<configuration>
    <!-- 开启resourcemanager(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>node002</value>
    </property>
	
    <property>
        <name>yarn.resourcemanager.hostname.rm2</name>
        <value>node003</value>
    </property>
    
    <!-- YARN资源管理器(ResourceManager)的Web用户界面的地址 -->
    <property>
        <name>yarn.resourcemanager.webapp.address.rm1</name>
        <value>node002:8088</value>
    </property>
	
    <property>
        <name>yarn.resourcemanager.webapp.address.rm2</name>
        <value>node003:8088</value>
    </property>
	
	<!-- yarn对applicationmaster服务的端口 -->
    <property>
        <name>yarn.resourcemanager.scheduler.address.rm1</name>
        <value>node002:8030</value>
    </property>
    
    <property>
        <name>yarn.resourcemanager.scheduler.address.rm2</name>
        <value>node003:8030</value>
    </property>
    
    <!-- yarn对nodemanager服务的地址 -->
    <property>
        <name>yarn.resourcemanager.resource-tracker.address.rm1</name>
        <value>node002:8031</value>
    </property>
    
    <property>
        <name>yarn.resourcemanager.resource-tracker.address.rm2</name>
        <value>node003:8031</value>
    </property>

    <!--yarn对客户端服务的端口 -->
    <property>
        <name>yarn.resourcemanager.address.rm1</name>
        <value>node002:8032</value>
    </property>

    <property>
        <name>yarn.resourcemanager.address.rm2</name>
        <value>node003:8032</value>
    </property>

    <!-- yarn对管理员服务的地址 -->
    <property>
        <name>yarn.resourcemanager.admin.address.rm1</name>
        <value>node002:8033</value>
    </property>

    <property>
        <name>yarn.resourcemanager.admin.address.rm2</name>
        <value>node003:8033</value>
    </property>
	
    <!-- 指定zk集群地址 -->
    <property>
        <name>yarn.resourcemanager.zk-address</name>
        <value>node001:2181,node002:2181,node003:2181</value>
    </property>
	
     <!-- 指定MR走shuffle -->
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    
    <!-- 开启日志聚合 -->
    <property>
        <name>yarn.log-aggregation-enable</name>
        <value>true</value>
    </property>
	
     <!-- 设置日志聚集服务器地址 -->
    <property>
        <name>yarn.log.server.url</name>
        <value>http://node003:19888/jobhistory/logs</value>
    </property>
	
    <!-- 设置日志保留时间 -->
    <property>
        <name>yarn.log-aggregation.retain-seconds</name>
        <value>86400</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>
        <!-- yarn重启后等待历史任务被加载的时间 -->
        <name>yarn.resourcemanager.work-preserving-recovery.scheduling-wait-ms</name>
        <value>10000</value>
    </property>
    
	<!-- 下面这两个配置是计算任务运行时资源队列允许每个Continer容器占用内存资源的大小最值,全局配置不需要区分ResourceManager实例 --> 
    <property>  
        <name>yarn.scheduler.minimum-allocation-mb</name>  
        <value>1024</value>  
    </property> 
	
    <property>  
        <name>yarn.scheduler.maximum-allocation-mb</name>  
        <value>8192</value>  
    </property>  

    <!-- 下面这两个配置是计算任务运行时资源队列允许每个Continer容器占用虚拟核数资源的大小最值,全局配置不需要区分ResourceManager实例 --> 
    <property>  
        <name>yarn.scheduler.minimum-allocation-vcores</name>  
        <value>1</value>  
    </property>
	
    <property>  
        <name>yarn.scheduler.maximum-allocation-vcores</name>  
        <value>4</value>  
    </property> 

    <!-- 配置虚拟内存额外使用比例 -->
    <property>  
        <name>yarn.nodemanager.vmem-pmem-ratio</name>  
        <value>2.1</value>  
    </property>

    <!-- datanode是否检查资源超出,如果查出最大允许资源,任务会被kill掉 -->
    <property>  
        <name>yarn.nodemanager.pmem-check-enabled</name>  
        <value>true</value>  
    </property>

    <!-- 指定yarn的任务队列类型为容器 -->
    <property>
        <name>yarn.resourcemanager.scheduler.class</name>
        <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value>
    </property>
	
	<!-- 磁盘检查 -->
    <property>
        <name>yarn.nodemanager.vmem-check-enabled</name>
        <value>false</value>
    </property>
	
</configuration>

这里要说一点,在yarn配置文件里配置的日志聚合和mapreduce文件里配置的MR任务日志保存的地址是不一样的,这是因为hadoop提供了两个层级的日志记录,mapreduce里面的那个是只有任务自身,而且还不全,只是摘要,并且后期随着集群的运行,它里面的东西会越来越多,你需要手动去删除它,这个就是集群管理员的运维任务了,而yarn里面配置的聚合日志是很完整的日志,而且一般我们不会去直接在hdfs上找,因为它太多了,太详细了,所以你需要通过设置好的访问路径在web上,就可以去查看,而且被聚合的日志,通过上面设置的保存日期,它会自动删除,你登录yarn的web页面所看到的application列表里面所展示的历史MR任务列表,以及你可以看到他们的日志,就是因为你开启了日志聚合,你可以尝试关掉日志聚合功能,这样的话在你查看application列表的时候,你只能看到当前集群未重启时的任务列表,而且当你点击日志的时候你会看到的是一句提示大概就是告诉你任务容器日志没有被记录。其实你可以不在mapreduce里面另外配置MR的完成日志和中间日志,让他们默认保存在tmp里,之所以另外配置,是因为有的时候对运维人员或对其他所需要的场景下会需要这些摘要,从而找的时候方便一点而已。

第八步:按照自己的需要修改CapacityScheduler调度器配置文件capacity-scheduler.xml

<configuration>

  <property>
    <name>yarn.scheduler.capacity.maximum-applications</name>
    <value>10000</value>
    <description>
      整个集群正在运行的以及等待中的任务的最大数
    </description>
  </property>

  <property>
    <name>yarn.scheduler.capacity.maximum-am-resource-percent</name>
    <value>0.1</value>
    <description>
      整个集群中有多少资源可以可以用来运行applicationmaster
	  该配置主要用来限制正在运行的任务数量,防止集群过载
	  当前是整个集群的全局配置,如果你有需要可以使用
	  yarn.scheduler.capacity.<queue-path>.maximum-am-resource-percent
	  来规定某一个队列的
    </description>
  </property>

  <property>
    <name>yarn.scheduler.capacity.resource-calculator</name>
    <value>org.apache.hadoop.yarn.util.resource.DominantResourceCalculator</value>
	<description>
      使用的资源计算类
    </description>
  </property>

  <property>
    <name>yarn.scheduler.capacity.root.queues</name>
    <value>default</value>
    <description>
      有多少个一级队列用英文逗号隔开
    </description>
  </property>

  <property>
    <name>yarn.scheduler.capacity.root.default.capacity</name>
    <value>100</value>
    <description>该队列占总队列(root)的多少资源,是个百分比的值</description>
  </property>

  <property>
    <name>yarn.scheduler.capacity.root.default.user-limit-factor</name>
    <value>1</value>
    <description>
      不同用户向该队列提交时最多使用多少资源,例如1或0,5
    </description>
  </property>

  <property>
    <name>yarn.scheduler.capacity.root.default.maximum-capacity</name>
    <value>100</value>
    <description>
      该队列自身资源最大的可使用资源占比,是一个百分比值,意味着该队列
	  已使用的资源到达该值后,即使有空闲资源也不会再给其他任务使用
    </description>
  </property>

  <property>
    <name>yarn.scheduler.capacity.root.default.state</name>
    <value>RUNNING</value>
    <description>
      该队列的状态RUNNING(可使用) or STOPPED(暂停使用).
    </description>
  </property>

  <property>
    <name>yarn.scheduler.capacity.root.default.acl_submit_applications</name>
    <value>*</value>
    <description>
      谁可以向该队里及其子队列提交任务,默认*,既全部用户
    </description>
  </property>

  <property>
    <name>yarn.scheduler.capacity.root.default.acl_administer_queue</name>
    <value>*</value>
    <description>
      谁可以管理该队里及其子队列任务,比如做kill操作等,默认*,既全部用户
    </description>
  </property>

  <property>
    <name>yarn.scheduler.capacity.node-locality-delay</name>
    <value>40</value>
    <description>
      控制 YARN 调度器在放弃节点本地性(node locality)
	  并考虑机架本地性(rack locality)或其他非本地性资源之前
	  应该等待的调度机会数量
    </description>
  </property>

  <property>
    <name>yarn.scheduler.capacity.queue-mappings</name>
    <value></value>
    <description>
      一般不使用,它是指当你需要更加细致的用户队列映射时使用
	  语法如下:[u or g]:[name]:[queue_name][,next_mapping]
	  比如:u:user1:queueA,g:group1:queueB,u:user2:queueC
		用户 user1 会被映射到 queueA 队列。
		组 group1 中的所有用户会被映射到 queueB 队列。
		用户 user2 会被映射到 queueC 队列
    </description>
  </property>

  <property>
    <name>yarn.scheduler.capacity.queue-mappings-override.enable</name>
    <value>false</value>
    <description>
       这个配置是用来决定你是否允许用户或者应用程序通过动态配置
	   来覆盖你已经设置好的队列配置,通常保持false,主要是防止用户
	   之间访问不应该访问的运行资源
    </description>
  </property>

</configuration>

如果在未来你该更改capacity-scheduler.xml文件中的配置,更改完一定不要直接重启集群,要运行一下yarn rmadmin -refreshQueues命令才可以

第九步:修改workers配置文件,这个就是datanode节点,2.x版本叫做slaves,3.x改名了

node001
node002
node003

第十步:开始格式化。

1、首先你要确保你的Zookeeper时启动好的,这一步不需要受用户的影响,你自己的zookeeper该怎么启动就怎么启动就行,然后就是确保你的环境变量配置好了。

export JAVA_HOME=/opt/jdk1.8.0_333
export HADOOP_HOME=/opt/hadoop-3.3.6
export ZOOKEEPER_HOME=/opt/zookeeper-3.7.2

export PATH=$PATH:${JAVA_HOME}/bin
export PATH=$PATH:${HADOOP_HOME}/bin
export PATH=$PATH:${HADOOP_HOME}/sbin
export PATH=$PATH:${ZOOKEEPER_HOME}/bin

export HADOOP_CONF_DIR=/opt/hadoop-3.3.6/etc/hadoop

2、在所有的datanode节点上手动启动journalnode进程

${HADOOP_HOME}/sbin/hadoop-daemon.sh start journalnode
或者
${HADOOP_HOME}/bin/hdfs --daemon start journalnode

运行之后jsp检查,查看是否有journalnode进程

3、在你准备的主节点上格式化namenode

${HADOOP_HOME}/bin/hdfs namenode -format

4、在主namenode上运行命令,启动它,注意这一点和2.x不一样,2.x这时候可以运行start-dfs.sh直接启动hdfs,但是3.x不行,如果你运行了start-dfs.sh你会发现在操作journalnode会触发优先级拦截

${HADOOP_HOME}/bin/hdfs --daemon start namenode

5、在其他两个备用namenode节点运行命令同步主namenode数据

${HADOOP_HOME}/bin/hdfs namenode -bootstrapStandby

命令会在Found nn*卡一会不要着急

6、格式化zkfc,在主namenode上运行一次就可以

${HADOOP_HOME}/bin/hdfs zkfc -formatZK

7、启动hdfs和yarn

${HADOOP_HOME}/sbin/start-dfs.sh
${HADOOP_HOME}/sbin/start-yarn.sh

第一次启动hdfs的时候可能会在namendoe的一个文件上卡一下资源优先级,但是不要慌后面不报错正常启动完成就行,要注意的是后续启动hdfs不需要单独启动namenode了,会随着启动,但是active节点激活可能有些慢,而且随着你集群的namenode越多,这个时间越长。

8、访问namenode的9870端口,查看namenode的状态
在这里插入图片描述
访问yarn节点的8088端口可以打开yarn的ui
在这里插入图片描述

你也可以验证一个namenode的HA

	可以浏览器访问:
		http://hdp4:9870
		NameNode 'hdp4:8020' (standby)
		http://hdp5:9870
		NameNode 'hdp5:8020' (active)
		http://hdp6:9870
		NameNode 'hdp6:8020' (standby)
	
	验证HDFS HA
		首先向hdfs上传一个文件
		hadoop fs -put /etc/profile /profile
		hadoop fs -ls /
		然后再kill掉active的NameNode
		kill -9 <进程id>
		浏览器访问:
		http://hdp5:9870 
		会发现之前主的namenode已经用不了了,web页面也无法访问
		http://hdp4:9870
		http://hdp6:9870 
		这个时候hdp6上的NameNode变成了active
		在执行命令:
		hadoop fs -ls /
		-rw-r--r--   3 root supergroup       1926 2014-02-06 15:36 /profile
		刚才上传的文件依然存在!!!
		在之前的主namenode上手动启动被我们kill的NameNode
		hadoop-daemon.sh start namenode
		通过浏览器访问:http://hdp5:9870
		可以发现原来主的namenode又可以使用了,不过当前处于备用状态
	
	验证YARN:
		运行一下hadoop提供的demo中的WordCount程序:
		hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar  wordcount /input /output
	
	还有一些测试集群工作状态的一些指令 :
    	hdfs dfsadmin -report	 查看hdfs的各节点状态信息
		cluster1n/hdfs haadmin -getServiceState nn1		 获取一个namenode节点的HA状态
		scluster1n/hadoop-daemon.sh start namenode  单独启动一个namenode进程
		hadoop-daemon.sh start zkfc   单独启动一个zkfc进程

你可以写一个shell脚本放在主namenode节点上来启动hadoop

#!/bin/bash
#该脚本用来启动所有服务,通过参数决定

#集群地址
cluster = (hdp4 hdp5 hdp6)

case $1 in 
"zk_start"){
#启动zookeeper
	echo `date` > /opt/start_ap_log/zk_start.log
	for i in cluster
	do
		echo "-----------正在启动$i的zookeeper---------"
		echo "$i--zookeeper:" >> /opt/start_ap_log/zk_start.log
		ssh $i "source /etc/profile && /opt/zookeeper-3.4.10/bin/zkServer.sh start" >> /opt/start_ap_log/zk_start.log
	done
};;
"zk_stop"){
#关闭zookeeper
        echo `date` > /opt/start_ap_log/zk_stop.log
        for i in cluster
        do
                echo "-----------正在关闭$i的zookeeper---------"
                echo "$i--zookeeper:" >> /opt/start_ap_log/zk_stop.log
                ssh $i "source /etc/profile && /opt/zookeeper-3.4.10/bin/zkServer.sh stop" >> /opt/start_ap_log/zk_stop.log
        done
};;
"hdp_start"){
#开启hadoop
	echo `date` > /opt/start_ap_log/hdp_start.log
	echo "----------------开始启动namenode-hdfs----------------"
	/opt/hadoop-3.3.6/sbin/start-dfs.sh >> /opt/start_ap_log/hdp_start.log

	echo `date` > /opt/start_ap_log/yarn_start.log
	echo "----------------开始启动yarn----------------"
	echo "yarn节点----------------------" >> /opt/start_ap_log/yarn_start.log
	ssh hdp5 "source /etc/profile && /opt/hadoop-3.3.6/sbin/start-yarn.sh" >> /opt/start_ap_log/yarn_start.log

	echo "----------------开始启动his----------------"
	echo `date` > /opt/start_ap_log/his_start.log
	ssh hdp5 "source /etc/profile && /opt/hadoop-3.3.6/sbin/mr-jobhistory-daemon.sh start historyserver" >> /opt/start_ap_log/his_start.log
};;
"hdp_stop"){
#关闭hadoop
	echo "----------------开始关闭his----------------"
	echo `date` > /opt/start_ap_log/his_stop.log
	ssh hdp5 "source /etc/profile && /opt/hadoop-3.3.6/sbin/mr-jobhistory-daemon.sh stop historyserver" >> /opt/start_ap_log/his_stop.log
	
	echo `date` > /opt/start_ap_log/yarn_stop.log
	echo "----------------开始关闭yarn----------------"
    echo "yarn节点----------------------" >> /opt/start_ap_log/yarn_stop.log
    ssh hdp5 "source /etc/profile && /opt/hadoop-3.3.6/sbin/stop-yarn.sh" >> /opt/start_ap_log/yarn_stop.log

	echo "----------------关闭namenode-hdfs------------"
        echo `date` > /opt/start_ap_log/hdp_stop.log
        /opt/hadoop-3.3.6/sbin/stop-dfs.sh >> /opt/start_ap_log/hdp_stop.log
};;
esac

注意,最后测试操作和脚本里面的节点域名和配置文件中的不一样,这是因为在写本篇搭建方法的时候实机操作发现一些问题,所以从新整理过配置文件,确认无误后把最终的配置文件放了上去,就是说后面测试和前面配置步骤用的配置文件不是一套,不过流程一样,大家注意一下就行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/733193.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

超级干货 !数据平滑9大妙招(python版)_python指数平滑预测案例

大家好&#xff0c;对数据进行平滑处理的方法有很多种&#xff0c;具体的选择取决于数据的性质和处理的目的。如果你对Python感兴趣&#xff0c;想要学习pyhton&#xff0c;这里给大家分享一份**Python全套学习资料**&#xff0c;都是我自己学习时整理的&#xff0c;希望可以帮…

动手学深度学习(Pytorch版)代码实践 -卷积神经网络-28批量规范化

28批量规范化 """可持续加速深层网络的收敛速度""" import torch from torch import nn import liliPytorch as lp import matplotlib.pyplot as pltdef batch_norm(X, gamma, beta, moving_mean, moving_var, eps, momentum):""&quo…

【LeetCode刷题】232.用栈实现队列

目录 题目链接 图解思路 整体结构 实现过程 入队列 出队列 实现代码 MyQueue.h MyQueue.c stack.h stack.c test.c 题目链接 232. 用栈实现队列 - 力扣&#xff08;LeetCode&#xff09; 图解思路 整体结构 实现过程 入队列 插入数据时&#xff0c;插入到ist。…

拦截器Interceptor

概念&#xff1a;是一种动态拦截方法调用的机制&#xff0c;类似于过滤器。Spring框架中提供的&#xff0c;用来动态拦截方法的执行。 作用&#xff1a;拦截请求&#xff0c;在指定的方法调用前后&#xff0c;根据业务需要执行预先设定的代码。

C++实现自动生成c++类中的属性的get和set方法

目录 应用场景 运行准备 代码展示 结果显示 应用场景 当我们在编写类的属性时&#xff0c;需要对该属性进行封装&#xff0c;需要一系列的get和set的方法。例如下面是天气类的成员属性。可以看到属性很多&#xff0c;而写get和set都是一些固定的操作&#xff0c;因此可以直…

stata17中java installation not found或java not recognozed的问题

此问题在于stata不知道去哪里找java,因此需要手动的告诉他 方法1&#xff1a; 1.你得保证已经安装并配置好java环境 2.在stata中输入以下内容并重启stata即可 set java_home "D:\Develope\JDk17" 其中java_home后面的""里面的内容是你的jdk安装路径 我的…

由 Vault 支持的 KES 的 MinIO Operator

为了提供安全锁定和擦除的合规性功能&#xff0c;MinIO 使用服务器端加密 &#xff08;SSE&#xff09; 在存储层加密对象&#xff0c;以保护对象作为写入操作的一部分。MinIO 以极高的效率做到这一点——基准测试表明 MinIO 能够以接近线速进行加密/解密。 MinIO 使用的秘诀是…

Linux htop命令使用

文章目录 简介界面介绍第一行第二行第三行第四行 如何使用 简介 htop 是一个类似于 top 的命令&#xff0c;但具有更丰富的功能和更友好的界面。它可以实时显示系统中各个进程的资源占用情况&#xff0c;如 CPU 使用率、内存使用率等。以下是对 htop 命令的完全解析&#xff1…

vscode插件path-intellisense失效原因

很可能是因为设置中的自动补全部分除了问题。 问题 作者自身是因为使用了copilot之后&#xff0c;感觉vscod自带的自动补全(设置里面叫"建议"&#xff0c;或者inttelisense)就没必要了&#xff0c;然后一通改设置把建议关掉之后发现插件path-intellisense也不能用了…

【C语言】函数指针数组和指向函数指针数组的指针

1 函数指针数组 数组是一个存放相同类型数据的存储空间&#xff0c;那我们已经学习了指针数组。 比如&#xff1a; int *arr[10];//数组的每个元素是int* 那要把函数的地址存到一个数组中&#xff0c;那这个数组就叫函数指针数组&#xff0c;那函数指针的数组如何定义呢&am…

【经验分享】RT600 serial boot mode测试

【经验分享】RT600 serial boot mode测试 一&#xff0c; 文档描述二&#xff0c; Serial boot mode测试2.1 evkmimxrt685_gpio_led_output 工程测试2.2 evkmimxrt685_dsp_hello_world_usart_cm33工程测试 一&#xff0c; 文档描述 RT600的启动模式共支持4种&#xff1a; 1&am…

svm和决策树基本知识以及模型评价以及模型保存

svm和决策树基本知识以及模型评价以及模型保存 文章目录 一、SVM1.1&#xff0c;常用属性函数 二、决策树2.1&#xff0c;常用属性函数2.2&#xff0c;决策树可视化2.3&#xff0c;决策树解释 3&#xff0c;模型评价3.1&#xff0c;方面一&#xff08;评价指标&#xff09;3.2&…

MatLab手把手搭建FOC控制环路(全部使用matlab自带模块)

MatLab手把手搭建FOC控制环路&#xff08;全部使用matlab自带模块&#xff09; Matlab添加模块只需要在空白处双击鼠标左键&#xff0c;输入模块的名字。 添加PMSM模块&#xff1a; Permanent Magnet Synchronous Machine 参数选择&#xff1a; 添加逆变器Two-Level Conver…

Apple - Cryptographic Services Guide

本文翻译自&#xff1a;Cryptographic Services Guide&#xff08;更新时间&#xff1a;2018-06-04 https://developer.apple.com/library/archive/documentation/Security/Conceptual/cryptoservices/Introduction/Introduction.html#//apple_ref/doc/uid/TP40011172 文章目录…

python字符串如何删除后几位

1、首先在jupyter notebook中新建一个空白的python文件&#xff1a; 2、然后定义一个字符串&#xff0c;用字符串截取的方式打印出排除最后三个字符的结果&#xff0c;这里的“s[:-3]”的意思就是从字符串取第0个字符至倒数第三个字符的前一个字符&#xff0c;这样就截取了最后…

别再滥用std::async了,strace命令暴露了一个乱开线程问题

用strace查看进程的系统调用后&#xff0c;发现一个std::async滥用问题 问题现象 进程的系统调用clone次数持续增加 使用工具strace发现进程clone系统调用过多且一直在增加 strace -c -p PID问题分析 clone在做什么&#xff1a;创建进程&#xff08;线程&#xff09; 查看…

基于Redis和openresty实现高并发缓存架构

目录 概述缓存架构设计实践代码路由业务封装redis 效果 概述 本文是对项目中 QPS 高并发相关问题的一种解决方案&#xff0c;利用 Nginx 与 Redis 的高并发、超低延迟响应&#xff0c;结合 Canal 进行实现。 openrestry官网 当程序需要提供较高的并发访问时&#xff0c;往往需…

算出未来——2024年,计算机相关专业仍是热门

随着高考结束&#xff0c;数百万考生和家长们开始着手专业选择与志愿填报。 选择大学专业不仅关乎未来四年的学习生涯&#xff0c;更可能决定一个人一生的职业方向和人生轨迹。 在众多专业中&#xff0c;计算机相关专业因其广泛的就业前景和不断变化的行业需求&#xff0c;一…

tauri中从前端ts调用rust函数,并异步收到响应结果

在前端是可以异步调用rust代码的&#xff0c;而且还是挺简单的逻辑&#xff0c;一共就三步&#xff1a;定义rust函数&#xff0c;注入到invoke_handler中&#xff0c;在前端调用。有英文能力的可以看官方文档&#xff1a;Calling Rust from the frontend | Tauri Apps 没有英文…

C++拷贝构造函数、运算符重载函数、赋值运算符重载函数、前置++和后置++重载等的介绍

文章目录 前言一、拷贝构造函数1. 概念2. 特征3. 编译器生成默认拷贝构造函数4. 拷贝构造函数典型使用场景 二、运算符重载函数三、赋值运算符重载函数1. 赋值运算符重载格式2. 赋值运算符只能重载成类的成员函数不能重载成全局函数3.编译器生成一个默认赋值运算符重载 四、前置…