生产调优9 Hadoop综合调优

目录

Hadoop综合调优

Hadoop小文件优化方式

Hadoop小文件缺点

1.占用大量NameNode的内存空间,元数据文件过多,导致寻址速度变慢。

HDFS每个文件都要在NameNode上创建对应的元数据,这个元数据的大小约为150byte,当小文件很多时,就会产生很多的元数据文件。

2.导致MapTask的处理时间比启动时间还小,浪费资源

小文件过多,在执行MR计算时,会生成过多切片,需要启动过多的MapTask。每个MapTask处理的数据量小,导致MapTask的处理时间比启动时间还小,浪费资源。

Hadoop小文件解决办法

从数据源头方向

在数据采集的时候,将小文件合成大文件再上传HDFS

存储方向:Hadoop Archive

是一个高效的将小文件放入 HDFS 块中的文件存档工具,能够将多个小文件打包成一个 HAR 文件,从而达到减少 NameNode 的内存使用

计算方向:CombineTextInputFormat

CombineTextInputFormat 用于将多个小文件放在一起切片(默认是一个文件一个文件进行切片)生成一个单独的切片或者少量的切片

计算方向:开启uber模式,实现JVM重用

默认情况下,每个 Task 任务都需要启动一个 JVM 来运行,如果 Task 任务计算的数据量很小,我们可以让同一个 Job 的多个 Task 运行在一个 JVM 中,不必为每个 Task 都开启一个 JVM。减少JVM的开启和结束时间。

在一个Java进程开始运行后,虚拟机就开始实例化了,有多个进程启动就会实例化多个虚拟机实例。进程退出或者关闭,则虚拟机实例消亡,虚拟机实例之间不能共享数据。

案例

未开启 uber 模式,在/input 路径上上传多个小文件并执行 wordcount 程序

[ranan@hadoop102 hadoop-3.1.3]$ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount /input /output2

观察控制台 默认uber模式是关闭的

2021-12-20 21:09:13,157 INFO mapreduce.Job: Job job_1640005657193_0001 running in uber mode : false

观察 http://hadoop103:8088/cluster

生产调优9 Hadoop综合调优

开启uber模式,在/opt/module/hadoop-3.1.3/etc/hadoop/mapred-site.xml中添加如下配置

<!-- 开启 uber 模式,默认关闭 -->
<property>
<name>mapreduce.job.ubertask.enable</name>
<value>true</value>
</property>
<!-- uber 模式中最大的 mapTask 数量(9个mapTask使用一个JVM),只能改小 -->
<property>
<name>mapreduce.job.ubertask.maxmaps</name>
<value>9</value>
</property>
<!-- uber 模式中最大的 reduce 数量,只能改小-->
<property>
<name>mapreduce.job.ubertask.maxreduces</name>
<value>1</value>
</property>
<!-- uber 模式中最大的输入数据量,默认使用 dfs.blocksize 的值,可向下修改  并不是所有作业都适用于使用uber-->
<property>
<name>mapreduce.job.ubertask.maxbytes</name>
<value></value>
</property>

分发

[ranan@hadoop102 hadoop]$ xsync mapred-site.xml 

分发之后不用重启直接执行

[ranan@hadoop102 hadoop-3.1.3]$ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount /input /output

可以观察到uber mode打开了

2021-12-20 21:23:26,728 INFO mapreduce.Job: Job job_1640005657193_0002 running in uber mode : true

生产调优9 Hadoop综合调优

测试MapReduce计算性能

之前测试过HDFS的读写性能,也需要对MapReduce计算性能进行压测,了解集群计算能力。

前提:保证当前集群的HDFS配置、MapReduce配置、Yarn配置都完成

注:单个虚拟机磁盘小于150G尽量不要执行这段代码

案例

使用Sort程序(排序)测评MapReduce

1.使用 RandomWriter 来产生随机数,每个节点运行 10 个 Map 任务,每个 Map 产生大约 1G 大小的二进制随机数

[ranan@hadoop102 hadoop-3.1.3]$ hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar randomwriter random-data

2.执行 Sort 程序

[ranan@hadoop102 hadoop-3.1.3]$ hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar sort random-data sorted-data

3.验证数据是否真正排好序了

[ranan@hadoop102 hadoop-3.1.3]$ hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-clientjobclient-3.1.3-tests.jar testmapredsort -sortInput random-data-sortOutput sorted-data

企业开发场景案例

需求

从1G数据中,统计每个单词出现次数。
服务器3台,每台配置4G内置,4核CPU,4线程

需求分析

1G数据,需要开启多少个MapReduce
1G/128M = 8个切片 8个MapTask
没有说分区问题,那么默认就是1个ReduceTask
1个mrAppMaster

平均每个节点运行10/3 4 3 3 个任务

HDFS参数调优

1 NameNode内存环境配置

手动配置NameNode内存值,不采用自动的配置。
自动配置明明内存不足了还显示有,就会抢占linux系统内存,不合理。
在hadoop102上启动NN和DN(一般会分开),总内存4G,配置NN1G,DN1G

[ranan@hadoop102 ~]$ cd /opt/module/hadoop-3.1.3/etc/hadoop/
[ranan@hadoop102 hadoop]$ vim  hadoop-env.sh
[ranan@hadoop102 hadoop]$ xsync hadoop-env.sh

2 NameNode心跳并发配置

NameNode有一个工作线程池,用来处理不同DataNode的并发心跳以及客户端并发的元数据操作。

生产调优9 Hadoop综合调优

[ranan@hadoop102 ~]$ sudo yum install -y python
[ranan@hadoop102 ~]$ python

Python 2.7.5 (default, Apr 11 2018, 07:36:10)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2
Type "help", "copyright", "credits" or "license" for more
information.
>>> import math
>>> print int(20*math.log(3))
21
>>> quit()

计算出来21个线程 修改hdfs-site.xml

[ranan@hadoop102 hadoop]$ vim hdfs-site.xml 

<!-- 新增 -->
<property>
<name>dfs.namenode.handler.count</name>
<value>21</value>
</property>

[ranan@hadoop102 hadoop]$ xsync hdfs-site.xml 

3 开启回收站

开启回收站功能,可以将删除的文件在不超时的情况下,回复原数据,起到防止误删除、备份的等作用。默认是禁用的。

修改core-site.xml, 配置垃圾回收时间为 60 分钟。

[ranan@hadoop102 hadoop]$ vim core-site.xml 

<!--新增-->
<property>
<name>fs.trash.interval</name>
<value>60</value>  <!--单位是分钟-->
</property>

[ranan@hadoop102 hadoop]$ xsync core-site.xml 

MapReduce 参数调优

修改mapred-site.xml

<!-- 环形缓冲区大小,默认 100m -->
<property>
<name>mapreduce.task.io.sort.mb</name>
<value>100</value>
</property>
<!-- 环形缓冲区溢写阈值,默认 0.8 -->
<property>
<name>mapreduce.map.sort.spill.percent</name>
<value>0.80</value>
</property>
<!-- merge 合并次数,默认 10 个 -->
<property>
<name>mapreduce.task.io.sort.factor</name>
<value>10</value>
</property>
<!-- maptask 内存,默认 1g; maptask 堆内存大小默认和该值大小一致
mapreduce.map.java.opts -->
<property>
<name>mapreduce.map.memory.mb</name>
<value>-1</value>
<description>The amount of memory to request from the
scheduler for each map task. If this is not specified or is
non-positive, it is inferred from mapreduce.map.java.opts and
mapreduce.job.heap.memory-mb.ratio. If java-opts are also not
specified, we set it to 1024.
</description>
</property>
<!-- matask 的 CPU 核数,默认 1 个 -->
<property>
<name>mapreduce.map.cpu.vcores</name>
<value>1</value>
</property>
<!-- matask 异常重试次数,默认 4 次 -->
<property>
<name>mapreduce.map.maxattempts</name>
<value>4</value>
</property>
<!-- 每个 Reduce 去 Map 中拉取数据的并行数。默认值是 5 -->
<property>
<name>mapreduce.reduce.shuffle.parallelcopies</name>
	<value>5</value>
</property>
<!-- Buffer 大小占 Reduce 可用内存的比例, 默认值 0.7 -->
<property>
<name>mapreduce.reduce.shuffle.input.buffer.percent</name>
<value>0.70</value>
</property>
<!-- Buffer 中的数据达到多少比例开始写入磁盘, 默认值 0.66。 -->
<property>
<name>mapreduce.reduce.shuffle.merge.percent</name>
<value>0.66</value>
</property>
<!-- reducetask 内存,默认 1g; reducetask 堆内存大小默认和该值大小一致mapreduce.reduce.java.opts -->
<property>
<name>mapreduce.reduce.memory.mb</name>
<value>-1</value>
<description>The amount of memory to request from the
scheduler for each reduce task. If this is not specified or
is non-positive, it is inferred
from mapreduce.reduce.java.opts and
mapreduce.job.heap.memory-mb.ratio.
If java-opts are also not specified, we set it to 1024.
</description>
</property>
<!-- reducetask 的 CPU 核数,默认 1 个 -->
<property>
<name>mapreduce.reduce.cpu.vcores</name>
<value>2</value> <!-- 8个MapTask 1个ReduceTask,任务量大所以这里多开了一个 -->
</property>
<!-- reducetask 失败重试次数,默认 4 次 -->
<property>
<name>mapreduce.reduce.maxattempts</name>
<value>4</value>
</property>
<!-- 当 MapTask 完成的比例达到该值后才会为 ReduceTask 申请资源。默认是 0.05。假设有100个MapTask,5个执行完毕就可以申请ReduceTask-->
<property>
<name>mapreduce.job.reduce.slowstart.completedmaps</name>
<value>0.05</value>
</property>
<!-- 如果程序在规定的默认 10 分钟内没有读到数据,将强制超时退出 -->
<property>
<name>mapreduce.task.timeout</name>
<value>600000</value>
</property>

Yarn 参数调优

<!-- 选择调度器,默认容量 -->
<property>
<description>The class to use as the resource scheduler.</description>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capaci
ty.CapacityScheduler</value>
</property>
<!-- ResourceManager 处理调度器请求的线程数量,默认 50;如果提交的任务数大于 50,可以增加该值,但是不能超过 3 台 * 4 线程 = 12 线程(去除其他应用程序实际不能超过 8) -->
<property>
<description>Number of threads to handle scheduler
interface.</description>
<name>yarn.resourcemanager.scheduler.client.thread-count</name>
<value>8</value>
</property>
<!-- 是否让 yarn 自动检测硬件进行配置,默认是 false,如果该节点有很多其他应用程序,建议手动配置。如果该节点没有其他应用程序,可以采用自动 -->
<property>
<description>Enable auto-detection of node capabilities such as
memory and CPU.
</description>
<name>yarn.nodemanager.resource.detect-hardware-capabilities</name>
<value>false</value>
</property>
<!-- 是否将虚拟核数当作 CPU 核数,默认是 false,采用物理 CPU 核数 -->
<property>
<description>Flag to determine if logical processors(such as
hyperthreads) should be counted as cores. Only applicable on Linux
when yarn.nodemanager.resource.cpu-vcores is set to -1 and
yarn.nodemanager.resource.detect-hardware-capabilities is true.
</description>
<name>yarn.nodemanager.resource.count-logical-processors-ascores</name>
<value>false</value>
</property>
<!-- 虚拟核数和物理核数乘数,默认是 1.0 -->
<property>
<description>Multiplier to determine how to convert phyiscal cores to
vcores. This value is used if yarn.nodemanager.resource.cpu-vcores
is set to -1(which implies auto-calculate vcores) and
yarn.nodemanager.resource.detect-hardware-capabilities is set to true.
The number of vcores will be calculated as number of CPUs * multiplier.
</description>
<name>yarn.nodemanager.resource.pcores-vcores-multiplier</name>
<value>1.0</value>
</property>
<!-- NodeManager 使用内存数,默认 8G,修改为 4G 内存 -->
<property>
<description>Amount of physical memory, in MB, that can be allocated
for containers. If set to -1 and
yarn.nodemanager.resource.detect-hardware-capabilities is true, it is
automatically calculated(in case of Windows and Linux).In other cases, the default is 8192MB.
</description>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>4096</value>
</property>
<!-- nodemanager 的 CPU 核数,不按照硬件环境自动设定时默认是 8 个,修改为 4 个 -->
<property>
<description>Number of vcores that can be allocated
for containers. This is used by the RM scheduler when allocating
resources for containers. This is not used to limit the number of
CPUs used by YARN containers. If it is set to -1 and
yarn.nodemanager.resource.detect-hardware-capabilities is true, it is
automatically determined from the hardware in case of Windows and Linux.
In other cases, number of vcores is 8 by default.</description>
<name>yarn.nodemanager.resource.cpu-vcores</name>
<value>4</value>
</property>
<!-- 容器最小内存,默认 1G -->
<property>
<description>The minimum allocation for every container request at the
RM in MBs. Memory requests lower than this will be set to the value of
this property. Additionally, a node manager that is configured to have
less memory than this value will be shut down by the resource manager.
</description>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>1024</value>
</property>
<!-- 容器最大内存,默认 8G,修改为 2G -->
<property>
<description>The maximum allocation for every container request at the
RM in MBs. Memory requests higher than this will throw an
InvalidResourceRequestException.
</description>
<name>yarn.scheduler.maximum-allocation-mb</name>
<value>2048</value>
</property>
<!-- 容器最小 CPU 核数,默认 1 个 -->
<property>
<description>The minimum allocation for every container request at the
RM in terms of virtual CPU cores. Requests lower than this will be set to
the value of this property. Additionally, a node manager that is configured
to have fewer virtual cores than this value will be shut down by the
resource manager.
</description>
<name>yarn.scheduler.minimum-allocation-vcores</name>
<value>1</value>
</property>
<!-- 容器最大 CPU 核数,默认 4 个,修改为 2 个 -->
<property>
<description>The maximum allocation for every container request at the
RM in terms of virtual CPU cores. Requests higher than this will throw an
InvalidResourceRequestException.</description>
<name>yarn.scheduler.maximum-allocation-vcores</name>
<value>2</value>
</property>
<!--虚拟内存检查,默认打开,修改为关闭 -->
<property>
<description>Whether virtual memory limits will be enforced for
containers.</description>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
<!-- 虚拟内存和物理内存设置比例,默认 2.1 -->
<property>
<description>Ratio between virtual memory to physical memory when
setting memory limits for containers. Container allocations are
expressed in terms of physical memory, and virtual memory usage is
allowed to exceed this allocation by this ratio.
</description>
<name>yarn.nodemanager.vmem-pmem-ratio</name>
<value>2.1</value>
</property>

执行程序

重启集群

sbin/stop-yarn.sh
sbin/start-yarn.sh

执行WordCount程序

share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount /input /output
上一篇:【Bugs】RuntimeError CUDA out of memory


下一篇:云监控站点监控报警异常