大数据参数调优

MapReduce参数调优

  • 设置文件压缩(对输入文件、Map的输出文件、reduce的输出文件进行压缩)

    • mapreduce.map.output.compress
  • HDFS:
    dfs.block.size

  • Mapreduce:
    io.sort.mb
    io.sort.spill.percent
    mapred.local.dir
    mapred.map.tasks & mapred.tasktracker.map.tasks.maximum
    mapred.reduce.tasks & mapred.tasktracker.reduce.tasks.maximum
    mapred.reduce.max.attempts
    mapred.reduce.parallel.copies
    mapreduce.reduce.shuffle.maxfetchfailures
    mapred.child.java.opts
    mapred.reduce.tasks.speculative.execution
    mapred.compress.map.output & mapred.map.output.compression.codec
    mapred.reduce.slowstart.completed.maps
    下面来谈谈重头戏,那就是mapred中的这些NB的参数。前置知识我相信大家都已经了解了(如果你还不了解mapred的运行机制,看这个也无意义...),首先数据要进行map,然后merge,然后reduce进程进行copy,最后进行reduce,其中的merge和copy总称可以为shuffle。在你起一个job前,hadoop需要知道你要启动多少个map,多少个renduce进程,如果你进行默认参数启动,那么默认只有一个map线程。(reduce也许也是一个..)这个速度是很慢的。设置map启动个数的参数是mapred.map.tasks,reduce则是mapred.reduce.tasks。这两个参数可以说是对整个集群的性能起主导型作用的参数,调试也基本上围绕这两个参数。那大家要问就两个参数有什么好来回修改的呢?其实,这两个参数的设置配比也直接影响到其他的参数的设置。首当其冲的就是mapred.tasktracker.map.tasks.maximum以及 mapred.tasktracker.reduce.tasks.maximum。因为这两个参数设置了一台服务器上最多能同时运行的map和reduce数。现在我们来假设一个集群有一个namenode以及8个datanode,这是一个很客观的集群。我们假设上面的数据都是三备份,那么本地数据率为3/8。假设你设置的map.tasks=128,reuce.tasks=64,那么你的对应的两个maximum就应该分别为16以及8或是更高。因为这样才能保证你的所有map和reduce的任务都是分别同时启动的,如果你的设置reduce的maximum为7,那么你将得到非常糟糕的结果,因为这样8台机器同时可以运行的reduce数量为56了,比你设置的64差8个进程,这八个进程将会处于pending状态,直到某些正在运行的reduce完成它才能补上运行,势必大幅度的增加了运行时间。当然,这也不是越大越好,因为map有很长的一段时间是和reduce进程共存的,共存的时间取决于你设置的mapred.reduce.slowstart.completed.maps,如果你设置为0.6.那么reduce将在map完成60%后进入运行态。所以说,如果你设置的map和reduce参数都很大,势必造成map和reduce争抢资源,造成有些进程饥饿,超时出错,最大的可能就是socket.timeout的出错,网络过于繁忙。所以说,这些需要根据集群的性能,适当调试添加和减少,以达到最好的效果。那么,map和reduce之间是怎样的配比比较好呢?apache官网给了我们一些建议,比如设置reduce与map,他们之间有一个具体的公式。但是实际情况总是不能用公式来套用的(否则就不需要系统工程师了...)。一般情况下,当你设置好map和reduce进程数后,你可以通过hadoop的mapred的页面入口(http://namenode:50030/jobdetai.jps)查看map和reduce进度,如果你发现reduce在33%时,map正好提早一点点到100%,那么这将是最佳的配比,因为reduce是在33%的时候完成了copy阶段,也就是说,map需要再reduce到达33%之前完成所有的map任务,准备好数据。千万不能让reduce在等待,但是可以让map先完成。
    OK!这个重点的搞完之后我们在看看两个息息相关的参数,io.sort.mbmapred.child.java.opts。因为每一个map或是reduce进程都是一个task,都会对应启动一个JVM,所以其实java.opts也与你启动的map和reduce数以及别的一些jvm敏感的参数有关。既然task运行在JVM里面,那么,我这里所要提到的sort.mb 也是分配在JVM中的,这个值是用来设置到底我一个map sort的可用buffer大小是多少,如果map在内存中sort的结果达到一个特定的值,就会被spill进入硬盘。具体这个值是等于mbio.sort.spill.percent.。按照通常的设置方式,为了让jvm发挥最佳性能,一般设置JVM的最大可用内存量为mb设置的内存量的两倍。那么mb的内存量又根据什么设置呢?它主要是与你的一个map的结果数据量有关。如果一个map的结果数据量为600M,那么如果你设置的mbio.sort.spill.percent.=200M,那么将进行3次spill进入硬盘,然后map完成后再将数据从硬盘上取出进行copy。所以,这个mb设置如果是600M的话,那么就不需要进行这次硬盘访问了,节省了很多时间。但是最大的问题是内存耗费很大。如果mb是600M,那么jvm.opts将需要设置为1G以上,那么,按照上例,你同时启动16个map和8个reduce 的话,那么你的内存至少应该有24G。所以,这里的设置也要慎重,因为毕竟你的服务器还要跑很多其他的服务。
    mapred.reduce.parallel.copiesmapreduce.reduce.shuffle.maxfetchfailures这些参数都是对网络有一些影响。第一个是reduce可以进行的最大并行拷贝线程数,这些线程会同时从不同的datanode上取map结果,而第二个出错重试次数过多对于很多我们的应用都是降低性能的一个问题。因为一般一个job重试了1次没有成功那基本以后无论怎么重试都是不会成功的,重试了不成功不要紧,关键是这个重试还大量的消耗系统的资源,让其他的线程可能也因为starvation而进入重试状态,恶性循环了。如果说你的网络确实很成瓶颈,千兆网都达不到,那么建议打开mapred.compress.map.output压缩选项,并配置 mapred.map.output.compression.codec压缩编码格式,一般都会使用snappy,因为这种格式对于压缩和解压缩都相对较快。还有就是如果你的集群是异构的,有些机器性能好,有些差,那么建议打开mapred.reduce.tasks.speculative.execution推测性执行,有利于优化进程分配,提升集群性能。
    来源: https://blog.csdn.net/yaoxiaochuang/article/details/50959158
  • Mapreduce的性能调优二

Hive参数调优

  • hive通过将查询划分成一个或多个MapReduce任务达到并行处理的目的。每个任务都可能具有多个mapper和reducer任务,其中至少有一些是可以并行执行的。
  • 确定最佳的mapper个数和reducer个数取决于多个变量,例如输入的数据量大小以及对这些数据执行的操作类型等。
  • 保持平衡性是很有必要的,对于Spark/Hadoop这样的大数据系统来讲,数据量大并不可怕,可怕的是数据倾斜,每个节点处理的运算不均衡。
  • 如果有太多的mapper或reducer任务,就会导致启动阶段、调度和运行job过程中产生过多的开销;而如果设置的数量太少,那就有可能没充分利用好集群内在并行性。

  • mapred.reduce.tasks
    所提交 Job 的 reduer 的个数,使用 Hadoop Client 的配置。

  • hive.mapred.mode
    Map/Redure 模式,如果设置为 strict,将禁止3中类型的查询:
    1.分区表的where筛选条件必须含有分区字段;
    2.对使用了order by语句的查询,必须使用limit语句(order by语句为执行排序会将所有的结果集数据分发到同一个reducer中进行处理,增加limit语句可以防止reducer额外执行很长时间)
    3.限制笛卡儿积的查询,就是有where语句,而没有on语句。
    'nonstrict'
  • hive.merge.mapfiles
    在Map-only的任务结束时合并小文件
    是否开启合并 Map 端小文件,当Hive输入由很多个小文件组成,由于每个小文件都会启动一个map任务,如果文件过小,会使得map任务启动和初始化的时间大于逻辑处理的时间,造成资源浪费,甚至OOM。为此,当我们启动一个任务,发现输入数据量小但任务数量多时,需要注意在Map前端进行输入合并。当然,在我们向一个表写数据时,也需要注意输出文件大小
    true

  • hive.merge.mapredfiles
    是否开启合并 Map/Reduce 小文件,即是否在Map-Reduce的任务结束时合并小文件
    false

  • hive.exec.parallel
    是否开启 map/reduce job的并发提交。
    false
  • hive.limit.optimize.enable
    当使用LIMIT语句时,其可以对数据源进行抽样,避免执行整个查询语句,然后再返回部分结果
    但这个功能有个缺点,有可能输入中有用的数据永远不会被处理到。
  • hive.exec.reducers.bytes.per.reducer
    每一个 reducer 的平均负载字节数。
    1000000000
  • hive.exec.reducers.max
    设置reducer个数的上限,可以阻止某个查询消耗过多的reducer资源,对这个属性值大小的设定,一个建议的计算公式如下:
    (集群总Reduce槽位个数*1.5) / (执行中查询的平均个数)
    1.5倍数是一个经验系数,用于防止未充分利用集群的情况。
    999
  • hive.exec.rowoffset
    hive提供了2种虚拟列:一种用于将要进行划分的输入文件名,另一种用于文件中的块内偏移量。当hive产生了非预期的或null的返回结果时,可以通过这些虚拟列诊断查询。通过这些“字段”,用户可以查看到哪个文件甚至哪些数据导致出现问题:
    SELECT
    INPUT_FILE_NAME,
    BLOCK_OFFSET_INSIDE_FILE,
    ROW_OFFSET_INSIDE_BLOCK,
    line
    FROM hive_text
    WHERE line LIKE '%hive%' LIMIT 2;
    true
  • hive.multigroupby.singlemr
    一个特别的优化,是否将查询中的多个group by操作组装到单个MapReduce任务中。
    false
  • hive.exec.dynamic.partition
    是否打开动态分区。
    false

  • hive.exec.dynamic.partition.mode
    打开动态分区后,动态分区的模式,有 strict 和 nonstrict 两个值可选,strict 要求至少包含一个静态分区列,nonstrict 则无此要求。
    strict

  • hive.exec.max.dynamic.partitions
    所允许的最大的动态分区的个数。
    1000

  • hive.exec.max.dynamic.partitions.pernode
    单个 reduce 结点所允许的最大的动态分区的个数。
    100

  • hive.exec.default.partition.name
    默认的动态分区的名称,当动态分区列为''或者null时,使用此名称。''
    'HIVE_DEFAULT_PARTITION'
  • hive.exec.mode.local.auto
    决定 Hive 是否应该自动地根据输入文件大小,在本地运行(在GateWay运行)
    true

  • hive.exec.mode.local.auto.inputbytes.max
    如果 hive.exec.mode.local.auto 为 true,当输入文件大小小于此阈值时可以自动在本地模式运行,默认是 128兆。
    134217728L

  • hive.exec.mode.local.auto.tasks.max
    如果 hive.exec.mode.local.auto 为 true,当 Hive Tasks(Hadoop Jobs)小于此阈值时,可以自动在本地模式运行。
    4

  • hive.auto.convert.join
    是否根据输入小表的大小,自动将 Reduce 端的 Common Join 转化为 Map Join,从而加快大表关联小表的 Join 速度。
    false

  • hive.mapred.local.mem
    Mapper/Reducer 在本地模式的最大内存量,以字节为单位,0为不限制。
    0

  • hive.exec.scratchdir
    HDFS路径,用于存储不同 map/reduce 阶段的执行计划和这些阶段的中间输出结果。
    /tmp/<user.name>/hive

  • hive.metastore.warehouse.dir
    Hive 默认的数据文件存储路径,通常为 HDFS 可写的路径。
    "

  • hive.groupby.skewindata
    决定 group by 操作是否支持倾斜的数据。
    false

  • hive.default.fileformat
    Hive 默认的输出文件格式,与创建表时所指定的相同,可选项为 'TextFile' 、 'SequenceFile' 或者 'RCFile'。
    'TextFile'

  • hive.map.aggr
    决定是否可以在 Map 端进行聚合操作
    true

  • hive.join.emit.interval
    Hive Join 操作的发射时间间隔,以毫秒为单位。
    1000

  • hive.mapjoin.cache.numrows
    Hive Map Join 所缓存的行数。
    25000

  • hive.groupby.mapaggr.checkinterval
    对于 Group By 操作的 Map 聚合的检测时间,以毫秒为单位。
    100000

  • hive.map.aggr.hash.percentmemory
    Hive Map 端聚合的哈稀存储所占用虚拟机的内存比例。
    0.5

  • hive.map.aggr.hash.min.reduction
    Hive Map 端聚合的哈稀存储的最小 reduce 比例。
    0.5

  • hive.merge.size.per.task
    每个任务合并后文件的大小,根据此大小确定 reducer 的个数,默认 256 M。
    256000000

  • hive.merge.smallfiles.avgsize
    需要合并的小文件群的平均大小,默认 16 M。
    16000000

  • mapred.min.split.size
    Map Reduce Job 的最小输入切分大小,与 Hadoop Client 使用相同的配置。
    1

  • hive.mergejob.maponly
    是否启用 Map Only 的合并 Job。
    true

  • hive.mapjoin.maxsize
    Map Join 所处理的最大的行数。超过此行数,Map Join进程会异常退出。
    1000000

  • hive.mapjoin.check.memory.rows
    设置每多少行检测一次内存的大小,如果超过 hive.mapjoin.localtask.max.memory.usage 则会异常退出,Map Join 失败。
    100000

  • hive.optimize.groupby
    是否优化 group by。
    true

  • hive.optimize.bucketmapjoin
    是否优化 bucket map join。
    false
    来源: https://www.cnblogs.com/binguo2008/p/7487782.html

Spark





猜你喜欢

转载自www.cnblogs.com/Marsm/p/06fe68c575a285406102ca0f0b751b8d.html