目录
一、HA介绍
二、环境准备
2.1 机器准备及节点规划
2.2 /etc/hosts配置
2.3 配置ssh免密登录
三、安装](#3)
3.1 安装zookeeper
3.2 安装包准备
3.3 新建/opt/hadoop目录
3.4 上传安装包
3.5 解压并创建目录
3.6 配置环境变量
3.7 集群配置
3.7.1 配置hadoop-env.sh
3.7.2 配置core-site.xml文件
3.7.3 配置hdfs-site.xml文件
3.7.4 创建并修改mapred-site.xml文件
3.7.5 修改yarn-site.xml文件
3.7.6 修改slaves文件
3.8 集群初始化和启动
3.9 集群日常启动与关闭
3.9.1 正常的启动顺序
3.9.2 正常的关闭顺序
一、HA介绍
Hadoop的HA包含了HDFS的HA、YARN的HA,HA架构和方案详见: //www.greatytc.com/p/7c697f146674
二、环境准备
2.1 机器准备及节点规划
host | ip | os | 节点规划-hdfs | 节点规划-yarn | 节点规划-zookeeper |
---|---|---|---|---|---|
hadoop-1 | 192.168.90.131 | Ubuntu 18.04.2 LTS | NameNode(active) 、DFSZKFailoverController | ResourceManager(standby) | zookeeper |
hadoop-2 | 192.168.90.132 | Ubuntu 18.04.2 LTS | NameNode(standby)、DFSZKFailoverController | ResourceManager(active) | zookeeper |
hadoop-3 | 192.168.90.133 | Ubuntu 18.04.2 LTS | DateNode 、JournalNode | NodeManager | zookeeper |
hadoop-4 | 192.168.90.134 | Ubuntu 18.04.2 LTS | DateNode 、JournalNode | NodeManager | zookeeper(observer) |
hadoop-5 | 192.168.90.135 | Ubuntu 18.04.2 LTS | DateNode 、JournalNode | NodeManager |
2.2 /etc/hosts配置
在每台机器上编辑/etc/hosts文件, 加入如下内容:
192.168.90.131 hadoop-1
192.168.90.132 hadoop-2
192.168.90.133 hadoop-3
192.168.90.134 hadoop-4
192.168.90.135 hadoop-5
2.3 配置ssh免密登录
-
对每台机器生成秘钥文件,以root用户登录,生成空字符串秘钥,执行:
ssh-keygen -t rsa -P ''
提示
Enter file in which to save the key (/root/.ssh/id_rsa):
,直接回车(用默认文件/root/.ssh/id_rsa)。执行完成后在/root/.ssh目录下有3个文件:authorized_keys、id_rsa、id_rsa.pub。(如果没有authorized_keys可以通过touch authorized_keys
手动生成)。 将所有机器上的id_rsa.pub的内容合并到authorized_keys文件中(这里“合并”的意思是每台机器上authorized_keys文件包含所有机器上id_rsa.pub文件的内容)。
在每台机器上用ssh命令测试登录其它机器
如果提示类如如下认证信息:
The authenticity of host 'hadoop-2 (192.168.90.132)' can't be established.
ECDSA key fingerprint is SHA256:XEhSC0caRxdbv0eHNBo8c7VULr7vhj5pM2bt3frOEAA.
Are you sure you want to continue connecting (yes/no)?
输入yes回车即可,后面可以直接ssh登录。
如果是非root用户(例如本文后面建立的hadoop用户)ssh免密登录,需要在.ssh目录下执行
chmod 600 authorized_keys
, 将authorized_keys权限改为600 。
三、安装
3.1 安装zookeeper
本文用hadoop-1 ~ hadoop-4安装zookeeper集群,参考: //www.greatytc.com/p/e9becafcbaa7
3.2 安装包准备
下载hadoop安装包,地址:https://archive.apache.org/dist/hadoop/common/hadoop-2.8.3/
3.3 新建/opt/hadoop目录
mkdir /opt/hadoop
3.4 上传安装包
上传hadoop-2.8.3.tar.gz到/opt/hadoop目录
3.5 解压并创建目录:
cd /opt/hadoop
tar -zxvf hadoop-2.8.3.tar.gz
mkdir hdfs
cd hdfs
mkdir data name tmp pid journalnode logs
cd ../
mkdir yarn
cd yarn
mkdir logs local staging
创建的hdfs下的date、name、tmp、pid在后续配置中会用到,分别用来配置hdfs的data目录、hdfs的namenode目录、hadoop的tmp目录、pid文件存放目录、journalnode存储目录、日志存储目录。yarn下目录用于配置yarn运行的相关目录。
3.6 配置环境变量
export HADOOP_HOME=/opt/hadoop/hadoop-2.8.3
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
3.7 集群配置
涉及文件如下表所示:
文件 | 说明 |
---|---|
hadoop-env.sh | hadoop运行环境配置 |
core-site.xml | Common组件,定义系统级别参数,如hdfs url等 |
hdfs-site.xml | HDFS组件 |
mapred-site.xml | MapReduce组件 |
yarn-site.xml | YARN组件 |
slaves | slaves节点 |
3.7.1 配置hadoop-env.sh
编辑该文件,在文件开始处设置JAVA_HOME环境变量(和/etc/profile中的一致),如:
JAVA_HOME=/opt/jdk/jdk1.8.0_231
完整配置可参考:
# The java implementation to use.
JAVA_HOME=/opt/jdk/jdk1.8.0_231
#export JSVC_HOME=${JSVC_HOME}
export HADOOP_LOGFILE=${USER}-hadoop.log
export HADOOP_ROOT_LOGGER=INFO,DRFA,console
export HADOOP_MAPRED_ROOT_LOGGER=INFO,DRFA,console
export HDFS_AUDIT_LOGGER=WARN,DRFA,console
export HADOOP_SECURITY_LOGGER=INFO,DRFA,console
export HADOOP_CONF_DIR=${HADOOP_CONF_DIR:-"/etc/hadoop"}
export HADOOP_HOME=/opt/hadoop/hadoop-2.8.3
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_HDFS_HOME=$HADOOP_HOME
export HADOOP_YARN_HOME=$HADOOP_HOME
# Extra Java CLASSPATH elements. Automatically insert capacity-scheduler.
for f in $HADOOP_HOME/contrib/capacity-scheduler/*.jar; do
if [ "$HADOOP_CLASSPATH" ]; then
export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$f
else
export HADOOP_CLASSPATH=$f
fi
done
# The maximum amount of heap to use, in MB. Default is 1000.
export HADOOP_HEAPSIZE=3072
#export HADOOP_NAMENODE_INIT_HEAPSIZE=""
# Enable extra debugging of Hadoop's JAAS binding, used to set up
# Kerberos security.
# export HADOOP_JAAS_DEBUG=true
# Extra Java runtime options. Empty by default.
export HADOOP_OPTS="$HADOOP_OPTS -Djava.net.preferIPv4Stack=true"
# Command specific options appended to HADOOP_OPTS when specified
export HADOOP_NAMENODE_OPTS="-XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:GCPauseIntervalMillis=100 -Dhadoop.security.logger=${HADOOP_SECURITY_LOGGER:-WARN,RFAS} -Dhdfs.audit.logger=${HDFS_AUDIT_LOGGER:-WARN,NullAppender} $HADOOP_NAMENODE_OPTS"
export HADOOP_DATANODE_OPTS="-XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:GCPauseIntervalMillis=100 -Dhadoop.security.logger=ERROR,RFAS $HADOOP_DATANODE_OPTS"
export HADOOP_SECONDARYNAMENODE_OPTS="-Dhadoop.security.logger=${HADOOP_SECURITY_LOGGER:-WARN,RFAS} -Dhdfs.audit.logger=${HDFS_AUDIT_LOGGER:-WARN,NullAppender} $HADOOP_SECONDARYNAMENODE_OPTS"
export HADOOP_NFS3_OPTS="$HADOOP_NFS3_OPTS"
export HADOOP_PORTMAP_OPTS="-Xmx3072m $HADOOP_PORTMAP_OPTS"
# The following applies to multiple commands (fs, dfs, fsck, distcp etc)
export HADOOP_CLIENT_OPTS="$HADOOP_CLIENT_OPTS"
# set heap args when HADOOP_HEAPSIZE is empty
if [ "$HADOOP_HEAPSIZE" = "" ]; then
export HADOOP_CLIENT_OPTS="-Xmx3072m $HADOOP_CLIENT_OPTS"
fi
#HADOOP_JAVA_PLATFORM_OPTS="-XX:-UsePerfData $HADOOP_JAVA_PLATFORM_OPTS"
# On secure datanodes, user to run the datanode as after dropping privileges.
# This **MUST** be uncommented to enable secure HDFS if using privileged ports
# to provide authentication of data transfer protocol. This **MUST NOT** be
# defined if SASL is configured for authentication of data transfer protocol
# using non-privileged ports.
export HADOOP_SECURE_DN_USER=${HADOOP_SECURE_DN_USER}
# Where log files are stored. $HADOOP_HOME/logs by default.
export HADOOP_LOG_DIR=/opt/hadoop/hdfs/logs
# Where log files are stored in the secure data environment.
export HADOOP_SECURE_DN_LOG_DIR=${HADOOP_LOG_DIR}/${HADOOP_HDFS_USER}
###
# HDFS Mover specific parameters
###
# Specify the JVM options to be used when starting the HDFS Mover.
# These options will be appended to the options specified as HADOOP_OPTS
# and therefore may override any similar flags set in HADOOP_OPTS
#
# export HADOOP_MOVER_OPTS=""
###
# Advanced Users Only!clusterManager
###
# The directory where pid files are stored. /tmp by default.
# NOTE: this should be set to a directory that can only be written to by
# the user that will run the hadoop daemons. Otherwise there is the
# potential for a symlink attack.
export HADOOP_PID_DIR=/opt/hadoop/hdfs/pid
export HADOOP_SECURE_DN_PID_DIR=${HADOOP_PID_DIR}
# A string representing this instance of hadoop. $USER by default.
export HADOOP_IDENT_STRING=$USER
export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$HADOOP_HOME/share/hadoop/tools/lib/*
#for f in $HADOOP_HOME/share/hadoop/tools/lib/*.jar; do
# if [ "$HADOOP_CLASSPATH" ]; then
# export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$f
# else
# export HADOOP_CLASSPATH=$f
# fi
#done
3.7.2 配置core-site.xml文件
配置可参考:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!-- hdfs的nameservice名称 -->
<!-- 如果配置了NameNode的HA,则使用fs.defaultFS;如果单一NameNode节点,使用fs.default.name -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://ns</value>
</property>
<!--hadoop临时数据存储目录,如果hdfs-site.xml不配置namenode和datanode存储位置,默认放在该目录下-->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/hadoop/hdfs/tmp</value>
</property>
<!--hdfs数据缓冲区大小-->
<property>
<name>io.file.buffer.size</name>
<value>4096</value>
</property>
<!--hdfs垃圾箱(.Trash)创建检查点的时间间隔,应小于或等于fs.trash.interval;默认为0, 由fs.trash.interval项指定 -->
<property>
<name>fs.trash.checkpoint.interval</name>
<value>0</value>
</property>
<!--每次checkpoint时,会删除时间早于fs.trash.interval的检查点-->
<!--该配置可在服务端或客户端配置,服务端配置优先级高于客户端-->
<property>
<name>fs.trash.interval</name>
<value>1440</value>
</property>
<!--zookeeper地址-->
<property>
<name>ha.zookeeper.quorum</name>
<value>hadoop-1:2181,hadoop-2:2181,hadoop-3:2181,hadoop-4:2181</value>
</property>
<!--zookeeper超时时间间隔-->
<property>
<name>ha.zookeeper.session-timeout.ms</name>
<value>2000</value>
</property>
<!--hadoop.proxyuser.$superuser.hosts配置hadoop用户允许通过代理访问的主机节点-->
<property>
<name>hadoop.proxyuser.hadoop.hosts</name>
<value>*</value>
</property>
<!--hadoop.proxyuser.$superuser.groups配置hadoop用户允许通过代理的用户所属组-->
<property>
<name>hadoop.proxyuser.hadoop.groups</name>
<value>*</value>
</property>
<!--压缩和解压的方式-->
<property>
<name>io.compression.codecs</name>
<value>org.apache.hadoop.io.compress.GzipCodec, org.apache.hadoop.io.compress.DefaultCodec, org.apache.hadoop.io.compress.BZip2Codec, org.apache.hadoop.io.compress.SnappyCodec</value>
</property>
</configuration>
3.7.3 配置hdfs-site.xml文件
配置可参考:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!--指定hdfs的nameservice为ns,需要和core-site.xml中的保持一致 -->
<property>
<name>dfs.nameservices</name>
<value>ns</value>
</property>
<!-- ns下面有两个NameNode,分别是nn1,nn2 -->
<property>
<name>dfs.ha.namenodes.ns</name>
<value>nn1,nn2</value>
</property>
<!-- nn1的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.ns.nn1</name>
<value>hadoop-1:9000</value>
</property>
<!-- nn1的http通信地址 -->
<property>
<name>dfs.namenode.http-address.ns.nn1</name>
<value>hadoop-1:50070</value>
</property>
<!-- nn2的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.ns.nn2</name>
<value>hadoop-2:9000</value>
</property>
<!-- nn2的http通信地址 -->
<property>
<name>dfs.namenode.http-address.ns.nn2</name>
<value>hadoop-2:50070</value>
</property>
<!-- 指定NameNode的元数据在JournalNode上的存放位置 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop-3:8485;hadoop-4:8485;hadoop-5:8485/ns</value>
</property>
<!-- 指定JournalNode在本地磁盘存放数据的位置 -->
<!-- 在journalNode机器上要建立该目录 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/opt/hadoop/hdfs/journalnode</value>
</property>
<!-- 开启NameNode故障时自动切换 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<!-- 配置失败自动切换实现方式 -->
<property>
<name>dfs.client.failover.proxy.provider.ns</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>
<!-- 使用隔离机制时需要ssh免登陆 -->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/root/.ssh/id_rsa</value>
</property>
<!-- namenode存储位置 -->
<property>
<name>dfs.namenode.name.dir</name>
<value>/opt/hadoop/hdfs/name</value>
</property>
<!-- dataode存储位置 -->
<property>
<name>dfs.datanode.data.dir</name>
<value>/opt/hadoop/hdfs/data</value>
</property>
<!-- 副本数量根据自己的需求配置,这里配置2个 -->
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
<!-- 在NN和DN上开启WebHDFS (REST API)功能,不是必须 -->
<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
</property>
<!-- 在dfsclient中记录慢io警告的阈值-->
<property>
<name>dfs.client.slow.io.warning.threshold.ms</name>
<value>90000</value>
</property>
<!-- datanode的心跳时间间隔,单位为秒-->
<property>
<name>dfs.heartbeat.interval</name>
<value>8</value>
</property>
<!-- 心跳检测的时间间隔,单位是毫秒-->
<property>
<name>dfs.namenode.heartbeat.recheck-interval</name>
<value>90000</value>
</property>
<!-- namenode的checkpoint周期,单位秒。HA部署时,每经过一个周期,standby节点进行fsimage和editlog的合并-->
<property>
<name>dfs.namenode.checkpoint.preiod</name>
<value>3600</value>
</property>
<!-- namenode的checkpoint的最大操作次数。HA部署时,hdfs操作次数超过这个数量,standby节点进行fsimage和editlog的合并-->
<property>
<name>dfs.namenode.checkpoint.txns</name>
<value>1000000</value>
</property>
<!--块报告的时间间隔,单位是毫秒-->
<property>
<name>dfs.blockreport.intervalMsec</name>
<value>1800000</value>
</property>
<!--datanode以秒为单位扫描数据目录,并协调内存块和磁盘上的块之间的差异-->
<property>
<name>dfs.datanode.directoryscan.interval</name>
<value>1800</value>
</property>
<property>
<name>dfs.datanode.max.xcievers</name>
<value>8000</value>
</property>
<!-- 命名一个文件,该文件包含允许连接到namenode的主机列表点。必须指定文件的完整路径名。如果值为空,则允许所有主机。-->
<property>
<name>dfs.hosts</name>
<value>/opt/hadoop/hadoop-2.8.3/etc/hadoop/slaves</value>
</property>
<!-- 命名一个文件,该文件包含不允许连接到namenode的主机列表。必须指定文件的完整路径名。如果值为空,则不排除任何主机。
<property>
<name>dfs.hosts.exclude</name>
<value>/usr/local/service/hadoop/etc/hadoop/hdfsexcludedhosts</value>
</property>
-->
<!-- 每个DataNode平衡操作所允许的最大使用带宽,单位是byte.这个参数在守护进程启动的时候读入,管理员无法在平衡运行时来修改这个值,重启hdfs后生效:stop-dfs.sh start-dfs.sh-->
<property>
<name>dfs.balance.bandwidthPerSec</name>
<value>10485760</value>
</property>
<!-- 新文件的块大小,单位为字节.可使用后缀:k(kilo), m(mega), g(giga), t(tera), p(peta), e(exa) -->
<property>
<name>dfs.blocksize</name>
<value>67108864</value>
</property>
<!-- RPC服务器的监听client线程数 -->
<property>
<name>dfs.namenode.handler.count</name>
<value>64</value>
</property>
<!-- datanode进行传输数据的最大线程数 -->
<property>
<name>dfs.datanode.max.transfer.threads</name>
<value>36867</value>
</property>
<!-- 线程池中用于编制卷报告的线程数。 -->
<property>
<name>dfs.datanode.directoryscan.threads</name>
<value>18</value>
</property>
<!-- datanode的服务器线程数-->
<property>
<name>dfs.datanode.handler.count</name>
<value>128</value>
</property>
<!--在datanode中记录慢io警告的阈值-->
<property>
<name>dfs.datanode.slow.io.warning.threshold.ms</name>
<value>1000</value>
</property>
</configuration>
3.7.4 创建并修改mapred-site.xml文件
先执行下面命令创建mapred-site.xml文件。
cp mapred-site.xml.template mapred-site.xml
编辑该文件,配置可参考:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!--用于执行MapReduce作业的运行时框架。可以是本地,classic或yarn之一-->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!--mapred做本地计算的目录,可配置多块硬盘用逗号分隔-->
<property>
<name>mapred.local.dir</name>
<value>/opt/hadoop/yarn/local</value>
</property>
<!--Map Task 的 JVM 参数-->
<property>
<name>mapreduce.map.java.opts</name>
<value>-Xmx4096m</value>
</property>
<!--一个 Map Task 可使用的内存上限,单位MB,默认1024,如果 Map Task 实际使用的资源量超过该值,则会被强制杀死-->
<property>
<name>mapreduce.map.memory.mb</name>
<value>4096</value>
</property>
<!--Reduce Task 的 JVM 参数-->
<property>
<name>mapreduce.reduce.java.opts</name>
<value>-Xmx4096m</value>
</property>
<!--一个 Reduce Task 可使用的内存上限,单位MB,默认1024,如果 Reduce Task 实际使用的资源量超过该值,则会被强制杀死-->
<property>
<name>mapreduce.reduce.memory.mb</name>
<value>4096</value>
</property>
<!--<property>
<name>local.cache.size</name>
<value>10737418240</value>
</property>-->
<!--mapreduce.jobhistory.cleaner.interval-ms 作业历史记录清理程序检查要删除的文件的频率(以毫秒为单位)。默认为86400000(一天)。仅当文件早于mapreduce.jobhistory.max-age-ms时才会删除文件-->
<property>
<name>mapreduce.jobhistory.cleaner.interval-ms</name>
<value>604800000</value>
</property>
<!--作业列表缓存的大小,默认20000-->
<property>
<name>mapreduce.jobhistory.joblist.cache.size</name>
<value>20000</value>
</property>
<!--日期字符串缓存的大小。影响将扫描以查找作业的目录数-->
<property>
<name>mapreduce.jobhistory.datestring.cache.size</name>
<value>200000</value>
</property>
<property>
<name>mapreduce.jobhistory.cleaner.enable</name>
<value>true</value>
</property>
<!--运行历史记录清理程序时,将删除早于此毫秒的作业历史记录文件。默认为604800000(1周)-->
<property>
<name>mapreduce.jobhistory.max-age-ms</name>
<value>604800000</value>
</property>
</configuration>
3.7.5 修改yarn-site.xml文件
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 开启集群高可用(HA)-->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!-- 指定RM的cluster id -->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>hdcluster</value>
</property>
<!-- 指定RM的节点id-->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<!-- 指定RM节点的host-->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>hadoop-1</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>hadoop-2</value>
</property>
<!-- 指定RM节点web http地址的host和port-->
<property>
<name>yarn.resourcemanager.webapp.address.rm1</name>
<value>hadoop-1:8088</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm2</name>
<value>hadoop-2:8088</value>
</property>
<!-- 指定RM节点web https地址的host和port-->
<property>
<name>yarn.resourcemanager.webapp.https.address.rm1</name>
<value>hadoop-1:5005</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.https.address.rm2</name>
<value>hadoop-2:5005</value>
</property>
<!-- 指定RM节点调度程序接口的地址-->
<property>
<name>yarn.resourcemanager.scheduler.address.rm1</name>
<value>hadoop-1:5001</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address.rm2</name>
<value>hadoop-2:5001</value>
</property>
<!--指定RM管理界面的地址 -->
<property>
<name>yarn.resourcemanager.admin.address.rm1</name>
<value>hadoop-1:5003</value>
</property>
<property>
<name>yarn.resourcemanager.admin.address.rm2</name>
<value>hadoop-2:5003</value>
</property>
<!-- 指定zk地址-->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>hadoop-1:2181,hadoop-2:2181,hadoop-3:2181,hadoop-4:2181</value>
</property>
<!--等待节点管理器被认为已经死亡的时间,默认10分钟-->
<property>
<name>yarn.nm.liveness-monitor.expiry-interval-ms</name>
<value>100000</value>
</property>
<!--是否使用用户名关联分配的默认队列名称,如果是false或者未设置,所有的作业都有一个共享的默认队列,叫做default。默认是true, 如果是true,当任务中未指定资源池的时候,将以用户名作为资源池名。这个配置就实现了根据用户名自动分配资源池。-->
<property>
<name>yarn.scheduler.fair.user-as-default-queue</name>
<value>false</value>
</property>
<!--容器执行类-->
<property>
<name>yarn.nodemanager.container-executor.class</name>
<value>org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor</value>
</property>
<!--是否将对容器强制实施物理内存限制。-->
<property>
<name>yarn.nodemanager.pmem-check-enabled</name>
<value>true</value>
</property>
<!--是否启用自动故障转移-->
<property>
<name>yarn.resourcemanager.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<!--用于放置YARN的cgroups层次结构(不能包含逗号)-->
<!--<property>
<name>yarn.nodemanager.linux-container-executor.cgroups.hierarchy</name>
<value>/hadoop-yarn</value>
</property>-->
<!--yarn.nodemanager.resource.memory-mb 可以为容器分配的物理内存量(MB)。如果设置为-1且yarn.nodemanager.resource.detect-hardware-capabilities为true,则会自动计算(如果是Windows和Linux)。在其他情况下,默认值为8192MB-->。
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>4096</value>
</property>
<!--<property>
<name>yarn.resourcemanager.nodes.include-path</name>
<value>/opt/hadoop/yarn/yarnhosts</value>
</property>-->
<!--<property>
<name>yarn.resourcemanager.nodes.exclude-path</name>
<value>/opt/hadoop/yarn/yarnexcludedhosts</value>
</property>-->
<!--RM中每个容器请求的最大分配内存,以MB为单位。高于此的内存请求将抛出InvalidResourceRequestException-->。
<property>
<name>yarn.scheduler.maximum-allocation-mb</name>
<value>12288</value>
</property>
<!--就虚拟CPU核心而言,RM上每个容器请求的最大分配。高于此的请求将抛出InvalidResourceRequestException-->
<property>
<name>yarn.scheduler.maximum-allocation-vcores</name>
<value>32</value>
</property>
<!--schelduler失联等待连接时间-->
<property>
<name>yarn.app.mapreduce.am.scheduler.connection.wait.interval-ms</name>
<value>5000</value>
</property>
<!--启动后启用RM以恢复状态。如果为true,则必须指定yarn.resourcemanager.store.class-->
<property>
<name>yarn.resourcemanager.recovery.enabled</name>
<value>true</value>
</property>
<!--用作RM状态存储方式储的类-->
<property>
<name>yarn.resourcemanager.store.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
</property>
<!--rm失联后重新链接的时间间隔-->
<property>
<name>yarn.resourcemanager.connect.retry-interval.ms</name>
<value>2000</value>
</property>
<!--NM通过该地址交换信息-->
<property>
<name>yarn.resourcemanager.resource-tracker.address.rm1</name>
<value>hadoop-1:5002</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address.rm2</name>
<value>hadoop-2:5002</value>
</property>
<!--ZKRMStateStore连接的zk地址-->
<property>
<name>yarn.resourcemanager.zk.state-store.address</name>
<value>hadoop-1:2181,hadoop-2:2181,hadoop-3:2181,hadoop-4:2181</value>
</property>
<!--设置容器的内存限制时虚拟内存与物理内存之间的比率-->
<property>
<name>yarn.nodemanager.vmem-pmem-ratio</name>
<value>8</value>
</property>
<!--是否启用日志聚合.日志聚合收集每个容器的日志,并在应用程序完成后将这些日志移动到文件系统,例如HDFS。用户可以配置“yarn.nodemanager.remote-app-log-dir”和“yarn.nodemanager.remote-app-log-dir-suffix”属性以确定这些日志的移动位置。用户可以通过应用程序时间线服务器访问日志。-->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<!--日志聚合服务器的URL-->
<property>
<name>yarn.log.server.url</name>
<value>http://hadoop-1:19888/jobhistory/logs</value>
</property>
<!--聚合日志保留时间-->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>604800</value>
</property>
<property>
<name>yarn.nodemanager.log-dirs</name>
<value>/opt/hadoop/yarn/logs</value>
</property>
<!--application执行结束后延迟该时间删除文件及日志,单位s-->
<property>
<name>yarn.nodemanager.delete.debug-delay-sec</name>
<value>600</value>
</property>
<!--NN上日志聚集的位置(聚合日志后在hdfs的存放地址-->
<property>
<name>yarn.nodemanager.remote-app-log-dir</name>
<value>/yarn-logs</value>
</property>
<!--hdfs上集合日志后的存放地址由 ${remote-app-log-dir}/${user}/{thisParam}构成-->
<property>
<name>yarn.nodemanager.remote-app-log-dir-suffix</name>
<value>logs</value>
</property>
<!--存储本地化文件的目录列表。应用程序的本地化文件目录位于:$ {yarn.nodemanager.local-dirs} / usercache / $ {user} / appcache / application _ $ {appid}。单个容器的工作目录(称为container _ $ {contid})将是其子目录-->
<property>
<name>yarn.nodemanager.local-dirs</name>
<value>/opt/hadoop/yarn/local</value>
</property>
<!--默认为/tmp/hadoop-yarn/staging。MR作业在提交时所使用的临时目录, 是一个本地路径-->
<property>
<name>yarn.app.mapreduce.am.staging-dir</name>
<value>/opt/hadoop/yarn/staging</value>
</property>
<property>
<name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
<value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value>
</property>
<!--<property>
<name>yarn.acl.enable</name>
<value>true</value>
</property>-->
<!--可以为容器分配的vcores数。在为容器分配资源时,RM调度程序使用它。这不用于限制YARN容器使用的CPU数量。如果设置为-1且yarn.nodemanager.resource.detect-hardware-capabilities为true,则在Windows和Linux的情况下会自动从硬件确定。在其他情况下,默认情况下,vcores的数量为8。-->
<property>
<name>yarn.nodemanager.resource.cpu-vcores</name>
<value>8</value>
</property>
<!--最大应用程序尝试次数。它是所有应用程序master的全局设置。每个应用程序主机都可以通过API指定其各自的最大应用程序尝试次数,但是单个数字不能超过全局上限。如果是,资源管理器将覆盖它。默认数量设置为2,以允许至少一次重试AM。-->
<property>
<name>yarn.resourcemanager.am.max-attempts</name>
<value>5</value>
</property>
<!--RM中每个容器请求的最小分配(MB)内存-->
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>128</value>
</property>
<!--用于YarnAuthorizationProvider的类-->
<!--<property>
<name>yarn.authorization-provider</name>
<value>org.apache.ranger.authorization.yarn.authorizer.RangerYarnAuthorizer</value>
</property> -->
<!--启用嵌入式自动故障转移。默认情况下,仅在启用HA时启用它。嵌入式选举器依赖RM状态存储来处理防护,主要用于与ZKRMStateStore结合使用。-->
<property>
<name>yarn.resourcemanager.ha.automatic-failover.embedded</name>
<value>true</value>
</property>
<!--群集中每个NodeManager的心跳间隔(以毫秒为单位)-->
<property>
<name>yarn.resourcemanager.nodemanagers.heartbeat-interval-ms</name>
<value>1000</value>
</property>
<!--linux-container-executor应该运行的UNIX组-->
<property>
<name>yarn.nodemanager.linux-container-executor.group</name>
<value>hadoop</value>
</property>
<property>
<name>yarn.nodemanager.resource.percentage-physical-cpu-limit</name>
<value>100</value>
</property>
<property>
<name>yarn.scheduler.minimum-allocation-vcores</name>
<value>1</value>
</property>
<!--日志的保留时间,log aggregation没有enable时,有效-->
<property>
<name>yarn.nodemanager.log.retain-seconds</name>
<value>604800</value>
</property>
<!--是否将对容器强制实施虚拟内存限制-->
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
<!--RM保留的已完成应用程序的最大数量。-->
<property>
<name>yarn.resourcemanager.max-completed-applications</name>
<value>150</value>
</property>
<!--<property>
<name>yarn.scheduler.fair.allow-undeclared-pools</name>
<value>false</value>
</property>-->
<!--在聚合日志保留检查之间等待多长时间。如果设置为0或负值,则该值将计算为聚合日志保留时间的十分之一。-->
<property>
<name>yarn.log-aggregation.retain-check-interval-seconds</name>
<value>604800</value>
</property>
<!--<property>
<name>yarn.nodemanager.linux-container-executor.nonsecure-mode.local-user</name>
<value>hadoop</value>
</property>-->
<!--帮助linux-container-executor处理资源的类-->
<property>
<name>yarn.nodemanager.linux-container-executor.resources-handler.class</name>
<value>org.apache.hadoop.yarn.server.nodemanager.util.DefaultLCEResourcesHandler</value>
</property>
</configuration>
3.7.6 修改slaves文件
该文件配置hdfs的数据存储节点(datanodes):
hadoop-3
hadoop-4
hadoop-5
3.8 集群初始化和启动
# 1. 启动zookeeper集群(hadoop-1、hadoop-2、hadoop-3、hadoop-4)
zkServer.sh start
#运行jps命令,对应机器多了QuorumPeerMain的进程
# 2. 启动journalnode(hadoop-3、hadoop-4、hadoop-5)
hadoop-daemon.sh start journalnode
#运行jps命令可以看到多了JournalNode进程
#ps: 在任意一台机器启动会远程拉起所有机器的进程
# 3. 格式化namenode(hadoop-1)
hdfs namenode -format
# 4. 格式化ZKFC(初始化 HA 状态到 zk)(hadoop-1)
hdfs zkfc -formatZK
# 5. 启动 namenode1(hadoop-1)
hadoop-daemon.sh start namenode
#运行jps命令可以看到多了NameNode进程
# 6. 同步 namenode(hadoop-2)
hdfs namenode -bootstrapStandby
# 7. 启动 namenode2(hadoop-2)
hadoop-daemon.sh start namenode
#运行jps命令可以看到多了NameNode进程
# 8. 启动ZookeeperFailoverController(hadoop-1,hadoop-2)
hadoop-daemon.sh start zkfc
#运行jps命令可以看到多了DFSZKFailoverController进程.
#哪台机器先启动zkfc,哪台就是active
# 9. 启动 datanode(hadoop-3、hadoop-4、hadoop-5)
hadoop-daemon.sh start datanode
#运行jps命令,多了DataNode进程
# 10. 启动 resourcemanager(hadoop-2,hadoop-1)
yarn-daemon.sh start resourcemanager
#启动时先启动hadoop-2的rm,这样将hadoop-2的rm置为active(也可以通过命令手动切换)
#运行jps,多了ResourceManager进程
# 11. 启动 nodemanager(hadoop-3、hadoop-4、hadoop-5)
yarn-daemon.sh start nodemanager
#运行jps,多了NodeManager进程
# 12. 启动 historyserver(hadoop-1,hadoop-2)
mr-jobhistory-daemon.sh start historyserver
#运行jps,多了JobHistoryServer进程
3.9 集群日常启动与关闭
上述流程为刚初始化并启动集群的流程,日常启动无需格式化NameNode,否则数据会丢失。
3.9.1 正常的启动顺序
# 1. 启动 zookeeper(hadoop-1~hadoop-4)
zkServer.sh start
# 2. 启动 journalnode(hadoop-3~hadoop-5)
hadoop-daemons.sh start journalnode
# 3. 启动 namenode(hadoop-1, hadoop-2)
hadoop-daemon.sh start namenode
# 4. 启动ZookeeperFailoverController(hadoop-1,hadoop-2)
hadoop-daemon.sh start zkfc
#ps: 哪台机器先启动zkfc,哪台就是active
# 5. 启动 datanode(hadoop-3~hadoop-5)
hadoop-daemons.sh start datanode
# 6. 启动 resourcemanager(hadoop-2,hadoop-1)
yarn-daemon.sh start resourcemanager
#ps: 先启动的为active
# 7. 启动 nodemanager(hadoop-3~hadoop-5)
yarn-daemon.sh start nodemanager
# 8. 启动 historyserver(hadoop-1,hadoop-2)
mr-jobhistory-daemon.sh start historyserver
上述流程的6和7可以改为:先在某个RM节点上运行start-yarn.sh
(启动active RM和所有NM),再在另一个RM节点上运行yarn-daemon.sh start resourcemanager
(启动standby RM)
3.9.2 正常的关闭顺序
在开启相关服务的机器上执行:
# 1. 关闭 historyserver(hadoop-1,hadoop-2)
mr-jobhistory-daemon.sh stop historyserver
# 2. 关闭 nodemanager(hadoop-3~hadoop-5)
yarn-daemon.sh stop nodemanager
# 3. 关闭 resourcemanager(hadoop-2,hadoop-1)
yarn-daemon.sh stop resourcemanager
# 4. 关闭 datanode (hadoop-3~hadoop-5)
hadoop-daemons.sh stop datanode
# 5. 关闭 ZookeeperFailoverController (hadoop-1,hadoop-2)
hadoop-daemon.sh stop zkfc
# 6. 关闭 namenode(hadoop-1, hadoop-2
hadoop-daemon.sh stop namenode
# 7. 关闭 journalnode(hadoop-3~hadoop-5)
hadoop-daemons.sh stop journalnode
# 8. 关闭 zookeeper(hadoop-1~hadoop-4)
zkServer.sh stop
上述流程的2和3可以改为:现在standby RM上执行yarn-daemon.sh stop resourcemanager
(关闭standby RM),再在active RM上执行stop-yarn.sh
(关闭active RM和所有NM).
四、验证高可用
相关命令:
# hdfs查看nn命令
hdfs haadmin -getServiceState nn1
# hdfs 切换为active命令
hdfs haadmin -transitionToActive --forcemanual nn1
# hdfs 切换为standby命令
hdfs haadmin -transitionToStandby --forcemanual nn2
# yarn查看rm命令
yarn rmadmin -getServiceState rm1
# yarn切换为 standby 状态
yarn rmadmin -transitionToStandby --forcemanual rm2
# yarn切换为 active 状态
yarn rmadmin -transitionToActive --forcemanual rm1
验证方法:在active NameNode节点将NameNode kill掉,看standby NameNode是否变成active状态;active Resoucemanager 节点将Resoucemanager进程kill掉,看standby Resoucemanager是否变成active状态。