打怪升级之小白的大数据之旅(五十九)<Hadoop优化方案>
Posted GaryLea
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了打怪升级之小白的大数据之旅(五十九)<Hadoop优化方案>相关的知识,希望对你有一定的参考价值。
打怪升级之小白的大数据之旅(五十八)
Hadoop优化方案与扩展知识点
上次回顾
上一章,我们对Hadoop的扩展知识HA进行了学习,本章是我们在使用Hadoop过程中的一些优化方案和其他几个需要了解的扩展知识,因为压缩和HA更加重要一些,所以我单独抽出来了
Hadoop优化方案
为什么要优化
- 我们在为Hadoop优化之前,首先要了解,我们要优化的地方在哪里,我们的程序哪一个部分可以进行优化,如果不了解、我们可能会适得其反
- 通常情况下,Hadoop的优化大部分都是在MR程序中,因为MR程序是我们整个Hadoop的核心工作
MapReduce可能导致运行缓慢的原因
- 计算机性能
- 这个问题的解决很简单:一个字,钱,当然了,这是在我们可承受的情况下,一般我们程序猿们几乎不需要关注这个问题
- I/O操作
- 数据倾斜
- Map和Reduce数量设置不合理
- Map运行时间过长导致Reduce等待过久
- 小文件过多
- 大量的不可分块的超大文件
- spill次数过多
- Merge次数过多
MapReduce优化方法
MapReduce优化方法主要从六个方面考虑:数据输入、Map阶段、Reduce阶段、IO传输、数据倾斜问题和常用的调优参数
数据输入
- 数据输入造成MR运行缓慢的原因通常情况下都是因为小文件比较多,因为每个小文件,会产生一个Map任务,任务的装载比较耗时
- 我们可以采用ComBineTextInputFormat作为输入来解决输入端大量小文件的问题
Map阶段
Map阶段有两个造成运行缓慢的原因,分别是溢写Spill阶段和Merge阶段
溢写阶段
- 减少溢写次数:Map阶段后,会将数据存储到环形缓冲区,然后对其进行分区排序、溢写,溢写次数过多会造成频繁的IO,所以我们可以增加Spill内存上限来减少溢写Spill的次数
Merge阶段
- 减少合并次数:通过IO.sort.factor参数,增大Merge的文件数目,从而减少Merge的次数
如果情况运行,我们可以在不影响业务逻辑的前提下,先对数据进行Combine处理,这样可以减少IO操作
Reduce阶段
- 合理设置Map和Reduce的数量,可以减少一定的运行时间
- 因为两个都不能设置太少或者太多,太少会导致Task处于等待状态,增加处理时间
- 太多会导致Map和Reduce任务间竞争资源,造成处理超时等问题
- 如果有可能,我们可以尽量规避使用Reduce。因为Reduce阶段在连接数据集的时候会产生大量的网络资源
- 如果无法规避Reduce,我们也要尽量使得Map和Reduce共存
- 因为在Map运行时,Reduce会等待,我们可以通过调整参数,让Map运行一段时间后,Reduce就开始工作,这样就可以在一定程度上提高MR的工作效率
- 我们知道,MR的Buffer阶段分为Map的后半段和Reduce的前半段
- 在Reduce那段时,默认情况下,数据到达一定阈值时Buffer会对数据进行落盘,也就是写入磁盘,此时如果频繁落盘就会造成很多的IO操作
- 我们可以通过修改配置参数,使得Buffle中一部分数据直接从内存输送到Reduce而不再进行落盘,从而减少IO的开销
IO传输
- 通过前面我们学习的压缩知识,想必大家一看到IO传输就知道如何进行优化了吧?没错,我们可以进行数据压缩的方式来完成数据的IO操作
- 通常情况下,我们都会采用Snappy和Lzo的方法进行压缩,因为它们快!
数据倾斜
在我们的工作中,数据倾斜问题是一个普遍的现象,数据倾斜我在前面提到过,数据倾斜分为两种情况
- 数据频率倾斜:某一区域的数据量远远大于其他区域
- 数据大小倾斜: 部分记录的大小远远大于平均值
- 既然数据倾斜问题是无法根治的,那么我们可以通过一些调优方法来减少数据倾斜
减少数据倾斜的方法
- 抽样和分区
- 这个很好理解,我们直接对数据进行抽样然后自定义分区,这样就可以一定程度上减少数据倾斜问题
- Combine
- 万金油的Combine,我们通过Combine合并大量小数据来减少数据倾斜
- 采用Map Join尽量避免Reduce Join
- 在前面讲MR的时候,提到过数据连接Join并通过代码来演示具体的实现方法,
- 我们知道Map Join 和 Reduce Join的主要区别就是 Map Join是通过将一个小文件存储在内存中实现Join的,
- 而Reduce通过磁盘中文件合并的方式进行,所以,如果硬件Hold住的话,我们尽量采用Map Join
- 在前面讲MR的时候,提到过数据连接Join并通过代码来演示具体的实现方法,
常用的调优参数
资源相关参数
- 下面的参数是默认值,我们可以通过用户自定义来更改。例如修改mapred-default.xml参数,我们就可以根据下面的表格,添加参数到 mapred-stie.xml中进行修改
mapred-default.xml
配置参数 | 参数说明 |
---|---|
mapreduce.map.memory.mb | 一个MapTask可使用的资源上限(单位:MB),默认为1024。如果MapTask实际使用的资源量超过该值,则会被强制杀死。 |
mapreduce.reduce.memory.mb | 一个ReduceTask可使用的资源上限(单位:MB),默认为1024。如果ReduceTask实际使用的资源量超过该值,则会被强制杀死。 |
mapreduce.map.cpu.vcores | 每个MapTask可使用的最多cpu core数目,默认值: 1 |
mapreduce.reduce.cpu.vcores | 每个ReduceTask可使用的最多cpu core数目,默认值: 1 |
mapreduce.reduce.shuffle.parallelcopies | 每个Reduce去Map中取数据的并行数。默认值是5 |
mapreduce.reduce.shuffle.merge.percent | Buffer中的数据达到多少比例开始写入磁盘。默认值0.66 |
mapreduce.reduce.shuffle.input.buffer.percent | Buffer大小占Reduce可用内存的比例。默认值0.7 |
mapreduce.reduce.input.buffer.percent | 指定多少比例的内存用来存放Buffer中的数据,默认值是0.0 |
yarn-default.xml
配置参数 | 参数说明 |
---|---|
yarn.scheduler.minimum-allocation-mb | 给应用程序Container分配的最小内存,默认值:1024 |
yarn.scheduler.maximum-allocation-mb | 给应用程序Container分配的最大内存,默认值:8192 |
yarn.scheduler.minimum-allocation-vcores | 每个Container申请的最小CPU核数,默认值:1 |
yarn.scheduler.maximum-allocation-vcores | 每个Container申请的最大CPU核数,默认值:32 |
yarn.nodemanager.resource.memory-mb | 给Containers分配的最大物理内存,默认值:8192 |
shuffle性能优化的关键参数
配置参数 | 参数说明 |
---|---|
mapreduce.task.io.sort.mb | Shuffle的环形缓冲区大小,默认100m |
mapreduce.map.sort.spill.percent | 环形缓冲区溢出的阈值,默认80% |
容错相关参数
配置参数 | 参数说明 |
---|---|
mapreduce.map.maxattempts | 每个Map Task最大重试次数,一旦重试参数超过该值,则认为Map Task运行失败,默认值:4。 |
mapreduce.reduce.maxattempts | 每个Reduce Task最大重试次数,一旦重试参数超过该值,则认为Map Task运行失败,默认值:4。 |
mapreduce.task.timeout | Task超时时间,经常需要设置的一个参数,该参数表达的意思为:如果一个Task在一定时间内没有任何进入,即不会读取新的数据,也没有输出数据,则认为该Task处于Block状态,可能是卡住了,也许永远会卡住,为了防止因为用户程序永远Block住不退出,则强制设置了一个该超时时间(单位毫秒),默认是600000。如果你的程序对每条输入数据的处理时间过长(比如会访问数据库,通过网络拉取数据等),建议将该参数调大,该参数过小常出现的错误提示是“AttemptID:attempt_14267829456721_123456_m_000224_0 Timed out after 300 secsContainer killed by the ApplicationMaster.”。 |
HDFS小文件优化方法
有关小文件会造成HDFS运行缓慢的原因我前面提过了很多次了,我再重复一次哈
- HDFS上每个文件都要在NameNode上建立一个索引,这个索引的大小约为150byte,这样当小文件比较多的时候,就会产生很多的索引文件,一方面会大量占用NameNode的内存空间,另一方面就是索引文件过大使得索引速度变慢
针对小文件的优化方案如下
- 在数据采集的时候,就将小文件或小批数据合成大文件再上传HDFS。
- 在业务处理之前,在HDFS上使用MapReduce程序对小文件进行合并。
- 在MapReduce处理时,可采用CombineTextInputFormat提高效率
- 开启JVM重用机制
- 对于大量小文件job,开启JVM重用会减少45%的运行时间
- JVM重用原理就是:每一个Job的运行会有很多的MapTask和Reduce,每一个Task都会创造一个单独的JVM,开启JVM重用,就是指当一个Task运行完成,在此JVM上运行下一个Task
Hadoop扩展知识点
集群间数据拷贝
scp实现两个远程主机之间的文件复制
// 推push,将当前节点文件推送到hadoop103服务器上
scp -r hello.txt root@hadoop103:/user/conpany/hello.txt
// 拉pull,从103服务器上获取一个文件
scp -r root@hadoop103:/user/conpany/hello.txt hello.txt
// 将hadoop103的文件,复制到hadoop104上
scp -r root@hadoop103:/user/conpany/hello.txt root@hadoop104:/user/hadoopuser
采用distcp命令实现两个Hadoop集群之间的递归数据复制
- 因为我没有两个集群,就不写示例了,大家可以查官网文档
hadoop distcp
这个命令 - hadoop distcp 这个命令就是用于集群间数据的拷贝的
小文件存档
- 小文件存档指的是在小文件存储时,采用HDFS存档文件或HAR文件对小文件进行存储
- 通俗一些来说,小文件通过HDFS存档或HAR存档在我们看来没什么区别,但是对NameNode而言,是一个整体,
- 这样可以减少元数据的体量,从而减少NameNode的内存消耗
小文件存储示例
-
启动Yarn进程
start-yarn.sh
-
归档文件
# 把/user/company/input目录里面的所有文件归档成一个叫input.har的归档文件,并把归档后文件存储到/user/company/output路径下 bin/hadoop archive -archiveName input.har -p /user/company/input /user/company/output
-
查看归档
hadoop fs -ls -r /user/company/output/input.har hadoop fs -ls -r har:///user/atguigu/output/input.har
-
解归档文件
hadoop fs -cp har:/// user/company/output/input.har/* /user/company
回收站
- 开启回收站功能,可以将删除的文件在不超时的情况下,恢复原数据,起到防止误删除、备份等作用
- 回收站工作机制就类似我们windows中的回收站,只不过它可以设置定时时间,自动对回收站进行清理
- 回收站参数说明
- fs.trashinterval=0, 默认0表示禁用回收站,其他非0的数值表示开启回收站
- fs.trash.checkpoint.interval=0, 默认0表示这个值的设置和上面的参数值相等,它代表检查回收站的间隔时间
- 一般要求 fs.trash.checkpoint.interval<= fs.trashinterval
回收站的使用
- 启用回收站
# 修改core-site.xml,配置垃圾回收时间为1分钟
<property>
<name>fs.trash.interval</name>
<value>1</value>
</property>
-
查看回收站
回收站在集群中的路径:/user/hadoopuser/.Trash/….
-
修改访问垃圾回收站的用户名称
# 进入垃圾回收站用户名称,默认是dr.who,修改为hadoopuser用户,修改配置文件core-site.xml <property> <name>hadoop.http.staticuser.user</name> <value>hadoopuser</value> </property>
-
通过程序删除的文件不会经过回收站,需要调用moveToTrash()才进入回收站
Trash trash = New Trash(conf); trash.moveToTrash(path);
-
恢复回收站数据
hadoop fs -mv /user/hadoopuser/.Trash/Current/user/hadoopuser/input /user/hadoopuser/input
-
清空回收站
hadoop fs -expunge
多NN的HA架构
- 在我们上一章学习HA的时候提到过,并且我们的HA就采用的是多NN的方法,在hadoop2.0版本中,HA架构只允许两个NN
- 但是当我们需要更高的容错性来保证数据完整是就要采用多NN的方法,具体方法参考上一章的HA即可
纠删码
- HDFS中的默认3副本方案在存储空间和其他资源(例如,网络带宽)中具有200%的开销。
- 但是,对于I / O活动相对较低暖和冷数据集,在正常操作期间很少访问其他块副本,但仍会消耗与第一个副本相同的资源量。
- 纠删码(Erasure Coding)能够在不到50% 的数据冗余情况下提供和3副本相同的容错能力,
- 因此,使用纠删码作为副本机制的改进是自然而然的
总结
- 本章节主要是对Hadoop的一些优化方法和一些扩展知识进行分享,优化方法的原则是根据实际情况,灵活变化,就如同我在压缩那一章所说,合适的压缩会提高工作效率,反之还会减少工作效率甚至出现各种各样的问题发生
- 好了,我们Hadoop框架的知识点告一段落了,下一章我为大家带来Hive的相关知识
以上是关于打怪升级之小白的大数据之旅(五十九)<Hadoop优化方案>的主要内容,如果未能解决你的问题,请参考以下文章
打怪升级之小白的大数据之旅(五十三)<Hadoop最后一个模块--Yarn>
打怪升级之小白的大数据之旅(五十四)<Zookeeper概述与部署>
打怪升级之小白的大数据之旅(五十)<MapReduce框架原理二:shuffle>