目录
目录 1
1. 前言 3
2. 缩略语 3
3. 安装步骤 4
4. 下载安装包 4
5. 机器规划 4
6. 设置批量操作参数 5
7. 环境准备 5
7.1. 修改最大可打开文件数 5
7.2. 修改OOM相关参数 6
7.3. 免密码登录设置 6
7.4. 修改主机名 6
7.4.1. 临时修改主机名 6
7.4.2. 永久修改主机名 7
7.4.3. 批量修改主机名 7
7.4.4. 配置/etc/hosts 7
8. 安装建议 8
9. 创建安装用户组和用户 8
10. 安装JDK 8
11. 安装Zookeeper 9
11.1. 设置批量操作参数 9
11.2. 上传Zookeeper安装包到/data目录 9
11.3. 解压和安装Zookeeper 9
11.4. 创建Zookeeper数据目录和日志目录 10
11.5. 设置Zookeeper的myid文件 10
11.6. 创建和修改conf/zookeeper-env.sh 10
11.7. 修改conf/log4j.properties 11
11.8. 修改conf/java.env 11
11.9. 设置环境变量PATH 11
11.10. 修改Zookeeper的配置文件zoo.cfg 11
11.11. 启动Zookeeper 13
11.11.1. 批量手工启动Zookeeper 13
11.11.2. Crontab自动启动Zookeeper 13
11.11.3. 安装验证Zookeeper 13
12. 安装Hadoop 14
12.1. 设置批量操作参数 14
12.2. 上传Hadoop安装包到/data目录 14
12.3. 解压和安装Hadoop 14
12.4. 修改hadoop-env.sh 14
12.5. 修改slaves 15
12.6. 修改log4j.properties 15
12.7. 准备各配置文件 15
12.8. 修改core-site.xml 16
12.9. 修改hdfs-site.xml 17
12.10. 修改yarn-site.xml 22
12.11. 修改mapred-site.xml 26
12.12. 设置环境变量 28
12.13. 创建本地目录 29
13. 启动HDFS 29
13.1. 创建主备切换命名空间 29
13.2. 启动JournalNode集群 31
13.3. 格式化NameNode 31
13.4. 启动主NameNode 33
13.5. 查看NameNode主备状态 34
13.6. 启动主备切换进程zkfc 35
13.7. 启动备NameNode 35
13.8. 启动所有DataNode 36
13.9. 检查DataNode状态 36
13.10. 手动切换NameNode主备 37
14. 启动YARN 37
14.1. 启动ResourceManager 37
14.2. 启动NodeManager 37
14.3. 启动HistoryServer 38
14.4. 停止HistoryServer 38
15. 常用HDFS命令 38
15.1. hdfs dfs ls 38
15.2. hdfs dfs -put 38
15.3. hdfs dfs -rm 39
15.4. 查看文件分布在哪些节点 39
15.5. 关闭安全模式 39
15.6. 删除missing blocks 39
15.7. 强制DataNode上报块信息 39
15.8. 扩容和下线 39
15.8.1. 新增JournalNode 39
15.8.2. 新增NameNode 40
15.8.3. 扩容DataNode 41
15.8.4. 下线DataNode 42
16. YARN命令 44
16.1. 查看节点列表:yarn node -list 44
16.2. 查看节点状态:yarn node -status 44
16.3. 查看状态:yarn rmadmin -getServiceState rm1 44
16.4. 人工切换:yarn rmadmin -transitionToStandby rm1 44
16.5. 查看应用列表:yarn application --list 45
16.6. 查看作业列表:hadoop job -list 45
17. 运行MapReduce程序 45
附1:crontab监控脚本 46
附2:批量操作工具 47
附3:JVM基础知识 48
1)JPS命令 48
2)JVM内存 48
3)JVM GC(Garbage Collection,垃圾回收) 49
4)并行和并发 49
5)JVM的CMS垃圾回收 49
6)JVM内存参数 50
1. 前言
截至本文撰写时(2019/9/17日),Hadoop最高版本为3.2.0,但适用于生产环境的为3.1.2(9月22日发布了可用于生产环境的3.2.1版本),本文只介绍3.1.2版本的分布式安装,不包含单机版安装。适用于Hadoop-3.1.3版本,所操作的环境为CentOS-7.2,对应的Linux内核版本为3.10,不同的Linux可能略有区别。
为提升安装效率,本文的安装过程使用了批量命令工具和批量上传文件工具。批量操作工具的下载和使用,请参见《附2:批量操作工具》。
2. 缩略语
缩略语 |
全写 |
说明 |
JVM |
Java Virtual Matchine |
Java虚拟机 |
jps |
JVM Process Status |
Java虚拟机进程状态工具 |
HDFS |
Hadoop Distributed File System |
Hadoop分布式文件系统 |
NN |
NameNode |
名字节点 |
DN |
DataNode |
数据节点 |
JN |
JournalNode |
日志节点 |
YARN |
YetAnother Resource Negotiator |
|
RM |
Resource Manager |
YARN的资源管理器 |
AM |
Application Master |
|
RS |
Resource Scheduler |
资源调度器 |
MR |
Map Reduce |
|
zk |
Zookeeper |
3. 安装步骤
安装步骤可分解为以下几大步:
1) 下载安装包
2) 设置批量操作参数
3) 环境准备
4) 创建安装用户组和用户
5) 安装JDK
6) 安装Zookeeper
7) 安装Hadoop
每一大步又可分解为几个小步,具体有哪些小步参见各大步的说明。推荐使用批量命令工具mooon_ssh和批量上传文件工具mooon_upload完成各步安装。
4. 下载安装包
从零安装Hadoop,需要下载三个安装包,按照先后顺序分别是:
版本 |
下载链接 |
说明 |
|
批量工具 |
https://github.com/eyjian/libmooon/releases |
批量命令工具和批量上传文件工具 |
|
JDK |
1.8 |
http://www.oracle.com/technetwork/java/javase/downloads |
下载需要登录Oracle帐号 |
Zookeeper |
3.5.5 |
http://zookeeper.apache.org/releases.html |
官方推荐用于生产环境的最新版本 |
Hadoop |
3.1.2 |
https://hadoop.apache.org/releases.html |
Hadoop依赖Zookeeper |
5. 机器规划
以7台机器为本文的操作示例:
序号 |
IP |
主机名 |
角色 |
备注 |
1 |
192.168.1.21 |
hadoop-001 |
Master |
这2台用来做Master,部署HDFS的NameNode和YARN的ResourceManager,如果机器数不够,则Master可和Slave共用相同机器。 |
2 |
192.168.1.22 |
hadoop-002 |
||
3 |
192.168.1.23 |
hadoop-003 |
Slave |
这5台用来做HDFS的DataNode,以及组成5台机器组成的Zookeeper集群和5台机器组成的JournalNode集群。 |
4 |
192.168.1.24 |
hadoop-004 |
||
5 |
192.168.1.25 |
hadoop-005 |
||
6 |
192.168.1.26 |
hadoop-006 |
||
7 |
192.168.1.27 |
hadoop-007 |
6. 设置批量操作参数
如果不使用批量工具mooon_ssh和mooon_upload,则可用其它熟悉的工具替代,或者手工一台台操作。
export U=root # 以root用户安装JDK,否则没的操作目录/usr/local权限 export P=‘123456‘ # 用户root的密码 export H=‘192.168.1.21,192.168.1.22,192.168.1.23,192.168.1.24,192.168.1.25,192.168.1.26,192.168.1.27‘ # 逗号分隔的目标机器列表,注意Zookeeper和JournalNode只涉及其中5个 export THR=0 # 可选设置,但设置THR为0可多台机器并行操作 |
7. 环境准备
环境准备包含的子步骤:
1) 修改最大可打开文件数(建议调大)
2) 修改OOM参数(建议关闭Overcommit)
3) 免密码登录设置(可选,但建议NameNode间免密码登录)
4) 修改主机名(建议规范和统一主机命名)
7.1. 修改最大可打开文件数
这一步也不是必须的,可执行命令“ulimit -n”查看当前值是多少,如果值偏小则建议调大些,比如64G内存机器可设置为100000(甚至更大的值),但一般1024有点偏小。
修改方法是编辑文件/etc/security/limits.conf,调整其中的“soft nofile”和“hard nofile”两项值,如果此两项值不存在则应新增,可以limits.conf文件尾部新增这两项。
* soft nofile 100000 * hard nofile 100000 # End of file |
上述的“*”表示对所有用户运行的进程有效,也可限定只对运行Hadoop的用户有效,比如运行Hadoop的用户名为hadoop,则可如下这样设置:
hadoop soft nofile 100000 hadoop hard nofile 100000 # End of file |
limits.conf如何生效,请参见博文《源码解读Linux的limits.conf文件》,博文链接为:https://blog.csdn.net/Aquester/article/details/86694644,最省事的生效方法是重启系统。
7.2. 修改OOM相关参数
这一步也不是必须的,但一般建议将/proc/sys/vm/overcommit_memory值设置为1,以关闭系统的Overcommit,注意并不是关闭OOM,OOM由/proc/sys/vm/panic_on_oom控制。关于OOM更深入的介绍,可浏览博文《Linux OOM一二三》,对应的博文链接为:https://blog.csdn.net/Aquester/article/details/100543346。
# cat /proc/sys/vm/overcommit_memory 0 |
设置方法为编辑文件/etc/sysctl.conf,添加以下内容:
vm.overcommit_memory=1 |
修改好后再执行命令“sysctl -p”以使生效。
7.3. 免密码登录设置
这一步也不是必须的,有关设置可参考下列四篇博文,如果不知道是什么SSH,可执行“ssh -V”可看。
但进建议同一集群内的NameNode间可互免密码登录,以方便设置dfs.ha.fencing.methods及相关参数。
两个openssh间免密码登录 |
https://blog.csdn.net/Aquester/article/details/50013871 |
两个SSH2间免密码登录 |
http://blog.chinaunix.net/uid-20682147-id-4212099.html |
SSH2免密码登录OpenSSH |
http://blog.chinaunix.net/uid-20682147-id-4212097.html |
OpenSSH免密码登录SSH2 |
http://blog.chinaunix.net/uid-20682147-id-4212094.html |
7.4. 修改主机名
这一步不是必须的,只有主机名不满足Hadoop要求时才必须执行,不过建议同一Hadoop集群内的主机名有统一的命名规范,以方便运维和管理。
Hadoop要求主机名不能包含下划线,所以这一步需要解决这个问题。主机名的修改分临时修改和永久修改,临时修改在系统重启后失效,而永久修改在系统重启后依然有效。
7.4.1. 临时修改主机名
使用系统自带的命令hostname即可临时性修改主机名,比如将主机名改为hadoop001,只需执行下列命令即可:
hostname hadoop001 |
7.4.2. 永久修改主机名
为保证系统重启后依旧有效,永久修改是必须的。对于CentOS,永久性修改主机名的方法是编辑文件/etc/hostname,将新的主机名写入到此文件中,如:
# cat /etc/hostname Hadoop001 |
注意,不是所有的Linux发行版本都是修改/etc/hostname文件,比如SuSE对应的是/etc/HOSTNAME。如果不做临时修改,则在修改/etc/hostname后需要重启系统,否则不会生效。
7.4.3. 批量修改主机名
当机器数量多时,一台台修改主机名效率低,也容易出错。可使用工具set_hostname.sh批量修改。set_hostname.sh通过修改文件/etc/hostname来修改主机名,如果主机名文件不是hostname,则应当修改set_hostsname.sh后再用,将set_hostname.sh中的变量hostname_file修改为合适的值即可,比如如果是SuSE:hostname_file=/etc/HOSTNAME。
使用set_hostname.sh前,需准备一个IP和主机名映射文件,可命名为hosts.name如:
# cat hosts.name 192.168.1.21 hadoop-001 192.168.1.22 hadoop-002 192.168.1.23 hadoop-003 192.168.1.24 hadoop-004 192.168.1.25 hadoop-005 192.168.1.26 hadoop-006 192.168.1.27 hadoop-007 |
将工具文件set_hostname.sh和映射文件hosts.name都上传到目标机器的tmp目录。
mooon_upload -d=/tmp -s=hosts.name,set_hostname.sh |
批量远程执行set_hostname.sh,完成主机名的修改。
mooon_ssh -c=‘/tmp/set_hostname.sh /tmp/hosts.name‘ |
查看修改结果:
mooon_ssh -c=‘hostname‘ |
7.4.4. 配置/etc/hosts
IP和主机名的映射关系需写入到文件/etc/hosts中,推荐在一台机器完成后,再批量发布到其它机器。
8. 安装建议
建议JDK用root用户安装,Zookeeper用名为zk的用户安装,Hadoop用名为hadoop的用户安装,hbase用名为hbase的用户安装。同时,可以考虑建一个名为supergroup的用户组,将zk、hadoop和hbase都置于该用户组中,以方便管理。或者修改dfs.permissions.supergroup,以变更用户组名。
9. 创建安装用户组和用户
为方便管理,创建用户组hadoop,并分别为Zookeeper和Hadoop创建用户名zk和hadoop。注意用户名字符数不要超过8个,否则ps等命令将显示用户ID,而不是用户名,因此不能取名zookeeper。
以root用户,批量创建即可:
mooon_ssh -c=‘groupadd supergroup‘ # 创建用户组supergroup,建议这个名和hdfs-site.xml中的dfs.permissions.supergroup值一致 mooon_ssh -c=‘useradd -g supergroup -m zk‘ # 创建Zookeeper运行用户zk mooon_ssh -c=‘useradd -g supergroup -m hadoop‘ # 创建Hadoop运行用户hadoop mooon_ssh -c=‘echo "zk:123456"|chpasswd‘ # 设置用户zk的密码为123456 mooon_ssh -c=‘echo "hadoop:123456"|chpasswd‘ # 设置用户hadoop的密码为123456 |
如果使用不同的用户运行HBase,则最好保持相同的用户组,这样不容易遇到权限问题。
10. 安装JDK
本文使用的JDK安装包文件名为jdk-8u221-linux-x64.tar.gz,推荐将安装包文件上传到目标机器的/usr/local目录。
1) 批量上传jdk安装包到目标机器的/usr/local目录
mooon_upload -s=jdk-8u221-linux-x64.tar.gz -d=/usr/local |
2) 解压和安装JDK
mooon_ssh -c=‘cd /usr/local;tar xzf jdk-8u221-linux-x64.tar.gz;ln -s jdk1.8.0_221 jdk‘ |
3) 添加和更新环境变量
不建议直接修改/etc/profile文件,而应采取在目录/etc/profile.d下新建一文件方式,可将这文件命名为jdk.sh,文件内容如下:
$ cat jdk.sh JAVA_HOME=/usr/local/jdk export CLASSPATH=$JAVA_HOME/lib/tools.jar export PATH=$JAVA_HOME/bin:$PATH |
可先在操作机上创建好jdk.sh,可不添加可执行权限。然后用批量工具上传到目标机器的/etc/profile.d目录,如:
mooon_upload -s=jdk.sh -d=/etc/profile.d |
注意,重新登录环境变量才会生效。按照步骤来,这一步一般不会有什么问题。至此,JDK的安装顺利完成。
11. 安装Zookeeper
Hadoop依赖Zookeeper,所以在安装Hadoop前需先安装好Zookeeper。不推荐将Zookeeper和Hadoop也安装在/usr/local目录,因为生产环境的机器该目录所在分区不一定足够大,本文操作将Zookeeper安装到/data目录。
如果Zookeeper的机器和JDK机器不完全一致,则应当重新设置环境变量H,或者批量工具参数“-h”指定Zookeeper机器列表。
由于Zookeeper的ZAB协议是一个多数派协议,因此组成集群的节点数应当为奇数个,且不少于三个节点组成(四个节点和三个节点的容灾效果相同,但反而降低了效率)。
11.1. 设置批量操作参数
# 只涉及7个中的5个 export H=‘192.168.1.23,192.168.1.24,192.168.1.25,192.168.1.26,192.168.1.27‘ |
11.2. 上传Zookeeper安装包到/data目录
mooon_upload -s=apache-zookeeper-3.5.5-bin.tar.gz -d=/data |
11.3. 解压和安装Zookeeper
mooon_ssh -c=‘cd /data;tar xzf apache-zookeeper-3.5.5-bin.tar.gz‘ # 解压 mooon_ssh -c=‘cd /data;ln -s apache-zookeeper-3.5.5-bin zookeeper‘ # 建立软链接 mooon_ssh -c=‘cd /data;chown -R zk:supergroup zookeeper apache-zookeeper-3.5.5-bin‘ |
以下步骤切换到zk用户操作。
export U=zk # 运行Zookeeper的用户zk export P=‘123456‘ # 用户zk的密码 |
11.4. 创建Zookeeper数据目录和日志目录
mooon_ssh -c=‘mkdir /data/zookeeper/data‘ mooon_ssh -c=‘mkdir /data/zookeeper/datalog‘ mooon_ssh -c=‘mkdir /data/zookeeper/logs‘ |
11.5. 设置Zookeeper的myid文件
每个Zookeeper节点都需要一个不同的取值范围为1~255的myid值,建议将myid文件放在Zookeeper的数据目录下。由于每个节点的myid值不同,因此无法简单的批量操作,但可借助工具set_zookeeper_id.sh实现批量操作,下载链接:https://github.com/eyjian/libmooon/blob/master/shell/set_zookeeper_id.sh。
在使用之前,需要先准备好IP和myid值映射文件,以本文的为例:
$ cat hosts.id 192.168.1.23 3 192.168.1.24 4 192.168.1.25 5 192.168.1.26 6 192.168.1.27 7 |
确保工具文件set_zookeeper_id.sh有可执行权限,映射文件可命名为hosts.id,将映射文件hosts.id和工具文件set_zookeeper_id.sh都上传到目标机器的/tmp目录。
mooon_upload -d=/tmp -s=hosts.id,set_zookeeper_id.sh |
批量远程执行set_zookeeper_id.sh。
mooon_ssh -c=‘/tmp/set_zookeeper_id.sh /tmp/hosts.id /data/zookeeper/data/myid‘ |
查看设置执行结果:
mooon_ssh -c=‘cat /data/zookeeper/data/myid‘ |
以下修改可在Zookeeper集群中一台机器进行,完成后批量发布到集群中的其它机器或节点。当然也可以在操作机上完成,然后再批量发布到集群所有机器或节点。
11.6. 创建和修改conf/zookeeper-env.sh
不要直接修改bin/zkEnv.sh,因为zkEnv.sh会调用conf/zookeeper-env.sh,所以不必再修改zkEnv.sh。
zookeeper-env.sh文件内容:
export ZOO_LOG_DIR=/data/zookeeper/log export ZOO_LOG4J_PROP="INFO,ROLLINGFILE" |
修改ZOO_LOG4J_PROP的目的是让日志不输出到zookeeper.out,而是写入到日志文件。
11.7. 修改conf/log4j.properties
主要修改如下三项:
zookeeper.log.dir=/data/zookeeper/log log4j.appender.ROLLINGFILE.MaxFileSize=100MB log4j.appender.ROLLINGFILE.MaxBackupIndex=10 |
设置日志文件目录为/data/zookeeper/log,每个日志文件大小MaxFileSize为100M,文件滚动个数MaxBackupIndex为10个。
11.8. 修改conf/java.env
打开文件bin/zkEnv.sh,可以看到它有引用conf/java.env。可以在java.env中设置JAVA_HOME这个环境变量,如:export JAVA_HOME=/usr/local/jdk。
仅在/etc/profile等处设置JAVA_HOME,可能并不管用。如果不管用,查看log/zookeeper.out,可以看到错误“nohup: failed to run command ‘java‘: No such file or directory”。
11.9. 设置环境变量PATH
这步不是必须的,但是推荐将zookeeper/bin加入到环境变量PATH,这样操作zookeeper会方便些,如:export PATH=/data/zookeeper/bin:$PATH。
建议采取在目录/etc/profile.d下新建文件zookeeper.sh方式,文件内容为:
export ZOOKEEPER_HOME=/data/zookeeper export PATH=$ZOOKEEPER_HOME/bin:$PATH |
当然也可以直接修改/etc/profile文件,不过不推荐也不建议,但可以修改zk用户自己的.bashrc文件方式。
11.10. 修改Zookeeper的配置文件zoo.cfg
解压Zookeeper安装包后,在目录conf中可找到Zookeeper模板配置文件zoo_sample.cfg,重命名为zoo.cfg,修改后内容如下。
$ cat zoo.cfg # The number of milliseconds of each tick tickTime=2000 # The number of ticks that the initial # synchronization phase can take initLimit=10 # The number of ticks that can pass between # sending a request and getting an acknowledgement syncLimit=5 # the directory where the snapshot is stored. # do not use /tmp for storage, /tmp here is just # example sakes. dataDir=/data/zookeeper/data dataLogDir=/data/zookeeper/datalog # the port at which the clients will connect clientPort=2181 # the maximum number of client connections. # increase this if you need to handle more clients maxClientCnxns=1000 # Be sure to read the maintenance section of the # administrator guide before turning on autopurge. # # http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance # # The number of snapshots to retain in dataDir autopurge.snapRetainCount=20 # Purge task interval in hours # Set to "0" to disable auto purge feature autopurge.purgeInterval=24 # Zookeeper cluster nodes Server.3=hadoop-003:2888:3888 Server.4=hadoop-004:2888:3888 Server.5=hadoop-005:2888:3888 Server.6=hadoop-006:2888:3888 Server.7=hadoop-007:2888:3888 |
从Zookeeper -3.5开始,默认会启动一个内嵌的Jetty服务,默认端口号为8080,在zoo.cfg中的相关配置如下(设置enableServer值为false可关闭内嵌的Jetty):
# The port the embedded Jetty server listens on. Defaults to 8080 admin.serverPort=8080 # The address the embedded Jetty server listens on. Defaults to 0.0.0.0 admin.serverAddress=0.0.0.0 # Set to "false" to disable the AdminServer. By default the AdminServer is enabled admin.enableServer=false # The URL for listing and issuing commands relative to the root URL. Defaults to "/commands" admin.commandURL="/commands" # Set the maximum idle time in milliseconds that a connection can wait before sending or receiving data. Defaults to 30000 ms admin.idleTimeout=30000 |
准备好后,将zoo.cfg批量上传到Zookeeper的配置文件目录/data/zookeeper/conf。Zoo.cfg中使用了主机名,注意务必已在/etc/hosts中配置好。
至此,Zookeeper已经安装和配置完毕,可启动Zookeeper了。推荐使用进程监控工具process_monitor.sh拉起Zookeeper,并且建议将process_monitor.sh放在Crontab中,一旦Zookeeper进程不在,process_monitor.sh可在几秒内重拉起Zookeeper。Process_monitor.sh的下载链接为https://github.com/eyjian/libmooon/blob/master/shell/process_monitor.sh。
11.11. 启动Zookeeper
11.11.1. 批量手工启动Zookeeper
mooon_ssh -c=‘nohup /data/zookeeper/bin/zkServer.sh start > /dev/null 2>&1 &‘ |
建议先在一台机器上启动,查看是否能够正常启动,没有问题再启动整个集群。
11.11.2. Crontab自动启动Zookeeper
JAVA_HOME=/usr/local/jdk ZOOKEEPER_HOME=/data/zookeeper PMONITOR=/usr/local/bin/process_monitor.sh * * * * * $PMONITOR "$JAVA_HOME/bin/java -Dzookeeper" "$ZOOKEEPER_HOME/bin/zkServer.sh start" |
11.11.3. 安装验证Zookeeper
执行下列语句验证安装:
mooon_ssh -c=‘/data/zookeeper/bin/zkServer.sh status‘ |
如果正常,则Leader节点会输出:
Client port found: 2181. Client address: localhost. Mode: leader |
Follower节点会输出:
Client port found: 2181. Client address: localhost. Mode: follower |
一个集群内有且只有一个Leader,而且必须有一个Leader。
12. 安装Hadoop
Hadoop的安装要比Zookeeper复杂许多,本节主要参考3.1.2版本的官方安装指南:https://hadoop.apache.org/docs/r3.1.2/hadoop-project-dist/hadoop-common/ClusterSetup.html。
12.1. 设置批量操作参数
# 涉及到所有,保持Master和Slave的配置文件相同,以简化管理 export H=‘192.168.1.21,192.168.1.22,192.168.1.23,192.168.1.24,192.168.1.25,192.168.1.26,192.168.1.27‘ |
12.2. 上传Hadoop安装包到/data目录
mooon_upload -s=hadoop-3.1.2.tar.gz -d=/data |
12.3. 解压和安装Hadoop
mooon_ssh -c=‘cd /data;tar xzf hadoop-3.1.2.tar.gz‘ # 解压 mooon_ssh -c=‘cd /data;ln -s hadoop-3.1.2 hadoop‘ # 建立软链接 mooon_ssh -c=‘cd /data;chown -R hadoop:supergroup hadoop-3.1.2 hadoop‘ |
以下步骤切换到hadoop用户操作。
export U=hadoop # 运行Hadoop的用户hadoop export P=‘123456‘ # 用户hadoop的密码 |
12.4. 修改hadoop-env.sh
修改所有节点上的$HADOOP_HOME/etc/hadoop/hadoop-env.sh文件,找到JAVA_HOME,设置其值为:export JAVA_HOME=/usr/local/jdk;找到HADOOP_HOME,设置其值为:export HADOOP_HOME=/data/hadoop。
特别说明下,虽然在/etc/profile.d/jdk.sh已经添加了JAVA_HOME,但仍然得修改所有节点上的hadoop-env.sh,否则启动时,报如下所示的错误(比如jdk.sh对Crontab拉起的无效):
192.168.1.21: Error: JAVA_HOME is not set and could not be found. 192.168.1.22: Error: JAVA_HOME is not set and could not be found. 192.168.1.23: Error: JAVA_HOME is not set and could not be found. |
除JAVA_HOME之外,再添加或修改:
export HADOOP_HOME=/data/hadoop/ export HADOOP_CONF_DIR=${HADOOP_HOME}/etc/hadoop export HADOOP_ROOT_LOGGER=INFO,console |
其它可选设置:
export HADOOP_HEAPSIZE_MAX= # 针对“Java -Xmx”,如果不指定单位,默认为“MB” export HADOOP_HEAPSIZE_MIN= # 针对“Java -Xms”,如果不指定单位,默认为“MB” export HADOOP_OPTS="-Djava.library.path=${HADOOP_HOME}/lib/native" exort HADOOP_CLIENT_OPTS= # HADOOP_OPTS的组成部分,针对Hadoop命令或客户端(如hdfs)的额外Java运行时选项 export HADOOP_COMMON_LIB_NATIVE_DIR= |
建议将“${HADOOP_HOME}/lib/native”加入到HADOOP_OPTS(尝试设置HADOOP_COMMON_LIB_NATIVE_DIR未生效,检查只在文件bin/hadoop中有引用HADOOP_COMMON_LIB_NATIVE_DIR,但并未有实际使用)中,不然会在日志中见到如下内容:
WARN [main] util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable |
12.5. 修改slaves
很多安装教程都有这一步,但并非必须的。文件格式同/etc/hosts,但全为slaves节点。如果只使用hadoop-daemon.sh启动和停止Hadoop,而不使用hadoop-daemons.sh、start-all.sh、stop-all.sh、start-dfs.sh、stop-dfs.sh等,就用不到slaves文件,所以说它不是必须的。
12.6. 修改log4j.properties
可不修改log4j.properties,但建议修改以下几项:
hadoop.log.dir=/data/hadoop/log Hadoop.log.maxbackupindex=10 |
12.7. 准备各配置文件
解压后的$HADOOP_HOME/etc/hadoop目录下的core-site.xml、hdfs-site.xml、mapred-site.xml、yarn-site.xml、httpfs-site.xml和kms-site.xml都是空的配置文件,所以不能直接使用。
而目录$HADOOP_HOME/share/doc/hadoop存了可用的模板配置文件,执行以下操作将这些模板配置文件复制到$HADOOP_HOME/etc/hadoop目录下。
cd $HADOOP_HOME # cd /data/hadoop cp ./share/doc/hadoop/hadoop-project-dist/hadoop-common/core-default.xml ./etc/hadoop/core-site.xml cp ./share/doc/hadoop/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml ./etc/hadoop/hdfs-site.xml cp ./share/doc/hadoop/hadoop-yarn/hadoop-yarn-common/yarn-default.xml ./etc/hadoop/yarn-site.xml cp ./share/doc/hadoop/hadoop-mapreduce-client/hadoop-mapreduce-client-core/mapred-default.xml ./etc/hadoop/mapred-site.xml |
然后可以开始绞刑修改各配置文件了。
12.8. 修改core-site.xml
按照下列表格完成对core-site.xml的修改:
属性名 |
属性值 |
说明 |
fs.defaultFS |
hdfs://hdfs-cluster |
HDFS集群名,应当取不同于其它HDFS集群的名称。如果有多个集群,可以考虑名称带上机房名。注意,必须为hdfs-site.xml中的dfs.nameservices定义的值之一。 |
hadoop.tmp.dir |
/data/hadoop/tmp/${user.name} |
这是一个本地目录,注意根据实际选择空间足够的目录。仅Slaves有使用,比如YARN的yarn.nodemanager.local-dirs基于hadoop.tmp.dir。 |
hadoop.zk.address |
hadoop-003:2181,hadoop-004:2181,hadoop-005:2181,hadoop-006:2181,hadoop-007:2181 |
YARN会用到这个配置项,用于存储状态和Leader选举,参考来源:https://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/ResourceManagerHA.html。 |
ha.zookeeper.quorum |
hadoop-003:2181,hadoop-004:2181,hadoop-005:2181,hadoop-006:2181,hadoop-007:2181 |
ZKFailoverController会用到这个配置项 |
ha.zookeeper.parent-znode |
/hadoop-ha |
在Zookeeper上的根目录,该目录用来做NameNode选举。不需要指定nameservice ID,会自动使用nameservice ID作为/hadoop-ha的子目录 |
io.seqfile.local.dir |
默认值为${hadoop.tmp.dir}/io/local |
|
fs.s3.buffer.dir |
默认值为${hadoop.tmp.dir}/s3 |
|
fs.s3a.buffer.dir |
默认值为${hadoop.tmp.dir}/s3a |
|
io.file.buffer.size |
131072 |
默认值为4096 |
注意启动之前,需要将配置的目录创建好,如创建好/data/hadoop/current/tmp目录。详细可参考:
http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/core-default.xml。
12.9. 修改hdfs-site.xml
HDFS由NameNode和DataNode组成,加上JournalNode共三部分。其中JournalNode是独立集群,用于主从NameNode是同步数据。
按照下列表格完成对hdfs-site.xml的修改,NameNode和DataNode的hdfs-site.xml可完全相同,以方便统一维护:
属性名 |
属性值 |
说明 |
dfs.nameservices |
hdfs-cluster (如果有多个,需以逗号分隔) |
HDFS集群名,注意core-site.xml中的fs.defaultFS值需要在dfs.nameservices中,建议取一个有意义的名字,以方便管理。如果有多个nameservices,则以逗号分隔,如:hdfs-cluster1,hdfs-cluster2。 |
dfs.ha.namenodes.hdfs-cluster |
nn1,nn2 |
同一nameservice下,可配置一或多个NameNode,“nn”为NameNode的缩写。 |
dfs.namenode.rpc-address.hdfs-cluster.nn1 |
hadoop-001:8020 |
|
dfs.namenode.rpc-address.hdfs-cluster.nn2 |
hadoop-002-204:8020 |
|
dfs.namenode.http-address.hdfs-cluster.nn1 |
hadoop-001:9870 |
|
dfs.namenode.http-address.hdfs-cluster.nn2 |
hadoop-002:9870 |
|
dfs.namenode.servicerpc-address |
配置了dfs.namenode.rpc-address,这个可以不配 |
|
dfs.blocksize |
134217728 |
HDFS的块大小,值可加上后缀k、m、g、t、p、e,如128m即为134217728 |
以下为JournalNode相关配置项 |
||
dfs.journalnode.edits.dir |
/data/hadoop/dfs/journalnode/ |
这个不要带前缀“file://”,JournalNode存储其本地状态的位置,在JouralNode机器上的绝对路径,JNs的edits和其他本地状态将被存储在此处。此处如果带前缀,则会报“Journal dir should be an absolute path” |
dfs.journalnode.rpc-address |
0.0.0.0:8485 |
配置JournalNode的RPC端口号,默认为0.0.0.0:8485,可以不用修改 |
以下为NameNode相关配置项 |
||
dfs.image.compress |
false |
是否压缩image文件 |
dfs.namenode.name.dir |
file:///data/hadoop/dfs/namenode |
请带上前缀“file://”,NameNode元数据存放目录,默认值为file://${hadoop.tmp.dir}/dfs/name,也就是在临时目录下,可以考虑放到数据目录下,多个目录时使用逗号分隔 |
dfs.namenode.shared.edits.dir |
qjournal://hadoop-003:8485;hadoop-004:8485;hadoop-005:8485;hadoop-006:8485;hadoop-007:8485/hdfs-cluster |
至少三台Quorum Journal节点配置,注意分隔符是分号,而不是逗号。如果使用逗号,在格式化NameNode时将报错“Multiple shared edits directories are not yet supported”。 |
dfs.namenode.checkpoint.dir |
file://${hadoop.tmp.dir}/dfs/namesecondary |
默认值为file://${hadoop.tmp.dir}/dfs/namesecondary,但如果没有启用SecondaryNameNode,则不需要 |
dfs.namenode.handler.count |
10 |
NameNode的处理来源Clients的RPC请求线程数,未配置dfs.namenode.servicerpc-address才有效 |
dfs.namenode.service.handler.count |
10 |
NameNode的处理来源DataNode的RPC请求线程数,区别于dfs.namenode.handler.count,只有配置了dfs.namenode.servicerpc-address才有效 |
dfs.hosts |
/data/hadoop/etc/hadoop/dfs.hosts.permitted |
可选配置,但建议配置,以防止其它DataNode无意中连接进来。用于配置DataNode白名单,只有在白名单中的DataNode才能连接NameNode。dfs.hosts的值为一本地文件绝对路径,如:/data/hadoop/etc/hadoop/dfs.hosts.permitted,只需NameNode上有此文件 |
dfs.hosts.exclude |
/data/hadoop/etc/hadoop/dfs.hosts.excluded |
正常不要填写,需要下线DataNode时用到。dfs.hosts.exclude的值为本地文件的绝对路径,文件内容为每行一个需要下线的DataNode主机名或IP地址,如:/data/hadoop/etc/hadoop/dfs.hosts.excluded,只需NameNode上有此文件 |
dfs.namenode.num.checkpoints.retained |
2 |
默认为2,指定NameNode保存fsImage文件的个数 |
dfs.namenode.num.extra.edits.retained |
1000000 |
额外保留Edit日志文件数 |
dfs.namenode.max.extra.edits.segments.retained |
10000 |
|
以下为DataNode相关配置项 |
||
dfs.datanode.data.dir |
file:///data/hadoop/dfs/data |
请带上前缀“file://”,不要全配置成SSD类型,否则写文件时会遇到错误“Failed to place enough replicas”,多个目录时使用逗号分隔 |
dfs.datanode.max.transfer.threads |
12288 |
DataNode用于传输数据的线程数,值不能太小,在Hadoop1.X中,此配置项名为dfs.datanode.max.xcievers。如果运行HBase,则该值应当调整到至少4096或者更大的值。 |
dfs.datanode.http.address |
9864 |
DataNode的HTTP端口 |
dfs.datanode.https.address |
9865 |
DataNode的HTTPS端口 |
dfs.datanode.du.reserved |
0 |
预留磁盘空间大小,单位为字节 |
dfs.datanode.scan.period.hours |
默认为504小时 |
|
dfs.blockreport.intervalMsec |
DataNode向NameNode报告块信息的时间间隔,默认值为21600000毫秒 |
|
dfs.datanode.directoryscan.interval |
DataNode进行内存和磁盘数据集块校验,更新内存中的信息和磁盘中信息的不一致情况,默认值为21600秒 |
|
dfs.heartbeat.interval |
3s |
向NameNode发心跳的间隔,单位:秒 |
以下为HA相关配置项 |
||
dfs.ha.automatic-failover.enabled |
true |
自动主备切换 |
dfs.ha.fencing.methods |
可取值sshfence或shell,比如:sshfence(hadoop:36000) 如果配置为sshfence,当主NameNode异常时,使用ssh登录到主NameNode,然后使用fuser将主NameNode杀死,因此需要确保所有NameNode上可以使用fuser。 |
用来保证同一时刻只有一个主NameNode,以防止脑裂。可带用户名和端口参数,格式示例:sshfence([[username][:port]]);值还可以为shell脚本,格式示例: shell(/path/to/my/script.sh arg1 arg2 ...),如: shell(/bin/true) 如果sshd不是默认的22端口时,就需要指定。建议填写杀死NameNode的命令,以防止出现脑裂。参考来源:https://hadoop.apache.org/docs/r3.1.2/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html。 |
dfs.ha.fencing.ssh.private-key-files |
/home/hadoop/.ssh2/id_dsa_2048_a |
如果dfs.ha.fencing.methods值为sshfence时需指定。 用于指定私钥,如果是OpenSSL,则值为/home/hadoop/.ssh/id_rsa,如有多个私钥,则以逗号分隔。 |
dfs.ha.fencing.ssh.connect-timeout |
30000 |
可选的配置 |
以下为权限相关配置项 |
||
dfs.permissions.supergroup |
supergroup |
超级用户组名,建议创建同名的本地用户组 |
dfs.permissions |
true |
为true表示开启权限检查 |
fs.permissions.umask-mode |
022 |
权限掩码 |
dfs.namenode.acls.enabled |
false |
NameNode是否开启ACL(Access Control Lists) |
dfs.cluster.administrators |
管理员列表 |
|
dfs.web.ugi |
webuser,webgroup |
WEB使用的用户名和用户组 |
以下为Client相关配置项 |
||
dfs.client.datanode-restart.timeout |
30 |
单位为秒,不要写成“30s”,否则HBase会报错“java.lang.NumberFormatException: For input string: "30s"” |
dfs.client.failover.proxy.provider.hdfs-cluster |
org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider |
客户端通过它来找主NameNode |
详细配置可参考:
http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml。
如果没有配置dfs.namenode.rpc-address,则启动时报如下错误:
Incorrect configuration: namenode address dfs.namenode.servicerpc-address or dfs.namenode.rpc-address is not configured. |
这里需要指定IP和端口,如果只指定了IP,如<value>192.168.1.22</value>,则启动时输出如下:
Starting namenodes on [] |
改成“<value>hadoop-002:8020</value>”后,则启动时输出为:
Starting namenodes on [192.168.1.22] |
12.10. 修改yarn-site.xml
在YARN中,内存、CPU和磁盘等被抽象为资源。YARN由ResourceManager和NodeManager两部分组成,ResourceManager中的调度器负责资源(内存和CPU)分配,NodeManager负责资源的供给和隔离。其中,ResourceManager又由ApplicationsManager和ResourceScheduler两个部分组成。
按照下列表格完成对yarn-site.xml的修改,ResourceManager和NodeManager的yarn-site.xml可完全相同,以方便统一维护:
属性名 |
属性值 |
说明 |
yarn.resourcemanager.cluster-id |
yarn-cluster |
YARN集群名 |
yarn.resourcemanager.hostname |
0.0.0.0 |
HA模式可不配置,但由于其它配置项可能有引用它,建议保持值为0.0.0.0,如果没有被引用到,则可不配置。 |
yarn.resourcemanager.address |
${yarn.resourcemanager.hostname}:8032 |
ResourceManager的RPC地址 |
yarn.nodemanager.hostname |
0.0.0.0 |
一般不用修改,保持为“0.0.0.0”即可,以方便所有节点配置统一。 |
yarn.nodemanager.resource.detect-hardware-capabilities |
false |
如果为true,则自动检查硬件资源 |
以下为HA相关的配置,包括自动切换(可仅可在ResourceManager节点上配置) |
||
yarn.resourcemanager.ha.enabled |
true |
启用HA |
yarn.resourcemanager.ha.automatic-failover.enabled |
true |
RM是否自动故障切换 |
yarn.resourcemanager.ha.rm-ids |
rm1,rm2 |
注意NodeManager要和ResourceManager一样配置 |
yarn.resourcemanager.hostname.rm1 |
hadoop-001 |
|
yarn.resourcemanager.hostname.rm2 |
hadoop-002 |
|
yarn.resourcemanager.webapp.address.rm1 |
${yarn.resourcemanager.hostname.rm1}:8088 |
|
yarn.resourcemanager.webapp.address.rm2 |
${yarn.resourcemanager.hostname.rm2}:8088 |
|
yarn.resourcemanager.zk-address |
hadoop-003:2181,hadoop-004:2181,hadoop-005:2181,hadoop-006:2181,hadoop-007:2181 |
这个已被core-site.xml中的hadoop.zk.address所取代 |
yarn.resourcemanager.ha.automatic-failover.enable |
true |
可不配置,因为当yarn.resourcemanager.ha.enabled为true时,它的默认值即为true |
以下为NodeManager配置 |
||
yarn.nodemanager.aux-services |
mapreduce_shuffle |
MapReduce Application的混洗服务 |
yarn.nodemanager.resource.cpu-vcores |
8 |
NodeManager总的可用虚拟CPU个数,默认值为8,值为-1表示自动,值不能超过实际的CPU核数 |
yarn.nodemanager.pmem-check-enabled |
true |
是否启动一个线程检查每个任务正使用的物理内存量,如果任务超出分配值,则直接将其杀掉,默认是true |
yarn.nodemanager.vmem-check-enabled |
true |
是否启动一个线程检查每个任务正使用的虚拟内存量,如果任务超出分配值,则直接将其杀掉,默认是true,64位系统可以考虑设置为false。 |
yarn.nodemanager.resource.memory-mb |
8192 |
该节点上YARN可使用的物理内存总量(包含所有任务的),默认是8192(MB),该值不能大于实际物理内存大小。如果值为-1,并且yarn.nodemanager.resource.detect-hardware-capabilities值为true,则自动计算。 |
yarn.nodemanager.vmem-pmem-ratio |
2.1 |
每使用1MB物理内存,最多可用的虚拟内存数,默认值为2.1。在运行spark-sql时如果遇到“Yarn application has already exited with state FINISHED”,则应当检查NodeManager的日志,以查看是否该配置偏小原因。该值偏小,也可能导致错误“running beyond virtual memory limits”。64位系统,该值可以调大一点。 |
yarn.nodemanager.local-dirs |
${hadoop.tmp.dir}/nm-local-dir |
NodeManager中间文件存放的本地目录,可用逗号分隔填写多个目录 |
yarn.nodemanager.log-dirs |
${yarn.log.dir}/userlogs |
NodeManager容器日志文件存放的本地目录,可用逗号分隔填写多个目录,默认为${yarn.log.dir}/userlogs,“yarn.log.dir”是一个JAVA属性,使用“-D”指定 |
yarn.nodemanager.log.retain-seconds |
当不启用日志聚合时,日志文件保留在本地的时长,注意区分yarn.log-aggregation.retain-seconds |
|
yarn.nodemanager.env-whitelist |
从NodeManager继承的环境变量 |
|
yarn.nodemanager.delete.debug-delay-sec |
Application执行结束后延迟多少秒后删除本地文件及日志 |
|
以下为聚合日志配置 |
||
yarn.log-aggregation-enable |
false |
值true表示开启日志聚合功能,此项功能会把各NodeManager上的Application的所有盘上的Container聚合保存到HDFS |
yarn.nodemanager.remote-app-log-dir |
/app-logs |
聚合日志在HDFS上的存放目录 |
yarn.nodemanager.remote-app-log-dir-suffix |
logs |
聚合日志文件实际存放的HDFS目录:${yarn.nodemanager.remote-app-log-dir}/${user}/${thisParam} |
yarn.log-aggregation.retain-seconds |
-1 |
聚合日志保留在HDFS上的时长,注意区分yarn.nodemanager.log.retain-seconds,值-1表示一直保留不删除 |
yarn.log-aggregation.retain-check-interval-seconds |
-1 |
间隔多久检查一次聚合日志,并将满足条件的删除 |
以下配置,用于NodeManager检测NodeManager是否健康 |
||
yarn.nodemanager.health-checker.script.path |
检查节点健康状态的脚本 |
|
yarn.nodemanager.health-checker.script.opts |
传递给检查节点健康状态的脚本的参数 |
|
yarn.nodemanager.health-checker.interval-ms |
600000 |
检查节点健康状态频率,单位:毫秒 |
yarn.nodemanager.health-checker.script.timeout-ms |
1200000 |
检查节点健康状态的脚本执行超时时长,单位:毫秒 |
以下为ResourceManager配置 |
||
yarn.scheduler.minimum-allocation-vcores |
1 |
单个任务可申请的最少虚拟CPU个数,默认为1 |
yarn.scheduler.maximum-allocation-vcores |
32 |
单个任务可申请的最多虚拟CPU个数,默认为32 |
yarn.scheduler.minimum-allocation-mb |
1024 |
单位:MB,单个任务可申请的最小物理内存量 |
yarn.scheduler.maximum-allocation-mb |
8192 |
注意区别yarn.nodemanager.resource.memory-mb。单位:MB,单个任务可申请的最大物理内存量。可通过YARN的WEB查看内存使用情况:http://192.168.1.21:8088/cluster/nodes(这里的192.168.1.21:8088为ResourceManager的WEB地址)。 |
yarn.resourcemanager.nodes.include-path |
/data/hadoop/etc/hadoop/yarn.hosts.permitted |
指定NodeManager白名单文件,文件的每行一个NodeManager主机名件,只需ResourceManager上有此文件 |
yarn.resourcemanager.nodes.exclude-path |
/data/hadoop/etc/hadoop/yarn.hosts.excluded |
指定NodeManager黑名单文件,只需ResourceManager上有此文件 |
ACL控制配置 |
||
yarn.acl.enable |
false |
是否开启ACLs,默认为false |
yarn.admin.acl |
逗号分隔的管理员列表,“*”表示不限定 |
yarn.nodemanager.hostname如果配置成具体的IP,如192.168.1.22,则会导致每个NodeManager的配置不同。详细配置可参考:
http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-common/yarn-default.xml。
Yarn HA的配置可以参考:
https://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/ResourceManagerHA.html。
执行下列操作之前,确保已启动好Zookeeper,并且Zookeeper状态正常可用。请按照顺序完成下列操作,虽然有部分步骤可调换顺序,但按照顺序操作相对简单省事。
12.11. 修改mapred-site.xml
按照下列表格完成对mapred-site.xml的修改(注意不是修改NodeManager上的,而应修改ResourceManager上的mapred-site.xml才有效):
属性名 |
属性值 |
说明 |
mapreduce.framework.name |
yarn |
所有mapreduce节点 |
mapreduce.job.heap.memory-mb.ratio |
0.8 |
|
mapreduce.map.memory.mb |
1536 |
值过小,在MR时可能遇到错误“Java heap space”。 如果未指定或为负值,则使用“mapreduce.map.java.opts”和“mapreduce.job.heap.memory-mb.ratio”定义的值;如果 mapreduce.map.java.opts也未设置,则默认为1024。 |
mapreduce.map.java.opts |
-Xmx1024M |
|
mapreduce.reduce.memory.mb |
3072 |
如果未指定或为负值,则使用“mapreduce.reduce.java.opts”和“mapreduce.job.heap.memory-mb.ratio”定义的值;如果 mapreduce.reduce.java.opts也未设置,则默认为1024。 |
mapreduce.reduce.java.opts |
-Xmx2560M |
|
mapreduce.task.io.sort.mb |
512 |
|
mapreduce.task.io.sort.factor |
100 |
|
mapreduce.reduce.shuffle.parallelcopies |
50 |
|
yarn.app.mapreduce.am.env |
HADOOP_MAPRED_HOME=$HADOOP_HOME |
|
mapred.child.env |
HADOOP_MAPRED_HOME=$HADOOP_HOME |
传递给MR任务的环境变量 |
mapred.child.java.opts |
-Xmx1024m |
设置任务的Java选项,如果没有设置-Xmx,则使用“mapreduce.{map|reduce}.memory.mb”定义的值。如果值过小,在执行MR时可能报错“Error: Java heap space”或“running beyond virtual memory limits”。 如果mapred.child.java.opts值大于yarn.scheduler.maximum-allocation-mb的值,则会报错“The required MAP capability is more than the supported max container capability in the cluster”。 |
mapreduce.map.env |
HADOOP_MAPRED_HOME=$HADOOP_HOME |
已废弃 |
mapreduce.reduce.env |
HADOOP_MAPRED_HOME=$HADOOP_HOME |
已废弃 |
以下为针对 MapReduce JobHistory Server 的配置 (yarn-site.xml中的yarn.log-aggregation-enable值为true和设置了mapreduce.jobhistory.address才会开启)
启动HistoryServer: bin/mapred --daemon start historyserver 停止HistoryServer: bin/mapred --daemon stop historyserver
在集群中的任意一台或多台机器启动即可,以下中的“AM”为“ApplicationMaster”的缩写。 |
||
mapreduce.jobhistory.address |
0.0.0.0:10020 |
MapReduce JobHistory Server的RPC服务地址,默认值为0.0.0.0:10020 |
mapreduce.jobhistory.webapp.address |
0.0.0.0:19888 |
MapReduce JobHistory Server的WEB服务地址,默认值为0.0.0.0:19888 |
yarn.app.mapreduce.am.staging-dir |
/tmp/yarn/staging |
注意这是一个HDFS目录,不是本地目录,默认值为/tmp/hadoop-yarn/staging。ApplicationMaster运行时,将日志写到目录${yarn.app.mapreduce.am.staging-dir}/${user.name}/.staging/job_XXXXX_XXX下,其中后缀为“.jhist”的文件为Job的运行日志。 |
mapreduce.jobhistory.intermediate-done-dir |
${yarn.app.mapreduce.am.staging-dir}/history/done_intermediate |
这也是一个HDFS目录,存放正在运行的Jobs日志文件等 |
mapreduce.jobhistory.done-dir |
${yarn.app.mapreduce.am.staging-dir}/history/done |
也是一个HDFS目录,存放历史(即已完成的)Jobs的日志文件等 |
mapreduce.map.log.level |
INFO |
MAP任务的日志级别,默认为INFO,其它可选有:OFF/FATAL/ERROR/WARN/INFO/DEBUG/TRACE/ALL |
mapreduce.reduce.log.level |
||
mapreduce.shuffle.max.threads |
0 |
混洗线程数,为0表示为CPU核数的两倍 |
详细配置可参考:
12.12. 设置环境变量
这一步是不必须的,但可方便运维管理。建议在目录/etc/profile.d下新建文件hadoop.sh,文件内容如下(最重要的是HADOOP_HOME):
export HADOOP_HOME=/data/hadoop export HADOOP_COMMON_HOME=$HADOOP_HOME export HADOOP_HDFS_HOME=$HADOOP_HOME export HADOOP_YARN_HOME=$HADOOP_HOME export HADOOP_MAPRED_HOME=$HADOOP_HOME #export PATH=$HADOOP_HOME/bin:$PATH # 非必须,但建议也加上 |
当然也可只修改Hadoop用户自己的,比如在~/.bashrc或~/.bash_profile等文件中新增以上内容。
12.13. 创建本地目录
在执行其它操作之前,需要完成以下目录的创建:
配置项 |
本地目录 |
范围 |
hadoop.tmp.dir |
/data/hadoop/tmp |
所有机器 |
dfs.journalnode.edits.dir |
/data/hadoop/dfs/journalnode/ |
所有JournalNode机器 |
dfs.datanode.data.dir |
/data/hadoop/dfs/data |
所有DataNode机器 |
dfs.namenode.name.dir |
/data/hadoop/dfs/namenode |
所有NameNode机器 |
13. 启动HDFS
13.1. 创建主备切换命名空间
这一步必须在其它步骤之前先完成,实际为Zookeeper操作,而且只需要任意一台NameNode上操作。进入NameNode的bin目录,然后执行:
$HADOOP_HOME/bin/hdfs zkfc -formatZK |
如果运行没有出错信息,就表示成功:
2019-09-23 15:11:58,587 INFO tools.DFSZKFailoverController: registered UNIX signal handlers for [TERM, HUP, INT] 2019-09-23 15:11:58,844 INFO tools.DFSZKFailoverController: Failover controller configured for NameNode NameNode at hadoop-001/192.168.1.21:8020 2019-09-23 15:11:58,933 INFO zookeeper.ZooKeeper: Client environment:zookeeper.version=3.4.13-2d71af4dbe22557fda74f9a9b4309b15a7487f03, built on 06/29/2018 00:39 GMT 2019-09-23 15:11:58,933 INFO zookeeper.ZooKeeper: Client environment:host.name=hadoop-001 2019-09-23 15:11:58,933 INFO zookeeper.ZooKeeper: Client environment:java.version=1.8.0_221 2019-09-23 15:11:58,933 INFO zookeeper.ZooKeeper: Client environment:java.vendor=Oracle Corporation 2019-09-23 15:11:58,933 INFO zookeeper.ZooKeeper: Client environment:java.home=/usr/local/jdk1.8.0_221/jre 2019-09-23 15:11:58,933 INFO zookeeper.ZooKeeper: Client environment:java.class.path=/data/hadoop/etc/hadoop: 2019-09-23 15:11:58,934 INFO zookeeper.ZooKeeper: Client environment:java.library.path=/data/hadoop/lib/native 2019-09-23 15:11:58,934 INFO zookeeper.ZooKeeper: Client environment:java.io.tmpdir=/tmp 2019-09-23 15:11:58,934 INFO zookeeper.ZooKeeper: Client environment:java.compiler=<NA> 2019-09-23 15:11:58,934 INFO zookeeper.ZooKeeper: Client environment:os.name=Linux 2019-09-23 15:11:58,934 INFO zookeeper.ZooKeeper: Client environment:os.arch=amd64 2019-09-23 15:11:58,934 INFO zookeeper.ZooKeeper: Client environment:os.version=3.10.107-1-tlinux2-0046 2019-09-23 15:11:58,934 INFO zookeeper.ZooKeeper: Client environment:user.name=hadoop 2019-09-23 15:11:58,934 INFO zookeeper.ZooKeeper: Client environment:user.home=/home/hadoop 2019-09-23 15:11:58,934 INFO zookeeper.ZooKeeper: Client environment:user.dir=/data/hadoop-3.1.2/bin 2019-09-23 15:11:58,935 INFO zookeeper.ZooKeeper: Initiating client connection, connectString=hadoop-003:2181,hadoop-004:2181,hadoop-005:2181,hadoop-006:2181,hadoop-007:2181 sessionTimeout=10000 watcher[email protected]7722c3c3 2019-09-23 15:11:58,948 INFO zookeeper.ClientCnxn: Opening socket connection to server hadoop10111/9.2.167.183:2181. Will not attempt to authenticate using SASL (unknown error) 2019-09-23 15:11:58,952 INFO zookeeper.ClientCnxn: Socket connection established to hadoop-003/9.2.167.183:2181, initiating session 2019-09-23 15:11:58,960 INFO zookeeper.ClientCnxn: Session establishment complete on server hadoop10111/9.2.167.183:2181, sessionid = 0xb086f1716e10000, negotiated timeout = 10000 2019-09-23 15:11:58,962 INFO ha.ActiveStandbyElector: Session connected. 2019-09-23 15:11:58,979 INFO ha.ActiveStandbyElector: Successfully created /hadoop-ha/hdfs-cluster in ZK. 2019-09-23 15:11:58,981 INFO zookeeper.ZooKeeper: Session: 0xb086f1716e10000 closed 2019-09-23 15:11:58,982 INFO zookeeper.ClientCnxn: EventThread shut down for session: 0xb086f1716e10000 2019-09-23 15:11:58,982 INFO tools.DFSZKFailoverController: SHUTDOWN_MSG: /************************************************************ SHUTDOWN_MSG: Shutting down DFSZKFailoverController at hadoop-001/192.168.1.21 ************************************************************/ |
格式化成功后,会在ZooKeeper上创建core-site.xml中ha.zookeeper.parent-znode指定的路径。
[zk: localhost:2181(CONNECTED) 1] ls / [hadoop-ha, zookeeper] [zk: localhost:2181(CONNECTED) 2] ls /hadoop-ha [SHBX-hdfs-cluster] [zk: localhost:2181(CONNECTED) 3] ls /hadoop-ha/SHBX-hdfs-cluster [] |
如果有修改hdfs-site.xml中的dfs.ha.namenodes.hdfs-cluster值,则需要重新做一次formatZK,否则自动主备NameNode切换将失效。zkfc进程的日志文件将发现如下信息(假设nm1改成了nn1):
Unable to determine service address for namenode ‘nm1‘ |
另外需注意,如果有修改dfs.ha.namenodes.hdfs-cluster,上层的HBase等依赖HBase的也需要重启。
查看格式化后的Zookeeper变化:
$ ./zkCli.sh Connecting to localhost:2181 Welcome to ZooKeeper! JLine support is enabled WATCHER:: WatchedEvent state:SyncConnected type:None path:null [zk: localhost:2181(CONNECTED) 0] ls / [zookeeper, hadoop-ha] [zk: localhost:2181(CONNECTED) 1] ls /hadoop-ha [hdfs-cluster] [zk: localhost:2181(CONNECTED) 2] get /hadoop-ha/hdfs-cluster cZxid = 0x200000005 ctime = Thu Oct 11 17:16:25 CST 2018 mZxid = 0x200000005 mtime = Thu Oct 11 17:16:25 CST 2018 pZxid = 0x200000005 cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 0 numChildren = 0 |
13.2. 启动JournalNode集群
NameNode将元数据操作日志记录在JournalNode上,主备NameNode通过记录在JouralNode上的日志完成元数据同步。
在所有JournalNode上执行(注意不是$HADOOP_HOME/bin/hadoop-daemon.sh start journalnode):
$HADOOP_HOME/bin/hdfs --daemon start journalnode |
这一步必须在格式化NameNode之前执行,因为格式化NameNode会操作JournalNode集群。
13.3. 格式化NameNode
在主NameNode上执行以下命令(注意只能在主NameNode上执行):
$HADOOP_HOME/bin/hdfs namenode -format hdfs-cluster |
如果进行顺利,输出内容如下所示:
[[email protected] /data/hadoop/bin]$ ls /data/hadoop/dfs/namenode/ [[email protected] /data/hadoop/bin]$ ./hdfs namenode -format hdfs-cluster WARNING: /data/hadoop/logs does not exist. Creating. ************************************************************/ 2019-09-23 15:57:20,747 INFO namenode.NameNode: registered UNIX signal handlers for [TERM, HUP, INT] 2019-09-23 15:57:20,824 INFO namenode.NameNode: createNameNode [-format, hdfs-cluster] Formatting using clusterid: CID-6cf9848f-9744-4582-b7bf-a0f22458bfc1 2019-09-23 15:57:21,251 INFO namenode.FSEditLog: Edit logging is async:true 2019-09-23 15:57:21,265 INFO namenode.FSNamesystem: KeyProvider: null 2019-09-23 15:57:21,266 INFO namenode.FSNamesystem: fsLock is fair: true 2019-09-23 15:57:21,267 INFO namenode.FSNamesystem: Detailed lock hold time metrics enabled: false 2019-09-23 15:57:21,272 INFO namenode.FSNamesystem: fsOwner = hadoop (auth:SIMPLE) 2019-09-23 15:57:21,272 INFO namenode.FSNamesystem: supergroup = supergroup 2019-09-23 15:57:21,272 INFO namenode.FSNamesystem: isPermissionEnabled = true 2019-09-23 15:57:21,272 INFO namenode.FSNamesystem: Determined nameservice ID: hdfs-cluster 2019-09-23 15:57:21,272 INFO namenode.FSNamesystem: HA Enabled: true 。。。。。。 2019-09-23 15:57:23,781 INFO namenode.NameNode: SHUTDOWN_MSG: /************************************************************ SHUTDOWN_MSG: Shutting down NameNode at hadoop-001/192.168.1.21 ************************************************************/ [[email protected] /data/hadoop/bin]$ ls /data/hadoop/dfs/namenode/ current |
格式化成功后,可在该NameNode的数据目录下看到如下内容(由hdfs-site.xml中的dfs.namenode.name.dir决定):
[[email protected] /data/hadoop/bin]$ ls /data/hadoop/dfs/namenode/current/ fsimage_0000000000000000000 fsimage_0000000000000000000.md5 seen_txid VERSION |
这个时候的fsimage_0000000000000000000实际是空的,只有个文件头。
在进行格式化时,如果没有在/etc/hosts文件中添加主机名和IP的映射:“192.168.1.21 hadoop-001”,则会报如下所示错误:
23/09/1003:44:09 WARN net.DNS: Unable to determine local hostname -falling back to "localhost" java.net.UnknownHostException: hadoop-001: hadoop-001: unknown error at java.net.InetAddress.getLocalHost(InetAddress.java:1484) at org.apache.hadoop.net.DNS.resolveLocalHostname(DNS.java:264) at org.apache.hadoop.net.DNS.<clinit>(DNS.java:57) at org.apache.hadoop.hdfs.server.namenode.NNStorage.newBlockPoolID(NNStorage.java:945) at org.apache.hadoop.hdfs.server.namenode.NNStorage.newNamespaceInfo(NNStorage.java:573) at org.apache.hadoop.hdfs.server.namenode.FSImage.format(FSImage.java:144) at org.apache.hadoop.hdfs.server.namenode.NameNode.format(NameNode.java:845) at org.apache.hadoop.hdfs.server.namenode.NameNode.createNameNode(NameNode.java:1256) at org.apache.hadoop.hdfs.server.namenode.NameNode.main(NameNode.java:1370) Caused by: java.net.UnknownHostException: hadoop-001: unknown error at java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method) at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:907) at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1302) at java.net.InetAddress.getLocalHost(InetAddress.java:1479) ... 8 more |
格式化NameNode产生的版本信息存储在文件VERSION中:
[[email protected] /data/hadoop/bin]$ cat /data/hadoop/dfs/namenode/current/VERSION #Mon Sep 23 15:57:22 CST 2019 namespaceID=1732498488 clusterID=CID-6cf9848f-9744-4582-b7bf-a0f22458bfc1 cTime=1569225442971 storageType=NAME_NODE blockpoolID=BP-1854934288-192.168.1.21-1569225442971 layoutVersion=-64 |
注意cTime值的单位是毫秒而不是秒,转成人类可读时间如下:
[[email protected] /data/hadoop/bin]$ date --date=‘@1569225442‘ ‘+%Y-%m-%d %H:%M:%S‘ 2019-09-23 15:57:22 |
13.4. 启动主NameNode
如果hdfs-site.xml中配置为自动主备切换,则主NameNode起来时,实际是备状态(standby)。
启动NameNode命令:
$HADOOP_HOME/bin/hdfs --daemon start namenode |
使用jps查看NameNode进程是否已经拉起来:
[[email protected] /data/hadoop/bin]$ jps 160097 NameNode 160185 Jps |
查看NameNode的监听端口是否起来了(以NameNode的IP为192.168.1.21为例,为NameNode的RPC端口为8020,NameNode的HTTP端口为9870):
[[email protected] /data/hadoop/bin]$ jps 160097 NameNode 161149 Jps [[email protected] /data/hadoop/bin]$ netstat -lpnt|grep 160097 (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) tcp 0 0 192.168.1.21:8020 0.0.0.0:* LISTEN 160097/java tcp 0 0 192.168.1.21:9870 0.0.0.0:* LISTEN 160097/java |
主NameNode启动时,会在Zookeeper的路径“${ha.zookeeper.parent-znode}/${dfs.nameservices}”下分别创建一个临时节点ActiveStandbyElectorLock和永久节点ActiveBreadCrumb。
当临时节点ActiveStandbyElectorLock消失时,备NameNode会尝试竞争为主NameNode。永久节点ActiveBreadCrumb用来防止脑裂,ZKFC通过它来做Fencing,ActiveBreadCrumb保存了主NameNoded的地址信息。
13.5. 查看NameNode主备状态
这个时候如果还没启动主备切换进程,查看NameNode状态时,可看到为standy状态,即备状态:
[[email protected] /data/hadoop/bin]$ ./hdfs haadmin -getServiceState nn1 standby |
由于当前还没有一个主NameNode,所以刚启动的NameNode会以备NameNode身份尝试连接主NameNode。当hdfs-site.xml的dfs.ha.namenodes.hdfs-cluster配置了两个或更多NameNode时,会尝试连接自身之外的另一个NameNode。日志文件会出现如下内容:
2019-09-23 16:18:20,570 WARN org.apache.hadoop.hdfs.server.namenode.ha.EditLogTailer: Exception from remote name node RemoteNameNodeInfo [nnId=nn2, ipcAddress=hadoop-002/192.168.1.22:8020, httpAddress=http://hadoop-002:9870], try next. java.net.ConnectException: Call From hadoop-002/192.168.1.21 to 192.168.1.22:8020 failed on connection exception: java.net.ConnectException: 拒绝连接; For more details see: http://wiki.apache.org/hadoop/ConnectionRefused at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.apache.hadoop.net.NetUtils.wrapWithMessage(NetUtils.java:831) at org.apache.hadoop.net.NetUtils.wrapException(NetUtils.java:755) at org.apache.hadoop.ipc.Client.getRpcResponse(Client.java:1515) at org.apache.hadoop.ipc.Client.call(Client.java:1457) at org.apache.hadoop.ipc.Client.call(Client.java:1367) at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:228) at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:116) at com.sun.proxy.$Proxy19.rollEditLog(Unknown Source) at org.apache.hadoop.hdfs.protocolPB.NamenodeProtocolTranslatorPB.rollEditLog(NamenodeProtocolTranslatorPB.java:150) at org.apache.hadoop.hdfs.server.namenode.ha.EditLogTailer$2.doWork(EditLogTailer.java:365) at org.apache.hadoop.hdfs.server.namenode.ha.EditLogTailer$2.doWork(EditLogTailer.java:362) at org.apache.hadoop.hdfs.server.namenode.ha.EditLogTailer$MultipleNameNodeProxy.call(EditLogTailer.java:504) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Caused by: java.net.ConnectException: 拒绝连接 |
13.6. 启动主备切换进程zkfc
zkfc是zookeeper failover controller的缩写,负责NameNode的主备切换,只需在NameNode上执行,而且这一步可在“启动主NameNode”前。为启动主备切换进程,执行以下命令:
$HADOOP_HOME/bin/hdfs --daemon start zkfc |
只有启动了主备切换进程DFSZKFailoverController,NameNode才能自动切换主备。
$ ./hdfs haadmin -getServiceState nn1 active |
如果先将两个NameNode启动好,再启动主备切换进程,则哪个为主NameNode是不确定的。
13.7. 启动备NameNode
多个备NameNode启动步骤和方式相同,第一次启动一个备NameNode前,需要先在这个备NameNode上执行:
$HADOOP_HOME/bin/hdfs namenode -bootstrapStandby |
这一步的作用是同步主NameNode上的fsimage文件,注意只有第一次启动NameNode才需要。
[[email protected] /data/hadoop/bin]$ ls /data/hadoop/dfs/namenode/ [[email protected] /data/hadoop/bin]$ ./hdfs namenode -bootstrapStandby [[email protected] /data/hadoop/bin]$ ls /data/hadoop/dfs/namenode/ current |
然后和启动主NameNode方式相同启动备NameNode:
$HADOOP_HOME/bin/hdfs --daemon start namenode |
如果没有执行第1步,直接启动会遇到如下错误:
No valid image files found |
或者在该NameNode日志会发现如下错误:
2019-09-23 16:08:39,745 WARN org.apache.hadoop.hdfs.server.namenode.FSNamesystem: Encountered exception loading fsimage java.io.IOException: NameNode is not formatted. |
注意,在备NameNode上也需要启动“主备切换进程zkfc”,这样当主NameNode异常时,备NameNode才能变成主NameNode。
查看NameNode主备状态:
[[email protected] /data/hadoop/bin]$ ./hdfs haadmin -getServiceState nn1 active [[email protected] /data/hadoop/bin]$ ./hdfs haadmin -getServiceState nn2 standby |
13.8. 启动所有DataNode
HDFS集群就差DataNode没有启动了,这一步将所有DataNode启动起来。方法同样十分简单,只需在所有DataNode上执行下述命令:
$HADOOP_HOME/bin/hdfs --daemon start datanode |
批量启动DataNode:
mooon_ssh -c=‘/data/hadoop/bin/hdfs --daemon start datanode‘ -u=hadoop -p=‘123456‘ -h=‘‘ |
如果有发现DataNode进程并没有起来,可以试试删除logs目录下的DataNode日志,再得启看看。
13.9. 检查DataNode状态
执行命令“hdfs dfsadmin -report”检查DataNode状态,以确定DataNode是否启动成功。正常应看到如下内容:
[[email protected] /data/hadoop/bin]$ ./hdfs dfsadmin -report Configured Capacity: 42518699704320 (38.67 TB) Present Capacity: 40066804686848 (36.44 TB) DFS Remaining: 40066804097024 (36.44 TB) DFS Used: 589824 (576 KB) DFS Used%: 0.00% Replicated Blocks: Under replicated blocks: 0 Blocks with corrupt replicas: 0 Missing blocks: 0 Missing blocks (with replication factor 1): 0 Low redundancy blocks with highest priority to recover: 0 Pending deletion blocks: 0 Erasure Coded Block Groups: Low redundancy block groups: 0 Block groups with corrupt internal blocks: 0 Missing block groups: 0 Low redundancy blocks with highest priority to recover: 0 Pending deletion blocks: 0 ------------------------------------------------- Live datanodes (5): |
13.10. 手动切换NameNode主备
执行下命令即可完成手动切换,以将nn2切换为主NameNode为例,只需要执行:
$HADOOP_HOME/bin/hdfs haadmin -transitionToActive nn2 |
强制切换,使用如下命令(自动切换模式不支持):
hdfs haadmin -failover --forcefence --forceactive nn1 nn2 # 让nn2成为主NameNode |
14. 启动YARN
14.1. 启动ResourceManager
在所有ResourceManager机器或节点上执行以下命令启动ResourceManager:
$HADOOP_HOME/bin/yarn --daemon start resourcemanager |
如果ResourceManager不能自动主备切换,检查下是否有其它的ResourceManager正占用着Zookeeper。
14.2. 启动NodeManager
在所有NodeManager机器或节点上执行以下命令启动NodeManager:
$HADOOP_HOME/bin/yarn --daemon start nodemanager |
正常情况下,可执行“yarn --daemon stop nodemanager”来停掉NodeManager,但如果执行时遇到错误“no nodemanager to stop”,则可通过如下方式:
kill `/usr/local/jdk/bin/jps | awk ‘/NodeManager/{print $1}‘ ` |
对应的批量操作:
mooon_ssh -c="kill \`/usr/local/jdk/bin/jps | awk ‘/NodeManager/{print \$1}‘ \`" |
14.3. 启动HistoryServer
在集群中的任意一台或多台机器启动即可,并不需要在每一台机器上都启动HistoryServer。
HistoryServer的默认Web端口为19888,由mapred-site.xml中的mapreduce.jobhistory.webapp.address控制。假设在192.168.1.21上启动了HistoryServer,则可浏览器打开“http://192.168.1.21:19888”查看。
如果有防火墙挡住了端口19888,则应修改mapreduce.jobhistory.webapp.address的值,或者使用rinetd或sshd等工具转发到19888。
bin/mapred --daemon start historyserver |
14.4. 停止HistoryServer
bin/mapred --daemon stop historyserver |
15. 常用HDFS命令
15.1. hdfs dfs ls
“hdfs dfs -ls”带一个参数,如果参数以“hdfs://URI”打头表示访问HDFS,否则相当于ls。其中URI为NameNode的IP或主机名,可以包含端口号,即hdfs-site.xml中“dfs.namenode.rpc-address”指定的值。
“hdfs dfs -ls”要求默认端口为8020,如果配置成9000,则需要指定端口号,否则不用指定端口,这一点类似于浏览器访问一个URL。示例:
> hdfs dfs -ls hdfs:///192.168.1.21:9001/ |
9001后面的斜杠/是和必须的,否则被当作文件。如果不指定端口号9001,则使用默认的8020,“192.168.1.21:9001”由hdfs-site.xml中“dfs.namenode.rpc-address”指定。
不难看出“hdfs dfs -ls”可以操作不同的HDFS集群,只需要指定不同的URI。
文件上传后,被存储在DataNode的data目录下(由DataNode的hdfs-site.xml中的属性“dfs.datanode.data.dir”指定),如:
$HADOOP_HOME/data/current/BP-139798373-192.168.1.21-1397735615751/current/finalized/blk_1073741825
文件名中的“blk”是block,即块的意思,默认情况下blk_1073741825即为文件的一个完整块,Hadoop未对它进额外处理。
15.2. hdfs dfs -put
上传文件命令,示例:
> hdfs dfs -put /etc/SuSE-release hdfs:///192.168.1.21:9001/ |
15.3. hdfs dfs -rm
删除文件命令,示例:
> hdfs dfs -rm hdfs://192.168.1.21:9001/SuSE-release Deleted hdfs://192.168.1.21:9001/SuSE-release |
15.4. 查看文件分布在哪些节点
hdfs fsck hdfs:///tmp/slaves -files -locations -blocks |
15.5. 关闭安全模式
hdfs dfsadmin -safemode leave |
15.6. 删除missing blocks
hdfs fsck -delete |
15.7. 强制DataNode上报块信息
在扩容过程中,有可能遇到DataNode启动时未向NameNode上报block信息。正常时,NameNode都会通过心跳响应的方式告诉DataNode上报block,但当NameNode和DataNode版本不一致等时,可能会使这个机制失效。搜索DataNode的日志文件,将搜索不到上报信息日志“sent block report”。
这个时候,一旦重启NameNode,就会出现大量“missing block”。幸好HDFS提供了工具,可以直接强制DataNode上报block,方法为:
hdfs dfsadmin -triggerBlockReport ‘192.168.1.21:50020 |
上述‘192.168.1.21为DataNode的IP地址,50020为DataNode的RPC端口。最终应当保持DataNode和NameNode版本一致,不然得每次做一下这个操作,而且可能还有其它问题存在。
15.8. 扩容和下线
15.8.1. 新增JournalNode
如果是扩容,将已有JournalNode的current目录打包到新机器的“dfs.journalnode.edits.dir”指定的相同位置下。
为保证扩容和缩容JournalNode成功,需要先将NameNode和JournalNode全停止掉,再修改配置,然后在启动JournalNode成功后(日志停留在“IPC Server listener on 8485: starting”处),再启动NameNode,否则可能遇到如下这样的错误:
org.apache.hadoop.hdfs.qjournal.protocol.JournalOutOfSyncException: Can‘t write, no segment open |
找一台已有JournalNode节点,修改它的hdfs-site.xml,将新增的Journal包含进来,如在
<value>qjournal://hadoop-003:8485;hadoop-004:8485;hadoop-005:8485/test</value>
的基础上新增hadoop-033和hadoop-034两个JournalNode:
<value>qjournal://hadoop-003:8485;hadoop-004:8485;hadoop-005:8485;hadoop-006:8485;hadoop-007:8485/test</value>
然后将安装目录和数据目录(hdfs-site.xml中的dfs.journalnode.edits.dir指定的目录)都复制到新的节点。
如果不复制JournalNode的数据目录,则新节点上的JournalNode可能会报错“Journal Storage Directory /data/journal/test not formatted”,将来的版本可能会实现自动同步。ZooKeeper的扩容不需要复制已有节点的data和datalog,而且也不能这样操作。
接下来,就可以在新节点上启动好JournalNode(不需要做什么初始化),并重启下NameNode。注意观察JournalNode日志,查看是否启动成功,当日志显示为以下这样的INFO级别日志则表示启动成功:
2019-09-26 10:31:11,160 INFO org.apache.hadoop.hdfs.server.namenode.FileJournalManager: Finalizing edits file /data/journal/test/current/edits_inprogress_0000000000000194269 -> /data/journal/test/current/edits_0000000000000194269-0000000000000194270
但只能出现如下的日志,才表示工作正常:
2019-09-18 15:22:42,901 INFO org.apache.hadoop.ipc.Server: IPC Server listener on 8485: starting 2019-09-18 15:23:27,028 INFO org.apache.hadoop.hdfs.qjournal.server.JournalNode: Initializing journal in directory /data/journal/data/test 2019-09-18 15:23:27,042 INFO org.apache.hadoop.hdfs.server.common.Storage: Lock on /data/journal/data/test/in_use.lock acquired by nodename [email protected] 2019-09-18 15:23:27,057 INFO org.apache.hadoop.hdfs.qjournal.server.Journal: Scanning storage FileJournalManager(root=/data/journal/data/test) 2019-09-18 15:23:27,152 INFO org.apache.hadoop.hdfs.qjournal.server.Journal: Latest log is EditLogFile(file=/data/journal/data/test/current/edits_inprogress_0000000000027248811,first=0000000000027248811,last=0000000000027248811,inProgress=true,hasCorruptHeader=false) |
15.8.2. 新增NameNode
记得更换NameNode后,需要重新执行“hdfs zkfc -formatZK”,否则将不能自动主备切换。
当有NameNode机器损坏时,必然存在新NameNode来替代。把配置修改成指向新NameNode,然后以备机形式启动新NameNode,这样新的NameNode即加入到Cluster中:
./hdfs namenode -bootstrapStandby ./hadoop-daemon.sh start namenode |
记启动主备切换进程DFSZKFailoverController,否则将不能自动做主备切换!!!
新的NameNode通过bootstrapStandby操作从主NameNode拉取fsImage(hadoop-001:50070为主NameNode):
19/09/24 14:25:32 INFO namenode.TransferFsImage: Opening connection to http://hadoop-002:50070/imagetransfer?getimage=1&txid=2768127&storageInfo=-63:2009831148:1492719902489:CID-5b2992bb-4dcb-4211-8070-6934f4d232a8&bootstrapstandby=true 19/09/24 14:25:32 INFO namenode.TransferFsImage: Image Transfer timeout configured to 60000 milliseconds 19/09/24 14:25:32 INFO namenode.TransferFsImage: Transfer took 0.01s at 28461.54 KB/s 19/09/24 14:25:32 INFO namenode.TransferFsImage: Downloaded file fsimage.ckpt_0000000000002768127 size 379293 bytes. |
如果没有足够多的DataNode连接到NameNode,则NameNode也会进入safe模式,下面的信息显示只有0台DataNodes连接到了NameNode。
原因有可能是因为修改了dfs.ha.namenodes.hdfs-cluster的值,导致DataNode不认识,比如将nm1改成了nn1等,这个时候还需要重新formatZK,否则自动主备切换将失效。
如果DataNode上的配置也同步修改了,但修改后未重启,则需要重启DataNode:
Safe mode is ON. The reported blocks 0 needs additional 12891 blocks to reach the threshold 0.9990 of total blocks 12904. The number of live datanodes 0 has reached the minimum number 0. Safe mode will be turned off automatically once the thresholds have been reached. |
15.8.3. 扩容DataNode
兼容的版本可跨版本扩容,比如由Hadoop-3.1.1扩容Hadoop-3.1.2。扩容方法为在新增的机器上安装和配置好DataNode,在成功启动DataNode后,在主NameNode上执行命令:bin/hdfs dfsadmin -refreshNodes,即完成扩容。如果有配置dfs.hosts,则在执行refreshNodes前,需先加新扩的DataNode加入到dfs.hosts指向的文件中。
如要数据均衡到新加入的机器,执行命令:sbin/start-balancer.sh,可带参数-threshold,默认值为10,如:sbin/start-balancer.sh -threshold 5。参数-threshold的取值范围为0~100。
balancer命令可在NameNode和DataNode上执行,但最好在新增机器或空闲机器上执行。
参数-threshold的值表示节点存储使用率和集群存储使用率间的关系,如果节点的存储使用率小于集群存储的使用率,则执行balance操作。
15.8.4. 下线DataNode
本操作需在主NameNode上进行,即状态为active的NameNode上进行!!!如果备NameNode也运行着,建议备的hdfs-site.xml也做同样修改,以防止下线过程中发现主备NameNode切换,或者干脆停掉备NameNode。
下线完成后,记得将hdfs-site.xml修改回来(即将dfs.hosts.exclude值恢复为空值),如果不修改回来,那被下线掉的DataNode将一直处于Decommissioned状态,同时还得做一次“/data/hadoop/bin/hdfs dfsadmin -refreshNodes”,否则被下线的DataNode一直处于Decommissioned状态。
下线后,只要配置了dfs.hosts,即使被下线的DataNode进程未停掉,也不会再连接进来,而且这是推荐的方式,以防止外部的DataNode无意中连接进来。
但在将dfs.hosts.exclude值恢复为空值之前,需要将已下线的所有DataNode进程停掉,最好还设置hdfs-site.xml中的dfs.hosts值,以限制可以连接NameNode的DataNode,不然一不小心,被下线的DataNode又连接上来了,切记!另外注意,如果有用到slaves文件,也需要slaves同步修改。
修改主NameNode的hdfs-site.xml,设置dfs.hosts.exclude的值,值为一文件的全路径,如:/data/hadoop/etc/hadoop/hosts.exclude。文件内容为需要下线(即删除)的DataNode的机器名或IP,每行一个机器名或IP(注意暂不要将下线的DataNode从slaves中剔除)。
修改完hdfs-site.xml后,在主NameNode上执行:bin/hdfs dfsadmin -refreshNodes,以刷新DataNode,下线完成后可同扩容一样做下balance。
使用命令bin/hdfs dfsadmin -report或web界面可以观察下线的DataNode退役(Decommissioning)状态。完成后,将下线的DataNode从slaves中剔除。
下线前的状态:
$ hdfs dfsadmin -report Name: 192.168.1.21:50010 (hadoop-001) Hostname: hadoop-001 Decommission Status : Normal Configured Capacity: 3247462653952 (2.95 TB) DFS Used: 297339283 (283.56 MB) Non DFS Used: 165960652397 (154.56 GB) DFS Remaining: 3081204662272 (2.80 TB) DFS Used%: 0.01% DFS Remaining%: 94.88% Configured Cache Capacity: 0 (0 B) Cache Used: 0 (0 B) Cache Remaining: 0 (0 B) Cache Used%: 100.00% Cache Remaining%: 0.00% Xceivers: 1 Last contact: Wed Apr 19 18:03:33 CST 2017 |
下线进行中的的状态:
$ hdfs dfsadmin -report Name: 192.168.1.21:50010 (hadoop-001) Hostname: hadoop-001 Decommission Status : Decommission in progress Configured Capacity: 3247462653952 (2.95 TB) DFS Used: 297339283 (283.56 MB) Non DFS Used: 165960652397 (154.56 GB) DFS Remaining: 3081204662272 (2.80 TB) DFS Used%: 0.01% DFS Remaining%: 94.88% Configured Cache Capacity: 0 (0 B) Cache Used: 0 (0 B) Cache Remaining: 0 (0 B) Cache Used%: 100.00% Cache Remaining%: 0.00% Xceivers: 16 Last contact: Thu Apr 20 09:00:48 CST 2017 |
下线完成后的状态:
$ hdfs dfsadmin -report Name: 192.168.1.21:50010 (hadoop-001) Hostname: hadoop-001 Decommission Status : Decommissioned Configured Capacity: 1935079350272 (1.76 TB) DFS Used: 257292167968 (239.62 GB) Non DFS Used: 99063741175 (92.26 GB) DFS Remaining: 1578723441129 (1.44 TB) DFS Used%: 13.30% DFS Remaining%: 81.58% Configured Cache Capacity: 0 (0 B) Cache Used: 0 (0 B) Cache Remaining: 0 (0 B) Cache Used%: 100.00% Cache Remaining%: 0.00% Xceivers: 13 Last contact: Thu Apr 20 09:29:00 CST 2017 |
如果长时间处于“Decommission In Progress”状态,而不能转换成Decommissioned状态,这个时候可用“hdfs fsck”检查下。
成功下线后,还需要将该节点从slaves中删除,以及dfs.hosts.exclude中剔除,然后再做一下:bin/hdfs dfsadmin -refreshNodes。
16. YARN命令
16.1. 查看节点列表:yarn node -list
列举YARN集群中的所有NodeManager,如(注意参数间的空格,直接执行yarn可以看到使用帮助):
> yarn node -list Total Nodes:3 Node-Id Node-State Node-Http-Address Number-of-Running-Containers localhost:45980 RUNNING localhost:8042 0 localhost:47551 RUNNING localhost:8042 0 localhost:58394 RUNNING localhost:8042 0 |
16.2. 查看节点状态:yarn node -status
查看指定NodeManager的状态,如:
> yarn node -status localhost:47551 Node Report : Node-Id : localhost:47551 Rack : /default-rack Node-State : RUNNING Node-Http-Address : localhost:8042 Last-Health-Update : 星期五 18/四月/14 01:45:41:555GMT Health-Report : Containers : 0 Memory-Used : 0MB Memory-Capacity : 8192MB CPU-Used : 0 vcores CPU-Capacity : 8 vcores |
16.3. 查看状态:yarn rmadmin -getServiceState rm1
查看rm1的主备状态,即查看它是主(active)还是备(standby)。
16.4. 人工切换:yarn rmadmin -transitionToStandby rm1
将rm1从主切为备,更多的yarn命令可以参考:
https://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YarnCommands.html。
16.5. 查看应用列表:yarn application --list
不带参数执行“yarn application”,可显示帮助信息,使用“yarn application”还可杀死或优雅停止指定的应用(Application),以及显示应用状态等。
16.6. 查看作业列表:hadoop job -list
不带参数执行“hadoop job”,可显示帮助信息,使用“hadoop job”还可杀死指定的作业(Job),以及显示作业状态等。
17. 运行MapReduce程序
在安装目录的share/hadoop/mapreduce子目录下,有现存的示例程序:
~/hadoop> ls share/hadoop/mapreduce hadoop-mapreduce-client-app-3.1.2.jar hadoop-mapreduce-client-hs-plugins-3.1.2.jar hadoop-mapreduce-client-shuffle-3.1.2.jar lib hadoop-mapreduce-client-common-3.1.2.jar hadoop-mapreduce-client-jobclient-3.1.2-tests.jar hadoop-mapreduce-client-uploader-3.1.2.jar lib-examples hadoop-mapreduce-client-core-3.1.2.jar hadoop-mapreduce-client-jobclient-3.1.2.jar hadoop-mapreduce-examples-3.1.2.jar sources hadoop-mapreduce-client-hs-3.1.2.jar hadoop-mapreduce-client-nativetask-3.1.2.jar jdiff |
跑一个示例程序试试:
hdfs dfs -put /etc/hosts hdfs:///test/in/ hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.2.jar wordcount hdfs:///test/in/ hdfs:///test/out/ |
运行过程中,使用java的jps命令,可以看到yarn启动了名为YarnChild的进程。
wordcount运行完成后,结果会保存在out目录下,保存结果的文件名类似于“part-r-00000”。另外,跑这个示例程序有两个需求注意的点:
in目录下要有文本文件,或in即为被统计的文本文件,可以为HDFS上的文件或目录,也可以为本地文件或目录
out目录不能存在,程序会自动去创建它,如果已经存在则会报错。
包hadoop-mapreduce-examples-3.1.2.jar中含有多个示例程序,不带参数运行,即可看到用法:
> hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.2.jar wordcount Usage: wordcount <in> <out> > hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.2.jar An example program must be given as the first argument. Valid program names are: aggregatewordcount: An Aggregate based map/reduce program that counts the words in the input files. aggregatewordhist: An Aggregate based map/reduce program that computes the histogram of the words in the input files. bbp: A map/reduce program that uses Bailey-Borwein-Plouffe to compute exact digits of Pi. dbcount: An example job that count the pageview counts from a database. distbbp: A map/reduce program that uses a BBP-type formula to compute exact bits of Pi. grep: A map/reduce program that counts the matches of a regex in the input. join: A job that effects a join over sorted, equally partitioned datasets multifilewc: A job that counts words from several files. pentomino: A map/reduce tile laying program to find solutions to pentomino problems. pi: A map/reduce program that estimates Pi using a quasi-Monte Carlo method. randomtextwriter: A map/reduce program that writes 10GB of random textual data per node. randomwriter: A map/reduce program that writes 10GB of random data per node. secondarysort: An example defining a secondary sort to the reduce. sort: A map/reduce program that sorts the data written by the random writer. sudoku: A sudoku solver. teragen: Generate data for the terasort terasort: Run the terasort teravalidate: Checking results of terasort wordcount: A map/reduce program that counts the words in the input files. wordmean: A map/reduce program that counts the average length of the words in the input files. wordmedian: A map/reduce program that counts the median length of the words in the input files. wordstandarddeviation: A map/reduce program that counts the standard deviation of the length of the words in the input files. |
修改日志级别为DEBBUG,并打屏:
export HADOOP_ROOT_LOGGER=DEBUG,console |
附1:crontab监控脚本
使用这种方法,不需要在Master和Slaves节点间建立免密码登录关系,因为相关进程由crontab拉起,并不需要显示调用start-all.sh、start-dfs.sh、start-yarn.sh、start-hbase.sh等。
监控工具下载:
https://github.com/eyjian/libmooon/blob/master/shell/process_monitor.sh
监控工具使用示例:
PMONITOR=/usr/local/bin/process_monitor.sh JAVA=/usr/local/jdk/bin/java ZK_SERVER=/data/zookeeper/bin/zkServer.sh HDFS=/data/hadoop/bin/hdfs YARN=/data/hadoop/bin/yarn HBASE_DAEMON=/data/hbase/bin/hbase-daemon.sh # 监控 ZooKeeper * * * * * $PMONITOR "$JAVA -Dzookeeper" "$ZK_SERVER start" # 监控 HDFS NameNode(仅在 Master 上启动) * * * * * $PMONITOR "$JAVA -Dproc_namenode" "$HDFS --daemon start namenode" # 监控 HDFS 切换主备 NameNode 程序(仅在 Master 上启动) * * * * * $PMONITOR "$JAVA -Dproc_zkfc" "$HDFS --daemon start zkfc" # 监控 HDFS JournalNode(仅在 JournalNode 上启动) #* * * * * $PMONITOR "$JAVA -Dproc_journalnode" "$HDFS --daemon start journalnode" # 监控 HDFS DataNode(仅在 DataNode 上启动) #* * * * * $PMONITOR "$JAVA -Dproc_datanode" "$HDFS --daemon start datanode" # 监控 YARN ResourceManager(仅在 Master 上启动) * * * * * $PMONITOR "$JAVA -Dproc_resourcemanager" "$YARN --daemon start resourcemanager" # 监控 YARN NodeManager(一般和 DataNode 共享相同机器) #* * * * * $PMONITOR "$JAVA -Dproc_nodemanager" "$YARN --daemon start nodemanager" # 监控HBase Master(仅在 Master 上启动) #* * * * * $PMONITOR "$JAVA -Dproc_master" "$HBASE_DAEMON start master" # 监控HBase regionserver(仅在 RegionServer 上启动) #* * * * * $PMONITOR "$JAVA -Dproc_regionserver" "$HBASE_DAEMON start regionserver" # 监控HBase thrift2(一般和 RegionServer 共享相同机器) #* * * * * $PMONITOR "$JAVA -Dproc_thrift2" "$HBASE_DAEMON start thrift2 --framed -nonblocking" |
附2:批量操作工具
批量操作工具下载:
https://github.com/eyjian/libmooon/releases
其中,mooon_ssh为批量命令工具,mooon_upload为批量上传文件工具。
批量操作工具使用示例:
# 设置环境变量 export H=‘192.168.1.21,192.168.1.22,192.168.1.23,192.168.1.24,192.168.1.25,192.168.1.26‘ export U=root export P=password export PORT=201810 # 上传/etc/hosts和/etc/profile到:192.168.31.12,192.168.31.13,192.168.31.14,192.168.31.15 mooon_upload -s=/etc/hosts,/etc/profile -d=/etc # 检查/etc/profile文件是否一致 mooon_ssh -c=‘md5sum /etc/hosts‘ |
附3:JVM基础知识
1)JPS命令
当执行jps命令时,如果看不到运行中的Java进程。假设用户名为test,则检查目录/tmp/hsperfdata_test的Owner和权限是否正确,如果权限不正确,则jps将看不到运行中的Java进程。
2)JVM内存
JVM内存由3部分组成:
作用 |
说明 |
|
新生代(Young) |
存活时间较短,一般存储刚生成的一些对象 |
又分为一个伊甸园(Eden)区,和两个Survivor区,两个Survivor区总有一个是空的。对新生代的垃圾回收叫做Minor GC,特点是次数频繁,但每次回收时间较短。 对象在Survivor每经历一次Minor GC,年龄就增长1岁,默认增长到15岁时就晋升到Old代。 |
老年代(Tenured) |
也叫旧生成(Old),存活时间较长,主要存储在应用程序中生命周期较长的对象 |
对象优先在Eden上分配,但大对象直接在Old上分配。对老年代的垃圾回收叫做MajorGC或Full GC,特点是次数相对少,每次回收时间较长。 |
永久代(Perm) |
存储meta和class的信息,JDK8已删除永久代 |
永久代垃圾回收比较少,效率也比较低。因为在JDK8中已无永久代,所以JVM参数“-XX:PermSize”和 “-XX:MaxPermSize”已作废,代替的参数分别为“-XX:MetaspaceSiz”和“-XX:MaxMetaspaceSize”。 |
3)JVM GC(Garbage Collection,垃圾回收)
当Eden空间不足时,即触发Minor GC。Full GC的触发条件为:Old空间不足;Perm空间不足;统计得到的Minor GC晋升到Old的平均大小大于Old的剩余空间。
回收策略 |
|
|
Serial |
串行收集器 |
串行单线程处理所有垃圾回收工作,适合小数据量的回收,使用“-XX:+UseSerialGC”打开。 |
Parrallel New Collector |
并行收集器 |
Serial的多线程版本,并行多线程处理,使用“-XX:+UseParallelOldGC”打开,用“-XX:ParallelGCThreads=<N>”指定垃圾回收线程数。 |
CMS(Concurrent Mark Sweep) |
并发收集器,响应时间优先回收器 |
并发多线程处理,使用“-XX:+UseConcMarkSweepGC”打开,只针对老年代。 |
4)并行和并发
并行 |
Parallel |
多条垃圾收集线程并行工作,应用线程处于等待状态 |
并发 |
Concurrent |
垃圾收集线程与应用线程一段时间内同时工作,不是并行而是交替执行 |
5)JVM的CMS垃圾回收
CMS(Concurrent Mark Sweep)是一个并发使用标记的GC,以牺牲CPU吞吐量为代价获得最短回收停顿时间的垃圾回收器。
CMS不对堆(Heap)进行整理和压缩,节约了垃圾回收停顿时间,但产生了空间碎片,增加了堆空间的浪费。
CMS虽然是老生代的GC,但仍然需要扫描新生代。
启用方式:JVM参数加上“XX:+UseConcMarkSweepGC”,这个参数表示对于老年代的回收采用CMS,CMS采用“标记—清除”算法。
CMS分成以下几个过程:
1) 初始标记(STW initial mark)
需暂停JVM,官方的叫法STW(Stop The Word),这个过程虽然暂停了JVM,但很快完成。这个过程只标记GC ROOT可直接关联的对象,不包括间接关联的对象。
2) 并发标记(Concurrent marking)
无停顿,应用程序的线程和并发标记的线程并发执行,本过程标记所有可达对象,通过GC ROOT TRACING可达到的对象是活着的对象。
3) 并发预清理(Concurrent precleaning)
无停顿,这个过程也是并发的。
4) 重新标记(STW remark)
这个过程也会暂停JVM,重新扫描堆中的对象,标记活着的对象,包含子过程Rescan。
5) 并发清理(Concurrent sweeping)
无停顿,应用程序线程和收集器线程并发执行。
6) 并发重置(Concurrent reset)
无停顿,重置CMS收集器的数据结构,等待下一次垃圾回收。
6)JVM内存参数
执行命令“java -X”可看到相关参数的说明,不同版本的JDK默认值不一定相同,可执行命令“java -XX:+PrintFlagsFinal -version | grep HeapSize”查看默认值。
参数名 |
参数说明 |
示例 |
-Xms |
初始Java堆大小,JVM启动时分配的内存 |
-Xms256m |
-Xmx |
最大Java堆大小,运行时可分配的最大内存 |
-Xmx2048m |
-Xss |
Java线程堆栈大小,每个线程分配的内存大小 |
-Xss128m |
-XX:OnOutOfMemoryError |
内存溢出时的动作 |
-XX:OnOutOfMemoryError=‘kill -9 %p‘ |
-XX:+UseConcMarkSweepGC |
设置并发垃圾收集器 |
-XX:+UseConcMarkSweepGC |
-XX:+UseParallelGC |
设置并行垃圾收集器,同时运行在多CPU上,独占式收集器(收集过程中进程暂停STW),不能与CMS收集器一起。使用这个参数,新生代为并行回收,老年代为串行回收。 |
-XX:+UseParallelGC |
-XX:+UseSerialGC |
设置串行垃圾收集器,也是独占式收集器。使用这个参数,新生代和老年代都为串行回收。 |
-XX:+UseSerialGC |
-XX:+UseParNewGC |
设置并发串行收集器,实际是串行垃圾回收器的多线程化,即串行垃圾回收器的多线程版本,也是独占式收集器。使用这个参数时,新生代为并行回收,老年代仍是串行回收。 |
-XX:+UseParNewGC |
-XX:+UseParallelOldGC |
新生代和老年代都使用并行收集器 |
-XX:+UseParallelOldGC |
-XX:+UseConcMarkSweepGC |
老年代回收器,停顿(STW)减少,但吞吐量会降低。 |
-XX:+UseConcMarkSweepGC |
-XX:ParallelGCThreads |
设置并行收集线程数 |
-XX:ParallelGCThreads=10 |
原文地址:https://www.cnblogs.com/aquester/p/11783542.html