MapReduce程序效率的瓶颈在于两点:
计算机性能 CPU,内存,磁盘健康,网络I/O操作优化 (1)数据倾斜 (2)Map和Reduce数设置不合理 (3)Map运行时间太长,导致Reduce等待过久 (4)小文件过多 (5)大量的不可分块的超大文件 (6)Spill次数过多 (7)Merge次数过多MapReduce优化方法主要从六个方面考虑:数据输入、Map阶段、Reduce阶段、IO传输、数据倾斜问题和常用的调优参数。
就是设定一个一定大小的空间,然后把尽可能多的小文件都放进去,这样就不需要每一个小文件都要一个切片了。
资源相关参数 (1)以下参数是在用户自己的MR应用程序中配置就可以生效(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数目,默认值: 1mapreduce.reduce.cpu.vcores每个ReduceTask可使用的最多cpu core数目,默认值: 1mapreduce.reduce.shuffle.parallelcopies每个Reduce去Map中取数据的并行数。默认值是5mapreduce.reduce.shuffle.merge.percentBuffer中的数据达到多少比例开始写入磁盘。默认值0.66mapreduce.reduce.shuffle.input.buffer.percentBuffer大小占Reduce可用内存的比例。默认值0.7mapreduce.reduce.input.buffer.percent指定多少比例的内存用来存放Buffer中的数据,默认值是0.0(2)应该在YARN启动之前就配置在服务器的配置文件中才能生效(yarn-default.xml)
配置参数参数说明yarn.scheduler.minimum-allocation-mb给应用程序Container分配的最小内存,默认值:1024yarn.scheduler.maximum-allocation-mb给应用程序Container分配的最大内存,默认值:8192yarn.scheduler.minimum-allocation-vcores每个Container申请的最小CPU核数,默认值:1yarn.scheduler.maximum-allocation-vcores每个Container申请的最大CPU核数,默认值:4yarn.nodemanager.resource.memory-mb给Containers分配的最大物理内存,默认值:8192(3)Shuffle性能优化的关键参数,应在YARN启动之前就配置好(mapred-default.xml)
配置参数参数说明mapreduce.task.io.sort.mbShuffle的环形缓冲区大小,默认100mmapreduce.map.sort.spill.percent环形缓冲区溢出的阈值,默认80%容错相关参数(MapReduce性能优化)
配置参数参数说明mapreduce.map.maxattempts每个Map Task最大重试次数,一旦重试参数超过该值,则认为Map Task运行失败,默认值:4。mapreduce.reduce.maxattempts每个Reduce Task最大重试次数,一旦重试参数超过该值,则认为Map Task运行失败,默认值:4。mapreduce.task.timeoutTask超时时间,经常需要设置的一个参数,该参数表达的意思为:如果一个Task在一定时间内没有任何进入,即不会读取新的数据,也没有输出数据,则认为该Task处于Block状态,可能是卡住了,也许永远会卡住,为了防止因为用户程序永远Block住不退出,则强制设置了一个该超时时间(单位毫秒),默认是600000。如果你的程序对每条输入数据的处理时间过长(比如会访问数据库,通过网络拉取数据等),建议将该参数调大,该参数过小常出现的错误提示是“AttemptID:attempt_14267829456721_123456_m_000224_0 Timed out after 300 secsContainer killed by the ApplicationMaster.”。HDFS上每个文件都要在NameNode中都有对应的元数据,这个元数据的大小约为150byte,这样当小文件比较多的时候,一方面会大量占用NameNode的内存空间,另一方面就是元数据过多的情况查找速度变慢。 小文件过多,在进行MR计算时,会导致生成过多的切片. 需要启动过多的MapTask。
1)小文件优化的方向: (1)在数据采集的时候,就将小文件或小批数据合成大文件再上传HDFS。 (2)在业务处理之前,在HDFS上使用MapReduce程序对小文件进行合并。 (3)在MapReduce处理时,可采用CombineTextInputFormat提高效率。 (4)开启uber模式,实现jvm重用
2)Hadoop Archive 是一个高效的将小文件放入HDFS块中的文件存档工具,能够将多个小文件打包成一个HAR文件,从而达到减少NameNode的内存使用
3)SequenceFile SequenceFile是由一系列的二进制k/v组成,如果为key为文件名,value为文件内容,可将大批小文件合并成一个大文件
4)CombineTextInputFormat CombineTextInputFormat用于将多个小文件在切片过程中生成一个单独的切片或者少量的切片。
5)开启uber模式,实现jvm重用。默认情况下,每个Task任务都需要启动一个jvm来运行,如果Task任务计算的数据量很小,我们可以让同一个Job的多个Task运行在一个Jvm中,不必为每个Task都开启一个Jvm.
开启uber模式,在mapred-site.xml中添加如下配置
<!-- 开启uber模式 --> <property> <name>mapreduce.job.ubertask.enable</name> <value>true</value> </property> <!-- uber模式中最大的mapTask数量,可向下修改 --> <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 的值,可向下修改 --> <property> <name>mapreduce.job.ubertask.maxbytes</name> <value></value> </property>6)配置mapreduce.job.jvm.numtasks 参数实现在一个Jvm中运行多个Task . 如果设置为-1 , 则没有数量限制。 一般设置在 10-20之间.