赞
踩
Hadoop作业调度器主要有三种:FIFO、Capacity Scheduler和Fair Scheduler。Hadoop2.9.2默认的资源调度器是Capacity Scheduler。
可以查看yarn-default.xml
Yarn集群资源设置为A,B两个队列,
<!-- 指定我们的任务调度使用fairScheduler的调度方式 -->
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>
<description>In case you do not want to use the defaultscheduler</description>
</property>
<?xml version="1.0" encoding="utf-8"?> <allocations> <defaultQueueSchedulingPolicy>fair</defaultQueueSchedulingPolicy> <queue name="root"> <queue name="default"> <aclAdministerApps>*</aclAdministerApps> <aclSubmitApps>*</aclSubmitApps> <maxResources>9216 mb,4 vcores</maxResources> <maxRunningApps>100</maxRunningApps> <minResources>1024 mb,1vcores</minResources> <minSharePreemptionTimeout>1000</minSharePreemptionTimeout> <schedulingPolicy>fair</schedulingPolicy> <weight>7</weight> </queue> <queue name="queue1"> <aclAdministerApps>*</aclAdministerApps> <aclSubmitApps>*</aclSubmitApps> <maxResources>4096 mb,4vcores</maxResources> <maxRunningApps>5</maxRunningApps> <minResources>1024 mb, 1vcores</minResources> <minSharePreemptionTimeout>1000</minSharePreemptionTimeout> <schedulingPolicy>fair</schedulingPolicy> <weight>3</weight> </queue> </queue> <queuePlacementPolicy> <rule create="false" name="specified"/> <rule create="true" name="default"/> </queuePlacementPolicy> </allocations>
界面验证
命令启动Hdfs集群
start-dfs.sh
该命令会启动Hdfs的NameNode以及DataNode,启动NameNode主要是通过org.apache.hadoop.hdfs.server.namenode.NameNode类。
我们重点关注NameNode在启动过程中做了哪些工作(偏离主线的技术细节不深究)
对于分析启动流程主要关注两部分代码:
namenode的主要责任是文件元信息与数据块映射的管理。相应的,namenode的启动流程需要关注与客户端、datanode通信的工作线程,文件元信息的管理机制,数据块的管理机制等。其中,RpcServer主要负责与客户端、datanode通信,FSDirectory主要负责管理文件元信息。
datanode的Main Class是DataNode,先找到DataNode.main()
高并发访问NameNode会遇到什么样的问题:
经过学习HDFS的元数据管理机制,Client每次请求NameNode修改一条元数据(比如说申请上传一个文件,都要写一条edits log,包括两个步骤:
分段加锁机制
首先各个线程依次第一次获取锁,生成顺序递增的txid,然后将edits写入内存双缓冲的区域1,接着就立马第一次释放锁了。趁着这个空隙,后面的线程就可以再次立马第一次获取锁,然后立即写自己的
edits到内存缓冲。
双缓冲机制
程序中将会开辟两份一模一样的内存空间,一个为bufCurrent,产生的数据会直接写入到这个bufCurrent,而另一个叫bufReady,在bufCurrent数据写入(达到一定标准)后,两片内存就会exchange(交换)。直接交换双缓冲的区域1和区域2。保证接收客户端写入数据请求的都是操作内存而不是同步写磁盘。
双缓冲源码分析 找到FsEditLog.java
Hadoop3.x中增强了很多特性,在Hadoop3.x中,不再允许使用jdk1.7,要求jdk1.8以上版本。这是因为Hadoop 2.0是基于JDK 1.7开发的,而JDK 1.7在2015年4月已停止更新,这直接迫使Hadoop社区基于JDK 1.8重新发布一个新的Hadoop版本,而这正是Hadoop3.x。Hadoop3.x以后将会调整方案架构,将Mapreduce 基于内存+io+磁盘,共同处理数据。
Hadoop 3.x中引入了一些重要的功能和优化,包括HDFS 可擦除编码、多Namenode支持、MR NativeTask优化、YARN基于cgroup的内存和磁盘IO隔离、YARN container resizing等。
Hadoop3.x官方文档地址如下:
http://hadoop.apache.org/docs/r3.0.1/
关于这两个特性的官方文档地址:
http://hadoop.apache.org/docs/r3.0.1/hadoop-project-dist/hadoop-
hdfs/HDFSErasureCoding.html
http://hadoop.apache.org/docs/r3.0.1/hadoop-project-dist/hadoop-
hdfs/HDFSHighAvailabilityWithQJM.html
http://hadoop.apache.org/docs/r3.0.1/hadoop-yarn/hadoop-yarn-
site/TimelineServiceV2.html
Job运行时,尽量让所有的节点都有任务处理,这样能尽量保证集群资源被充分利用,任务的并发度达到最大。可以通过调整处理的数据量大小,以及调整map和reduce个数来实现。
努力避免出现以下场景
一个job中,每个MapTask或ReduceTask的执行时间只有几秒钟,这就意味着这个job的大部分时间都消耗在task的调度和进程启停上了,因此可以考虑增加每个task处理的数据大小。建议一个task处理时间为1分钟。
Shuffle阶段是MapReduce性能的关键部分,包括了从MapTaskask将中间数据写到磁盘一直到ReduceTask拷贝数据并最终放到Reduce函数的全部过程。这一块Hadoop提供了大量的调优参数。
mapreduce.map.memory.mb
Ma需要的CPU核数可以通过如下参数调整
mapreduce.map.cpu.vcores
可以看到内存默认是1G,CPU默认是1核。
如果集群资源充足建议调整:
mapreduce.map.memory.mb=3G(默认1G)mapreduce.map.cpu.vcores=1(默认也是1)
1、Reduce资源
每个Reduce资源
mapreduce.reduce.memory.mb=5G(默认1G) mapreduce.reduce.cpu.vcores=1(默认为1)。
2、Copy
ReduceTask在copy的过程中默认使用5(mapreduce.reduce.shuffle.parallelcopies参数控制)个
并行度进行复制数据。
该值在实际服务器上比较小,建议调整为50-100.
3、溢写归并
Copy过来的数据会先放入内存缓冲区中,然后当使用内存达到一定量的时候spill磁盘。这里的缓冲区大小要比map端的更为灵活,它基于JVM的heap size设置。这个内存大小的控制是通过mapreduce.reduce.shuffle.input.buffer.percent(default 0.7)控制的。
shuffile在reduce内存中的数据最多使用内存量为:0.7 × maxHeap of reduce task,内存到磁盘merge的启动可以通过mapreduce.reduce.shuffle.merge.percent(default0.66)配置。
copy完成后,reduce进入归并排序阶段,合并因子默认为10(mapreduce.task.io.sort.factor参数控制),如果map输出很多,则需要合并很多趟,所以可以提高此参数来减少合并次数。
集群规模很大时(几百上千台节点的集群),个别机器出现软硬件故障的概率就变大了,并且会因此延长整个任务的执行时间推测执行通过将一个task分给多台机器跑,取先运行完的那个,会很好的解决这个问题。对于小集群,可以将这个功能关闭。
建议:
MapReduce的AM在申请资源的时候,会一次性申请所有的Map资源,延后申请reduce的资源,这样就能达到先执行完大部分Map再执行Reduce的目的。
mapreduce.job.reduce.slowstart.completedmaps
当多少占比的Map执行完后开始执行Reduce。默认5%的Map跑完后开始起Reduce。
如果想要Map完全结束后执行Reduce调整该值为1
yarn.nodemanager.resource.memory-mb 默认是8192
yarn.nodemanager.resource.cpu-vcores
该节点上YARN可使用的虚拟CPU个数,默认是8。
目前推荐将该值设值为逻辑CPU核数的1.5~2倍之间
YARN的NodeManager提供2种Container的启动模式。
默认,YARN为每一个Container启动一个JVM,JVM进程间不能实现资源共享,导致资源本地化的时间开销较大。针对启动时间较长的问题,新增了基于线程资源本地化启动模式,能够有效提升container
启动效率。
yarn.nodemanager.container-executor.class
运行的一个大任务,map总数达到了上万的规模,任务失败,发现是ApplicationMaster(以下简称AM)反应缓慢,最终超时失败。
失败原因是Task数量变多时,AM管理的对象也线性增长,因此就需要更多的内存来管理。AM默认分配的内存大小是1.5GB。
建议:
任务数量多时增大AM内存
yarn.app.mapreduce.am.resource.mb
JVM堆内存
补充:
JDK1.8版本废弃了永久代,替代的是元空间(MetaSpace),元空间与永久代上类似,都是方法区的实现,他们最大区别是:元空间并不在JVM中,而是使用本地内存。
查看当前jvm内存使用以及垃圾回收情况
结果解释:
开启HDFS GC详细日志输出
编辑hadoop-env.sh
export HADOOP_LOG_DIR=/hadoop/logs/
增加JMX配置打印详细GC信息
指定一个日志输出目录;注释掉之前的ops
增加新的打印配置
#JMX配置
export HADOOP_JMX_OPTS="-Dcom.sun.management.jmxremote.authenticate=false - Dcom.sun.management.jmxremote.ssl=false"
export HADOOP_NAMENODE_OPTS="-Dhadoop.security.logger=${HADOOP_SECURITY_LOGGER:- INFO,RFAS} -Dhdfs.audit.logger=${HDFS_AUDIT_LOGGER:-INFO,NullAppender} $HADOOP_NAMENODE_OPTS"
export HADOOP_DATANODE_OPTS="-Dhadoop.security.logger=ERROR,RFAS $HADOOP_DATANODE_OPTS"
export NAMENODE_OPTS="-verbose:gc -XX:+PrintGCDetails - Xloggc:${HADOOP_LOG_DIR}/logs/hadoop-gc.log \ -XX:+PrintGCDateStamps -XX:+PrintGCApplicationConcurrentTime - XX:+PrintGCApplicationStoppedTime \ -server -Xms150g -Xmx150g -Xmn20g -XX:SurvivorRatio=8 - XX:MaxTenuringThreshold=15 \ -XX:ParallelGCThreads=18 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC - XX:+UseCMSCompactAtFullCollection -XX:+DisableExplicitGC - XX:+CMSParallelRemarkEnabled \ -XX:+CMSClassUnloadingEnabled -XX:CMSInitiatingOccupancyFraction=70 - XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly - XX:CMSMaxAbortablePrecleanTime=5000 \ -XX:+UseGCLogFileRotation -XX:GCLogFileSize=20m - XX:ErrorFile=${HADOOP_LOG_DIR}/logs/hs_err.log.%p - XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${HADOOP_LOG_DIR}/logs/%p.hprof \"
export DATENODE_OPTS="-verbose:gc -XX:+PrintGCDetails - Xloggc:${HADOOP_LOG_DIR}/hadoop-gc.log \-XX:+PrintGCDateStamps -XX:+PrintGCApplicationConcurrentTime - XX:+PrintGCApplicationStoppedTime \ -server -Xms15g -Xmx15g -Xmn4g -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=15 \-XX:ParallelGCThreads=18 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC - XX:+UseCMSCompactAtFullCollection -XX:+DisableExplicitGC - XX:+CMSParallelRemarkEnabled \ -XX:+CMSClassUnloadingEnabled -XX:CMSInitiatingOccupancyFraction=70 - XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly - XX:CMSMaxAbortablePrecleanTime=5000 \ -XX:+UseGCLogFileRotation -XX:GCLogFileSize=20m - XX:ErrorFile=${HADOOP_LOG_DIR}/logs/hs_err.log.%p - XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${HADOOP_LOG_DIR}/logs/%p.hprof \"
export HADOOP_NAMENODE_OPTS="$NAMENODE_OPTS $HADOOP_NAMENODE_OPTS"
export HADOOP_DATANODE_OPTS="$DATENODE_OPTS $HADOOP_DATANODE_OPTS"
jstat命令输出
查看GC日志输出
总结:
在HDFS Namenode内存中的对象大都是文件,目录和blocks,这些数据只要不被程序或者数据的拥有者人为的删除,就会在Namenode的运 行生命期内一直存在,所以这些对象通常是存在在old区中,所以,如果整个hdfs文件和目录数多,blocks数也多,内存数据也会很大,如何降低Full GC的影响?
export HADOOP_NAMENODE_OPTS="-server -Xmx220G -Xms200G -XX:+UseG1GC - XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions - XX:+ParallelRefProcEnabled -XX:-ResizePLAB -XX:+PerfDisableSharedMem -XX:- OmitStackTraceInFastThrow -XX:G1NewSizePercent=2 -XX:ParallelGCThreads=23 - XX:InitiatingHeapOccupancyPercent=40 -XX:G1HeapRegionSize=32M - XX:G1HeapWastePercent=10 -XX:G1MixedGCCountTarget=16 -verbose:gc - XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps - XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=100M - Xloggc:/var/log/hbase/gc.log -Dhadoop.security.logger=${HADOOP_SECURITY_LOGGER:- INFO,RFAS} -Dhdfs.audit.logger=${HDFS_AUDIT_LOGGER:-INFO,NullAppender} $HADOOP_NAMENODE_OPTS"
注意:如果现在采用的垃圾收集器没有问题,就不要选择G1,如果追求低停顿,可以尝试使用G1
系统: CentOS-7_x86_64
protobuf: protoc-2.5.0
maven: maven-3.6.0
hadoop: hadoop-2.9.2
java: jdk1.8.0_131
cmake: cmake-2.8.12.2
OpenSSL: OpenSSL 1.0.2k-fips
findbugs: findbugs-1.3.9
# 安装编译需要的依赖库
yum install -y lzo-devel zlib-devel autoconf automake libtool cmake openssl- devel cmake gcc gcc-c++
#上传maven安装包 # 解压缩 $ tar -zxvf apache-maven-3.6.3-bin.tar.gz -C /usr/local/ # 配置到系统环境变量 $ vim /etc/profile export MAVEN_HOME=/usr/local/apache-maven-3.6.3 export PATH=$PATH:$MAVEN_HOME/bin # 刷新配置文件 $ source /etc/profile # 验证maven安装是是否成功 $ mvn -version [root@localhost ~]# mvn -version Apache Maven 3.6.0 (ff8f5e7444045639af65f6095c62210b5713f426; 2018-10- 25T03:39:06+08:00) Maven home: /usr/local/apache-maven-3.6.3 Java version: 1.8.0_131, vendor: Oracle Corporation Java home: /usr/local/jdk1.8.0_131/jre Default locale: en_US, platform encoding: UTF-8 OS name: "linux", version: "4.20.13-1.el7.elrepo.x86_64", arch: "amd64", family: "unix"
# 安装依赖环境 $ yum groupinstall Development tools -y # 下载 $ https://github.com/protocolbuffers/protobuf/releases/download/v2.5.0/protobuf- 2.5.0.tar.gz #上传protobuf安装包 # 解压缩 $ tar -zxvf protobuf-2.5.0.tar.gz cd protobuf-2.5.0 # 进入解压目录 配置安装路径(--prefix=/usr/local/protobuf-2.5.0) $ ./configure --prefix=/usr/local/protobuf-2.5.0 # 编译 $ make # 验证编译文件 $ make check # 安装 $ make install # 配置protobuf环境变量 $ vim /etc/profile export PROTOCBUF_HOME=/usr/local/protobuf-2.5.0 export PATH=$PATH:$PROTOCBUF_HOME/bin # 刷新配置文件 $ source /etc/profile # 验证是否安装成功 $ protoc --version [root@localhost ~]# protoc --version libprotoc 2.5.0
#下载 $https://jaist.dl.sourceforge.net/project/findbugs/findbugs/1.3.9/findbugs-1.3.9.tar.gz #上传安装包 # 解压缩 $ tar -zxvf findbugs-1.3.9.tar.gz -C /usr/local/ # 配置系统环境变量 $ vim /etc/profile export FINDBUGS_HOME=/usr/local/findbugs-1.3.9 export PATH=$PATH:$FINDBUGS_HOME/bin # 刷新配置文件 $ source /etc/profile # 验证是否安装成功 $ findbugs -version [root@localhost ~]# findbugs -version 1.3.9
找到maven环境下的settings.xml文件,添加镜像代理
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
<mirror>
<id>nexus-public-snapshots</id>
<mirrorOf>public-snapshots</mirrorOf>
<url>http://maven.aliyun.com/nexus/content/repositories/snapshots/</url>
</mirror>
进入代码文件目标路径
/root/hadoop-2.9.2-src/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop- mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/lib/input
编译
进入Hadoop源码目录
cd /root/hadoop-2.9.2-src
执行编译命令
mvn package -Pdist,native -DskipTests -Dtar
问题解决
hadoop-aws:jar时缺少依赖包DynamoDBLocal:jar
选择手动下载该Jar包,上传到本地maven仓库
cd /root/.m2/repository/com/amazonaws/DynamoDBLocal/1.11.86
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。