前言
hadoop高可用是其商用化时三大重点之一,另外两大重点是yarn的资源配置与分布式存储,其次我们要知道高可用,俗称HA,它核心是zookeeper提供的zkfc机制和hadoop自身有一组名为journal node的线程,两者配合负责主、备namenode节点的元数据同步问题
而高可用在极端的情况下可能发生脑裂、假死问题,所以大家非商业模式要正式使用的情况下,只是自己本地测试环境那最好还是做单主节点就好了
本篇博文将以商用为目的记录配置HA的方式,结点数目商用时最低7台,大家自己配置的时候据情况而定属于自己的合适结点策略
注意:如果其他技术访问高可用集群的namenode,只需要在原单namenode的访问路径上删除端口号就可
Hadoop自身搭建完是存储与计算磁盘级别分离,如果有存储和计算节点级别分离的特殊需求见–》https://blog.csdn.net/dudadudadd/article/details/141271409
搭建的时候注意,本文档中用的是root用户,因此在后面的使用上不会有太大的问题,不过业内习惯把hadoop的集群文件默认交给一个叫hdfs的系统用户,后续不同用户使用也会有对应的用户,这种情况下就要确保所有集群中useradd了对应的用户,而且确保每个队列对用户设置了合适的访问权限。同时hadoop的配置文件有很多不知有默认值,而且默认是最终状态不允许覆盖,比如MR任务参数就有一些默认无法覆盖,你可以通过yarn-web界面集群整体配置中看到配置中是否携带了<final>true</final>,如果你需要使用时覆盖就把它重写在yarn-web中展示的默认配置位置文件中,并设置<final>false</final>
节点
集群部署节点角色的规划(7节点,由于是最低档次所以zk放在了datanode同节点,zkfc、journal-node、his是zk和hdp自带的服务)
hdp1 namenode zkfc
hdp2 namenode zkfc his
hdp3 resourcemanager
hdp4 resourcemanager
hdp5 datanode nodemanager zookeeper journal-node
hdp6 datanode nodemanager zookeeper journal-node
hdp7 datanode nodemanager zookeeper journal-node
------------------
集群部署节点角色的规划(3节点)
hdp1 namenode resourcemanager zkfc nodemanager datanode zookeeper journal node
hdp2 namenode resourcemanager zkfc nodemanager datanode zookeeper journal node
hdp3 nodemanager datanode zookeeper journal node
直观上看就是比普通单namenode测试集群多出了一组namenode和resourcemanager,以及两个namenode数据同步依赖的zookeeper以及zkfc机制和journal node通道,配置的时候其实zookeeper集群和journal node可以单独再分出,这个具体看商用时的规划,这里提到是为了提醒大家配置的时候要对服务有基本的认知,zkfc和journal node是hadoop两个必要的核心组建,它们是hadoop基于zookeeper整合出来的两个东西,zkfc随着namenode启动负责监控namenode健康状态、主备切换和状态同步,journal node运行在单独的节点上,负责存储edit数据提供给备用的namenode提供完成元数据的同步更新,his是历史服务器节点。
如果你需要Hadoop搭建存储和计算节点分离–》https://blog.csdn.net/dudadudadd/article/details/141271409
安装
第一步:解压并将保证Hadoop与Java的环境变量存在,配置文件都在hadoop根目录的etc/hadoop中,我们要进入其中并修改一系列的-env.sh结尾文件中的JAVA_HOME,这一点和之前大家安装单namenode节点本地测试环境一样
第二步:修改core-site.xml
<configuration>
<!--
集群的 namenode组 访问地址在这里指定!注意我说的组是主、备的统称,该值必须和hdfs-site.xml文件中的组名配置一致,这里之所以强调就是防止大家两个文件写的不一样,大家使用自己的配置就可以,不是必须为hdp1 ,我这里只是为了方便,所以组名定义为了hdp1,它就是个名字不是域名
-->
<property>
<name>fs.defaultFS</name>
<value>hdfs://hdp1</value>
</property>
<!-- hadoop的运行时的临时数据的本地存放目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/hadoop/hadoopData</value>
</property>
<!-- ZooKeeper集群的地址和端口。注意,数量一定是奇数,且不少于三个节点-->
<property>
<name>ha.zookeeper.quorum</name>
<value>hdp5:2181,hdp6:2181,hdp7:2181</value>
</property>
<!--修改core-site.xml中的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>
<!--代理用户以及授信域,用法见:https://blog.csdn.net/dudadudadd/article/details/148031272-->
<property>
<name>hadoop.proxyuser.root.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.root.groups</name>
<value>*</value>
</property>
<!--按需更改hdfs上所有文件生成时的权限,默认是022,注意!这个配置是按位减
并且由于hdfs上没有执行一个文件的概念,执行权限是访问一个路径下子路径的基本权限
因此该参数计算时,当目标是一个文件,则最高权限是666,反之目录的最高权限是777,随后按位减
比如默认的022,目录权限的结果是755,应用在hdfs上最终的权限就是u=rwx,g=r-x,o=r-x
如果是个文件,最终权限就是644,rw-r--r--
-->
<property>
<name>fs.permissions.umask-mode</name>
<value>077</value>
</property>
<property>
<name>hadoop.security.authorization</name>
<value>false</value>
<description>默认就是false,为true的话意味着用户的识别要使用第三方的服务,比如kerberos,还要设置hadoop.security.auth_to_local 用户和凭证的映射</description>
</property>
</configuration>
配置好上面的core文件之后,hdfs提供了一个回收站的能力,你可以选择是否在其中配置。之所以没有直接写在core文件里面,是因为一旦启用的这个能力,你想要越过回收站直接删除文件,需要使用命令hdfs dfs -rm -skipTrash 路径来删除文件,当然普通的删除命令在hdfs底层实现就变成了移动,使用hdfs dfs -expunge命令可以清空回收站中的所有文件,这些文件将被永久删除且无法恢复,想要恢复文件可以在/user/${USER}/.Trash/Current目录中找到对应的文件,移动会原来的位置即可,其中${USER}是执行删除操作的用户名。值得注意的是启动了回收站能力之后,重启集群namenode很容易直接进入安全模式。
<!-- 回收站保存文件的过期时间,默认为0,单位为分钟,1440为24小时 -->
<property>
<name>fs.trash.interval</name>
<value>1440</value>
</property>
<!-- hdfs每隔多长时间检查检查一次回收站,目的是将回收站中的数据状态同步给namenode,一般和过期时间保持一致 -->
<property>
<name>fs.trash.checkpoint.interval</name>
<value>1440</value>
</property>
第三步:修改hdfs-site.xml
<configuration>
<!--指定hdfs的nameservice服务组名字,再次声明hdp1只是一个名字啊,不是hdp1这个节点,大家觉得别扭可以改成别的,但一定要和core-site.xml中的保持一致 -->
<property>
<name>dfs.nameservices</name>
<value>hdp1</value>
</property>
<!-- 这个配置时用来标识hdp1下面有主、备共两个NameNode,并且为他们标识名字,我配置的分别是nn1,nn2 -->
<property>
<name>dfs.ha.namenodes.hdp1</name>
<value>nn1,nn2</value>
</property>
<!-- nn1的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.hdp1.nn1</name>
<value>hdp1:9000</value>
</property>
<!-- nn1的http通信地址 -->
<property>
<name>dfs.namenode.http-address.hdp1.nn1</name>
<value>hdp1:50070</value>
</property>
<!-- nn2的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.hdp1.nn2</name>
<value>hdp2:9000</value>
</property>
<!-- nn2的http通信地址 -->
<property>
<name>dfs.namenode.http-address.hdp1.nn2</name>
<value>hdp2:50070</value>
</property>
<!-- 指定JournalNode服务节点的通讯端口,并同时指定NameNode的edits元数据在JournalNode上的存放位置,这个配置本质上的目的就是在zkfc服务保证NN高可用顺利切换的同时,让主副namenode对datanode中数据块信息有一个同步的位置,而这个位置的服务在哪里、怎么访问、又该访问服务中的那个路径,就在此配置,路径中保存的是集群数据的操作日志,注意配置的时候我这里的hdp5、hdp6、hdp7是JournalNode所在节点,不是zk所在节点,并且有的人以为JournalNode是跟随datanode启动的,并不是的,他们两个是不同的服务,这这个配置里你需要有多少个JournalNode就定义多少个就行,而不是datanode的节点,这种想法的一般都没搭建过商用化集群,一直用的本地测试,最终要的是路径中hdp1是你的集群ID,要和dfs.nameservices一致-->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://node001:8485;node002:8485;node003:8485/hdp</value>
</property>
<property>
<name>dfs.journalnode.http-address</name>
<value>0.0.0.0:8480</value>
</property>
<property>
<name>dfs.journalnode.rpc-address</name>
<value>0.0.0.0:8485</value>
</property>
<!-- 指定JournalNode数据在本地磁盘存放数据的位置 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/home/hadoop/app/hdpdata/journaldata</value>
</property>
<!-- 开启NameNode死亡自动切换 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<!-- 指定该集群出故障时,哪个实现类负责执行故障切换 -->
<property>
<name>dfs.client.failover.proxy.provider.hdp1</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免登陆,因此需要指定公钥路径,大家集群中ssh之后的公钥文件在哪里就指定那里,一般在用户主目录下的 .ssh文件夹里面-->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/hadoop/.ssh/id_rsa</value>
</property>
<!--副本数量,默认3个-->
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
<!-- 数据块大小,一般搭建时设置好了就不动了,因为后期更改那么已有的数据快不会随着立马生效,只是后期生成的数据块生效而已,例如设置为 256MB -->
<property>
<name>dfs.blocksize</name>
<value>268435456</value>
</property>
<!-- 配置sshfence隔离机制超时时间 -->
<property>
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value>30000</value>
</property>
<!-- namenode与datanode存储多路径配置,且更改datanode磁盘写入规则 -->
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///${hadoop.tmp.dir}/dfs/data,file:///${hadoop.tmp.dir}/dfs/data1</value>
</property>
<!-- 多路径的写入策略 -->
<property>
<name>dfs.datanode.fsdataset.volume.choosing.policy</name>
<value>org.apache.hadoop.hdfs.server.datanode.fsdataset.AvailableSpaceVolumeChoosingPolicy</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///${hadoop.tmp.dir}/dfs/name,file:///${hadoop.tmp.dir}/dfs/name1</value>
</property>
<!-- 打开hadoop的hdfs-web操作支持 -->
<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
</property>
<!-- 启用HDFS权限 控制-->
<property>
<name>dfs.permissions.enabled</name>
<value>true</value>
<description>默认就是true,开启hdfs的文件系统校验,chmod等这些文件元数据更改命令始终进行权限校验,不受这个配置等影响</description>
</property>
<property>
<name>dfs.permissions.superusergroup</name>
<value>root</value>
<description>默认是supergroup,超级用户组的名称,需要是一个linux系统中的组,hdfs不对该组做任何权限方面的检查</description>
</property>
<property>
<name>dfs.cluster.administrators</name>
<value>root root</value>
<description>超级用户,默认是空的,一般也不另行配置这个,知道有这个东西即可,因为默认会自动取服务构建用户(2.x)或者hadoopenv文件中定义的组件管理用户(3.x),这个配置设置时,应当最少包含hadoopenv中namenode相关服务的用户,不然会出问题,设置的格式为 "用户逗号分割 组逗号分割" 注意用户和组列表用空格分割</description>
</property>
<property>
<name>dfs.namenode.acls.enabled</name>
<value>true</value>
<description>默认是true,启用对HDFS ACL的支持,为false只有一种情况,可使得namenode拒绝所有hdfs路径的ACL请求,但是没有意义,知道有这配置就行</description>
</property>
<property>
<name>dfs.namenode.posix.acl.inheritance.enabled</name>
<value>true</value>
<description>默认是true,当创建一个目录时,namenode复用hdfs中父目录的默认权限选项,否则需要额外设置,也是知道有这个配置就行</description>
</property>
</configuration>
注意,一般情况下hdfs-web支持都是需要打开的,同类型的服务还有一个httpfs,如果需要开启,只需要更改httpfs-site.xml,追加如下可访问域的内容,并在后期负责运行httpfs的节点上执行sbin/httpfs.sh start命令即可,但是一般用的少,知道有这么个东西就行。
<!-- 自定义端口,如 14001 -->
<property>
<name>httpfs.http.port</name>
<value>14000</value>
</property>
<!-- 所有的节点都能访问httpfs服务 -->
<property>
<name>httpfs.proxyuser.httpfs.hosts</name>
<value>*</value>
</property>
<property>
<name>httpfs.proxyuser.httpfs.groups</name>
<value>*</value>
</property>
两个服务的区别是:WebHDFS是HDFS内置的组件,已经运行于NameNode和DataNode中。对HDFS文件的读写,将会重定向到文件所在的DataNode,并且会完全利用HDFS的带宽。HttpFS是独立于HDFS的一个服务。对HDFS文件的读写,将会通过它进行中转,它能限制带宽占用

第四步:修改mapred-site.xml
<configuration>
<!-- 指定mr框架为yarn方式 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!-- 历史服务器的外部服务端口 -->
<property>
<name>mapreduce.jobhistory.address</name>
<value>hdp2:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>hdp2:19888</value>
</property>
<!--MapReduce应用程序管理器的暂存目录,是一个hdfs路径,就是提交任务后yarn把任务打包成task等待时暂存的路径,这个路径会有手动维护的需求因此单独配置出来,默认在/tmp/hadoop-yarn/staging-->
<property>
<name>yarn.app.mapreduce.am.staging-dir</name>
<value>/hisdata/staging</value>
</property>
<!--MR JobHistory Server管理的已完成日志的存放位置,是一个hdfs路径-->
<property>
<name>mapreduce.jobhistory.done-dir</name>
<value>/history/done</value>
</property>
<!-- MapReduce作业产生的中间日志存放位置,是一个hdfs路径,当任务完成会聚合到mapreduce.jobhistory.done-dir路径中 -->
<property>
<name>mapreduce.jobhistory.intermediate-done-dir</name>
<value>/hisdata/done_intermediate</value>
</property>
</configuration>
这里说一点很重要的东西:mapred-site.xml文件中单独配置出了三个路径是因为他们默认被放在了/tmp下面,这个路径不安全,是个临时路径随时会被删除,并且重启集群后该目录也会被清空,所以把重要的日志相关信息放到其他路径下了,还要注意的是配置项mapreduce.jobhistory.done-dir和下面yarn文件中的yarn.nodemanager.remote-app-log-dir不冲突,两个路径虽然都保存的是MR任务的日志,但是yarn.nodemanager.remote-app-log-dir是聚合后的产物,它里面通过任务id为路径保存任务日志,主要有三类内容,分别是任务的syserr(标准错误输出)、sysout(标准输出)和syslog(系统日志),后期使用集群查看yarn上的日志就是这里提供的,而mapreduce.jobhistory.done-dir下面存放的日志并不是标准化输出的,它里面存留以.jhist和.xml结尾的文件。.jhist文件包含了MapReduce作业的详细运行信息,如作业的启动时间、结束时间、使用的Mapper和Reducer数量、Counter统计信息等。这些信息以JSON格式存储,便于机器解析和后续处理。.xml文件则通常包含了作业的配置参数,如内存设置、并行度等。
第五步:修改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的名字,对应主备namenode -->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<!-- 分别指定RM的地址 -->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>hdp3</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>hdp4</value>
</property>
<!-- 指定zk集群地址 -->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>hdp5:2181,hdp6:2181,hdp7:2181</value>
</property>
<!-- 外部shuffer服务,hadoop默认自带了mapreduce_shuffle,这里直接写其他的配置就会自动生效 -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 是否检查任务单容器使用的核数是否超出 -->
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
<!-- 是否检查任务单容器使用的内存是否超出 -->
<property>
<name>yarn.nodemanager.pmem-check-enabled</name>
<value>false</value>
</property>
<!--配置外部端口-->
<!-- yarn对applicationmaster服务的端口 -->
<property>
<name>yarn.resourcemanager.scheduler.address.rm1</name>
<value>hdp3:8030</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address.rm2</name>
<value>hdp4:8030</value>
</property>
<!-- yarn对nodemanager服务的地址 -->
<property>
<name>yarn.resourcemanager.resource-tracker.address.rm1</name>
<value>hdp3:8031</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address.rm2</name>
<value>hdp4:8031</value>
</property>
<!--yarn对客户端服务的端口 -->
<property>
<name>yarn.resourcemanager.address.rm1</name>
<value>hdp3:8032</value>
</property>
<property>
<name>yarn.resourcemanager.address.rm2</name>
<value>hdp4:8032</value>
</property>
<!-- yarn对管理员服务的地址 -->
<property>
<name>yarn.resourcemanager.admin.address.rm1</name>
<value>hdp3:8033</value>
</property>
<property>
<name>yarn.resourcemanager.admin.address.rm2</name>
<value>hdp4:8033</value>
</property>
<!-- yarn web UI服务的地址 -->
<property>
<name>yarn.resourcemanager.web.address.rm1</name>
<value>hdp3:8088</value>
</property>
<property>
<name>yarn.resourcemanager.web.address.rm2</name>
<value>hdp4:8088</value>
</property>
<!--开启Continer日志聚合,否则无法在web页面查看mr的日志-->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<!--这个是NN在执行完任务聚合日志给HDFS后,放在HDFS那个路径下,默认是/tmp/logs,但后期一般需要维护所以单独配出来-->
<property>
<name>yarn.nodemanager.remote-app-log-dir</name>
<value>/MRLogs</value>
</property>
<!-- 这个配置决定了nodemanager在跑任务时,continer容器的日志存放在哪路
是一个本地路径,默认是在hadoop安装路径下的logs/userlogs里
生产环境一定要配置一个单独的磁盘路径,因为任务非常多的时候随着日志的读写
磁盘损坏很容易发生 -->
<property>
<name>yarn.nodemanager.log-dirs</name>
<value>/mnt/hadoop/yarn/log</value>
</property>
<!-- 日志聚合服务器的url,生效的前提是配置好了日志服务器并配置的值是日志服务器上的一个url -->
<property>
<name>yarn.log.server.url</name>
<value>http://hdp5:19888/jobhistory/logs</value>
</property>
<!-- 设置日志保留时间 ,单位秒,默认保留七天-->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>86400</value>
</property>
<!-- 启用故障转移以及历史MR作业日志加载,虽然有点怪异,但这两个事情的开关确实是一个 -->
<property>
<name>yarn.resourcemanager.recovery.enabled</name>
<value>true</value>
</property>
<!-- 指定resourcemanager的所包含的状态信息在zookeeper集群上,故障切换后可以直接读取,历史MR也是由这个类加载 -->
<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>3</value>
</property>
<!-- 下面这两个配置在当前节点如果是nodemanager时生效规定当前节点可用总内存和可用总核数,全局配置不需要区分ResourceManager实例 -->
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>32768</value>
</property>
<property>
<name>yarn.nodemanager.resource.cpu-vcores</name>
<value>4</value>
</property>
<!-- 配置虚拟内存额外使用比例 -->
<property>
<name>yarn.nodemanager.vmem-pmem-ratio</name>
<value>1.5</value>
</property>
<!-- 指定yarn的任务队列类型为容器 -->
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value>
</property>
<!-- 这个配置是用来指定,如果当前节点是nodemanager角色,他在跑任务时产生的数据在哪里存放,比如拉到的数据块,生成的中间文件等等 -->
<property>
<name>yarn.nodemanager.local-dirs</name>
<value>file:///path/to/compute1,file:///path/to/compute2</value>
</property>
<!-- 任务完成的10分钟后,清理对应任务的相关数据,以保证 工作路径 空间的可以用率-->
<property>
<name>yarn.nodemanager.delete.debug-delay-sec</name>
<value>600</value>
</property>
<!-- 10分钟检查一次缓存 -->
<property>
<name>yarn.nodemanager.localizer.cache.cleanup.interval-ms</name>
<value>600000</value>
</property>
</configuration>
这里再强调一遍,在yarn配置文件里配置的日志聚合和mapreduce文件里配置的MR任务日志保存的地址是不一样的,这是因为hadoop提供了两个层级的日志记录,mapreduce里面的那个是任务自身的细节信息,未聚合,而yarn里面配置的聚合日志是很完整的日志,而且一般我们不会去直接在hdfs上找,因为它太多了,太详细了,所以你需要通过设置好的访问路径在web上,就可以去查看,而且被聚合的日志,通过上面设置的保存日期,它会自动删除,你登录yarn的web页面所看到的application列表里面所展示的历史MR任务列表,以及你可以看到他们的日志,就是因为你开启了日志聚合,你可以尝试关掉日志聚合功能,这样的话在你查看application列表的时候,你只能看到当前集群未重启时的任务列表,而且当你点击日志的时候你会看到的是一句提示大概就是告诉你任务容器日志没有被记录。其实你可以不在mapreduce里面另外配置MR的完成日志和中间日志,让他们默认保存在tmp里,之所以另外配置,是因为有的时候对运维人员或对其他所需要的场景下会需要这些摘要,从而找的时候方便一点而已。
对于yarn.nodemanager.aux-services,如果你的集群要跑spark on yarn任务,那么就要配置spark的外部shuffer服务,配置时,你需要在spark安装包中找到yarn/spark-x.y.x-yarn-shuffle.jar文件,将它上传到所有的nodemanager节点,随后在yarn-site.xml文件中添加如下配置
<!-- 在原有的mapreduce_shuffle基础上添加spark_shuffle -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle,spark_shuffle</value>
</property>
<!-- 新增spark_shuffle的依赖jar的存放路径 -->
<property>
<name>yarn.nodemanager.aux-services.spark_shuffle.classpath</name>
<value>这里是spark-x.y.x-yarn-shuffle.jar的放置路径</value>
</property>
<!-- 新增spark_shuffle的主类 -->
<property>
<name>yarn.nodemanager.aux-services.spark_shuffle.class</name>
<value>org.apache.spark.network.yarn.YarnShuffleService</value>
</property>
第六步:修改slaves,这里要注意的是,slaves中只需要指定datanode所在节点就可以
hdp5
hdp6
hdp7
第七步:修改capacity-scheduler.xml,这个文件对应了yarn配置文件中修改的使用队列,其中有很多默认值按照需要更改就行
<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,最大就是1
</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资源队列配置文件中可以使用hadoop预制的变量,但是!!在商用尝场景下,基本不用,你知道有怎么一个东西别人和你谈论起来不是一问三不知就行了,一来是基本不可能资源队列变来变去的,二来是这个玩意不同版本之间那个参数能生效不好说,比如下面这些参数是3.4.1,也就是写这偏博文时的最新版,该版本的官方文档中明确罗列的,但是其他版本,比如现在搭建的3.2.3,官方文档里面只提到并使用了%user 和 %primary_group。并且当yarn.scheduler.capacity.queue-mappings-override.enable=false时,这些变量是否生效也不好说,目前哪怕我在李老板公司干活的时候,也没有有过使用场景,所以就没深入研究
%application 提交的任务的名称。
%user 提交任务的用户。
%primary_group 提交者的主要组。
%secondary_group 提交者的次要(补充)组。
%default 调度程序的默认队列。
%specified 提交时用户配置中定义的队列。
如果在未来你该更改capacity-scheduler.xml文件中的配置,更改完一定不要直接重启集群,要运行一下yarn rmadmin -refreshQueues命令才可以
这里提一点,apache版本下的yarn任务执行权限,需要调度器配置文件和hdfs上的/user路径中是否存在用户主目录,且权限一般是755,两者同时把控
第八步:修改hadoop-policy.xml文件
<configuration>
<property>
<name>security.client.protocol.acl</name>
<value>*</value>
<description>谁可以操作客户端,你可以配置用户和组,两个列表用户在前,逗号分割,例如alice,bob users,wheel</description>
</property>
<property>
<name>security.client.datanode.protocol.acl</name>
<value>*</value>
<description>谁可以操作datanode节点协议,通俗的讲就是块平衡、块复制等,例如alice,bob users,wheel</description>
</property>
<property>
<name>security.datanode.protocol.acl</name>
<value>*</value>
<description>谁可以操作数据节点和namenode交互协议,例如alice,bob users,wheel</description>
</property>
<property>
<name>security.inter.datanode.protocol.acl</name>
<value>*</value>
<description>谁可以操作数据节点之间的ACL,例如alice,bob users,wheel</description>
</property>
<property>
<name>security.namenode.protocol.acl</name>
<value>*</value>
<description>谁可以操作namenode和辅助节点之间的ACL,例如alice,bob users,wheel</description>
</property>
<property>
<name>security.admin.operations.protocol.acl</name>
<value>root</value>
<description>谁可以操作ACL管理协议,上面都通常为 * ,但这个必须最小化控制,通常设置为hdfs或者整个hadoop集群的管理用户</description>
</property>
<property>
<name>security.refresh.user.mappings.protocol.acl</name>
<value>root</value>
<description>谁可以炒作用户映射刷新协议,同上需最小化</description>
</property>
<property>
<name>security.refresh.policy.protocol.acl</name>
<value>root</value>
<description>谁可以操作hadoop的安全策略刷新,比如dfsadmin和mradmin命令等,同上需要最小化</description>
</property>
<property>
<name>security.ha.service.protocol.acl</name>
<value>root</value>
<description>谁可以管理HA协议,比如namenode的活动和待机状态等,同上</description>
</property>
<property>
<name>security.zkfc.protocol.acl</name>
<value>root</value>
<description>谁可以访问控制ZK故障转义协议,同上最小化</description>
</property>
<property>
<name>security.qjournal.service.protocol.acl</name>
<value>root</value>
<description>控制哪些用户/组有权访问QJournalProtocol RPC服务</description>
</property>
<property>
<name>security.interqjournal.service.protocol.acl</name>
<value>root</value>
<description>控制哪些用户/组有权访问InterQJournalProtocol RPC服务,该服务专门管理 JournalNode节点之间的内部通信
</description>
</property>
<property>
<name>security.mrhs.client.protocol.acl</name>
<value>*</value>
<description>那些用户可以使用历史服务器和任务提交客户端之间的协议</description>
</property>
<!-- YARN Protocols -->
<property>
<name>security.resourcetracker.protocol.acl</name>
<value>*</value>
<description>那些用户可以访问资源总节点RM和NN之间的资源通信协议</description>
</property>
<property>
<name>security.resourcemanager-administration.protocol.acl</name>
<value>root</value>
<description>那些用户可以访问RN的管理命令协议,一般需要最小化</description>
</property>
<property>
<name>security.applicationclient.protocol.acl</name>
<value>*</value>
<description>谁可以访问任务客户端协议</description>
</property>
<property>
<name>security.applicationmaster.protocol.acl</name>
<value>*</value>
<description>谁可以访问任务管理协议</description>
</property>
<property>
<name>security.containermanagement.protocol.acl</name>
<value>*</value>
<description>谁可以访问容器管理协议.</description>
</property>
<property>
<name>security.resourcelocalizer.protocol.acl</name>
<value>*</value>
<description></description>
</property>
<!-- 下面这些都 * 就行 -->
<property>
<name>security.job.task.protocol.acl</name>
<value>*</value>
<description>ACL for TaskUmbilicalProtocol, used by the map and reduce
tasks to communicate with the parent tasktracker.
The ACL is a comma-separated list of user and group names. The user and
group list is separated by a blank. For e.g. "alice,bob users,wheel".
A special value of "*" means all users are allowed.</description>
</property>
<property>
<name>security.job.client.protocol.acl</name>
<value>*</value>
<description>ACL for MRClientProtocol, used by job clients to
communciate with the MR ApplicationMaster to query job status etc.
The ACL is a comma-separated list of user and group names. The user and
group list is separated by a blank. For e.g. "alice,bob users,wheel".
A special value of "*" means all users are allowed.</description>
</property>
<property>
<name>security.applicationhistory.protocol.acl</name>
<value>*</value>
<description>ACL for ApplicationHistoryProtocol, used by the timeline
server and the generic history service client to communicate with each other.
The ACL is a comma-separated list of user and group names. The user and
group list is separated by a blank. For e.g. "alice,bob users,wheel".
A special value of "*" means all users are allowed.</description>
</property>
<property>
<name>security.collector-nodemanager.protocol.acl</name>
<value>*</value>
<description>ACL for CollectorNodemanagerProtocol, used by nodemanager
if timeline service v2 is enabled, for the timeline collector and nodemanager
to communicate with each other.
The ACL is a comma-separated list of user and group names. The user and
group list is separated by a blank. For e.g. "alice,bob users,wheel".
A special value of "*" means all users are allowed.</description>
</property>
<property>
<name>security.applicationmaster-nodemanager.applicationmaster.protocol.acl</name>
<value>*</value>
<description>ACL for ApplicationMasterProtocol, used by the Nodemanager
and ApplicationMasters to communicate.
The ACL is a comma-separated list of user and group names. The user and
group list is separated by a blank. For e.g. "alice,bob users,wheel".
A special value of "*" means all users are allowed.</description>
</property>
<property>
<name>security.distributedscheduling.protocol.acl</name>
<value>*</value>
<description>ACL for DistributedSchedulingAMProtocol, used by the Nodemanager
and Resourcemanager to communicate.
The ACL is a comma-separated list of user and group names. The user and
group list is separated by a blank. For e.g. "alice,bob users,wheel".
A special value of "*" means all users are allowed.</description>
</property>
</configuration>
第九步:检查数据路径!!这一步相当重要,如果数据路径设置不当,后续的使用会非常难受,首先你要检查五个运行时所需要关键路径是否设置合理,如下
namenode和datanode,数据块的本地存储路径
nodemanager,任务计算用磁盘、continer执行日志磁盘
这四个路径,生产环境一定要有专属磁盘,解耦磁盘问题,保障数据安全
resourcemanager,日志聚合后与未聚合的四个数据存放路径,这个是在hdfs上底层使用datanode的本地存储路径,不过相对来说这个数据并不是致命因素,所以合理设置一个hdfs路径就行
历史服务器存放任务日志的三个路径,和rm的聚合日志一样不是致命因素,设置合理即可
随后检查hadoop-env.sh配置文件中的 HADOOP_LOG_DIR,这个配置决定了hadoop服务的整体日志存放地址,默认是在安装路径下的logs里面,比如NN或RM启停时的日志等,如在使用上有需要则可以更改它
第十步:scp分发hadoop安装包到集群其他节点,随后开始进行首次启动!!!
启动时,请严格按照下面的启动顺序来不然,就可以GG了。
1、先启动zookeeper集群
${ZOOKEEPER_HOME}/bin/zkServer.sh start
2、根据你的配置,在所有需要运行journalnode的节点上,手动启动journalnode进程
${HADOOP_HOME}/sbin/hadoop-daemon.sh start journalnode
或者
${HADOOP_HOME}/bin/hdfs --daemon start journalnode
运行之后jsp检查,查看是否有journalnode进程,以后就不需要手动起了,就第一次手动起
3、格式化namenode,在主namenode,也就是hdp1上执行命令:
${HADOOP_HOME}/bin/hdfs namenode -format
4、格式化zkfc,在主namenode上运行一次就可以,命令如下:
${HADOOP_HOME}/bin/hdfs zkfc -formatZK
5、在主namenode上运行${HADOOP_HOME}/sbin/start-dfs.sh命令,启动hdfs
6、上面步骤中主namenode格式化后,会在之前core-site.xml中hadoop.tmp.dir配置的目录下生成hdfs的数据文件,此时登录备用namenode节点运行如下命令,备用节点会自动拷贝主namenode文件,hadoop2.x备份运行的时候,会提示一次"(Y or N) "选择,一定要选Y意思是让备用节点后续处于交互式随着主namenode启动而启动,一定要确保主namenode格式化无异常
${HADOOP_HOME}/bin/hdfs namenode -bootstrapStandby
备份后,单独启动它
${HADOOP_HOME}/bin/hdfs --daemon start namenode
7、启动yarn,在hdp3节点运行${HADOOP_HOME}/sbin/start-yarn.sh
8、在hdp4上确定是否启动了备份的resourcemanager,因为高可用集群中namenode会自动切换,但是resourcemanager需要手动启,命令如下
${HADOOP_HOME}/sbin/yarn-daemon.sh start resourcemanager
9、在hdp2上启动历史服务器
${HADOOP_HOME}/sbin/mr-jobhistory-daemon.sh start historyserver
10、到此高可用的配置就结束了,我给大家找了一下测试用的命令大家可以试一试
可以浏览器访问:
http://hdp1:50070
NameNode 'hdp1:9000' (active)
http://hdp2:50070
NameNode 'hdp2:9000' (standby)
验证HDFS HA
首先向hdfs上传一个文件
hadoop fs -put /etc/profile /profile
hadoop fs -ls /
然后再kill掉active的NameNode
kill -9 <进程id>
浏览器访问:
http://hdp1:50070
会发现之前主的namenode已经用不了了
http://hdp2:50070
这个时候hdp2上的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://hdp1:50070
可以发现原来主的namenode又可以使用了
验证YARN:
运行一下hadoop提供的demo中的WordCount程序:
hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.4.1.jar wordcount /profile /out
还有一些测试集群工作状态的一些指令 :
hdfs dfsadmin -report 查看hdfs的各节点状态信息
cluster1n/hdfs haadmin -getServiceState nn1 获取一个namenode节点的HA状态
scluster1n/hadoop-daemon.sh start namenode 单独启动一个namenode进程
hadoop-daemon.sh start zkfc 单独启动一个zkfc进程
到此HA-Hadoop配置完毕,和伪分布式或者是单namenode方式,有一点要值得说明的是不在需要辅助namenode的存在,因为它本身就是1.x时提供的防止单namenode宕机的临时解决方案,在2.x搭建ha后就不需要它了。
最后,强调一遍启动方式
上面的启动方式是刚配置好的首次启动方式,后期启动没那么麻烦,只需要如下操作即可
1、启动zookeeper集群
2、启动hdfs,主副namenode会跟随着启动
3、启动yarn,副yarn会跟着启动
4、启动历史服务器
最后你可以写一个shell脚本来启动hadoop
#!/bin/bash
#该脚本用来启动所有服务,通过参数决定
#集群地址
cluster = (hdp1 hdp2 hdp3)
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-2.7.2/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 hdp2 "source /etc/profile && /opt/hadoop-2.7.2/sbin/start-yarn.sh" >> /opt/start_ap_log/yarn_start.log
echo "----------------开始启动his----------------"
echo `date` > /opt/start_ap_log/his_start.log
ssh hdp3 "source /etc/profile && /opt/hadoop-2.7.2/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 hdp3 "source /etc/profile && /opt/hadoop-2.7.2/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 hdp2 "source /etc/profile && /opt/hadoop-2.7.2/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-2.7.2/sbin/stop-dfs.sh >> /opt/start_ap_log/hdp_stop.log
};;
esac
对与上面这个脚本要留意一点的是,如果你的Hadoop集群备用RM不跟随着主RM启动那你就需要在启动yarn命令后面自己加一条/opt/hadoop-2.7.2/sbin/yarn-daemon.sh stop resourcemanager,当然,如果你用的是上面的脚本,完整的命令就是ssh hdp3 "source /etc/profile && /opt/hadoop-2.7.2/sbin/yarn-daemon.sh stop resourcemanager" >> /opt/start_ap_log/yarn_stop.log这样的,至于备用RM交互启动这一点,我也没有太留意过,因为博主搭建过很多测试集群以及商用灾备之类的目的集群,备用RM能不能交互启动都是失灵时不灵的,单独用命令启动也不影响,所以就没时间研究这个问题
在hdfs权限方面,如果你是自己个人使用,你可以直接把权限从根路径开始递归设置成777,否则你就要合理设置hdfs上的基本权限,这里给大家一个样板
首先 core-site 文件中,hdfs默认权限配置成077
随后,搭建好后手动设置基本权限架构,此时下面这些路径所属人正常都是服务管理员
/ 根路径自身的权限必须 777 因为所有人都要可访问hdfs上读写,是否拒绝那是最终路径的事情
/tmp 临时文件路径自身必须 777 ,其下子路径一般是不同服务或者某个用户使用过程中会自动生成一些临时文件,可以按需755或者700等,尤其是hive服务生成的 /tmp/hive 因为有代理身份它下面会有所有使用者所属的base路径,它们应该用700,还有个特殊的/tmp/hive/_resultscache_ 要777,通常为了方便 /tmp 就递归 777 了
/user hdfs内部的用户主目录,里面一般没什么东西,权限方面自身755,子路径700即可
后续使用,一个新的用户,需要管理员手动添加 /tmp 和 /user 下回用到的路径,并设置权限
/mr服务用到的路径,其下放日志等 路径自身 777 ,子路径按需配置,一般子路径也是按用户名为一级子目录划分的,一般用 755 ,或者只放日志直接777
/spark服务用到的路径,其下放日志、jars资源等 ,spark放日志不按照用户来,所以通常这个路径都是递归 777
不止这两个,其他用到hdfs路径的服务,它们的相关路径最好是直接配置到 / 根路径下,好处是权限控制清晰,简单明了
/hive的base路径 该路径自身必须777,和根路径一样的道理,同样建议配置在根路径下,其下子路径不用额外设置,依靠core文件中的默认配置即可
或者你也可以参考官网的建议路径,这种是最保险的,非Kerberos下看hdfs就行,local是部署路径的建议权限

#根路径不能,也不用 -R
hadoop fs -chown hdfs:hadoop /
hadoop fs -chmod 777 /
hadoop fs -chown -R hdfs:hadoop /tmp
hadoop fs -chmod -R 777 /tmp
hadoop fs -chown -R hdfs:hadoop /user
hadoop fs -chmod -R 755 /user
#下面这三个路径用你自己的配置
hadoop fs -chown -R yarn:hadoop /mrlogs
hadoop fs -chmod -R 777 /mrlogs
hadoop fs -chown -R mapred:hadoop /hisdata
hadoop fs -chmod -R 777 /hisdata
hadoop fs -chown -R mapred:hadoop /history
hadoop fs -chmod -R 750 /history
#如果你是已有集群添加认证,还要注意一个路径,这个是配置了标签后生成的,虽然标签在hadoop中是个不完整的假功能,但它的权限会影响启动
hadoop fs -chown -R yarn:hadoop /node-labels
hadoop fs -chmod -R 755 /node-labels
基本的权限组成就是这些
最后的最后!!!说一个经验,启停hadoop集群直接使用start-dfs.sh脚本其实是有事务风险的,一个搞不好会导致再次启动namenode发生org.apache.hadoop.hdfs.server.namenode.EditLogInputException异常,包括上面第一次格式化的启动,当然这个风险主要是偏向于停止操作,启动一般风险影响很小,保险的启停方式如下
停止流程:
# 1、在任意namenode节点执行,进入安全模式
hdfs dfsadmin -safemode enter
# 日志会出现 Safe mode is ON in xxxx,你也可以执行命令查询决定,off是已离开安全模式
hdfs dfsadmin -safemode get
# 2、停止ZKFC(在所以NameNode节点)
hdfs --daemon stop zkfc
# 3、 手动切换NN到Standby状态(在Active NameNode)
hdfs haadmin -ns hdp -transitionToStandby nn1 -forcemanual
# 确定结果
hdfs haadmin -ns hdp -getAllServiceState
# 4、此时才可以用脚本关闭datanode和namenode
# 单独操作一个节点,这个命令用在只维护某台节点时用
hdfs --daemon stop datanode
hdfs --daemon stop namenode
# 一般此时才可以使用 stop-dfs
sbin/stop-dfs.sh
# 5、在yarn的active节点上,让它进入Standby状态,rm1是你在配置文件中定义的id
yarn rmadmin -transitionToStandby rm1 -forcemanual
#查看结果
yarn rmadmin -getAllServiceState
# 6、和hdfs一样,此时可以用 stop-yarn脚本
sbin/stop-yarn.sh
# 同样的也可以单独操作某个节点
yarn --daemon stop resourcemanager
yarn --daemon stop nodemanager
# 7、停止JobHistory Server
mapred --daemon stop historyserver
# 8、在所有JournalNode节点执行
hdfs --daemon stop journalnode
启动流程和停止流程反着来:
# 1、在所有JournalNode节点执行启动命令
hdfs --daemon start journalnode
# 如果第一次启动的话
# 2-1、任意一台namenode上格式化ZKFC(高可用所需),则执行,否则跳过
hdfs zkfc -formatZK
# 2-2、同理格式化一台NameNode,通常是 nn1
hdfs namenode -format -clusterId <your-cluster-id>
# 2-3、启动nn1
hdfs --daemon start namenode
# 2-4、其他namenode同步数据后,启动
hdfs namenode -bootstrapStandby
hdfs --daemon start namenode
# 2-5 启动所有datanode
sbin/start-dfs.sh
# 如果是日常启动
# 2-1、 直接调用脚本
sbin/start-dfs.sh
# 3、检查DataNode连接 Live datanodes (数量),或者看namenode-web上的datanode节点列表,亦或者看有没有namenode进入active状态
hdfs dfsadmin -report
# 检查安全模式是否 off 离开
hdfs dfsadmin -safemode get
# 4、启动yarn
sbin/start-yarn.sh
# 5、启动历史服务器
mapred --daemon start historyserver
还有就是hadoop安装路径下的资源归属、官方建议的hdfs路径权限、hadoop-env中组件操作用户,这三块正式在公司内部署时,有要求的,不能直接用root,相关配置可以看-》https://blog.csdn.net/dudadudadd/article/details/157364726


487

被折叠的 条评论
为什么被折叠?



