1. 程式人生 > 其它 >生產調優9 Hadoop綜合調優

生產調優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

開啟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

測試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的併發心跳以及客戶端併發的元資料操作。

[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