hadoop 集群优化1

来源:互联网 发布:安装软件用什么软件源 编辑:程序博客网 时间:2024/05/29 16:56
 

1. 概述

随着企业要处理的数据量越来越大,MapReduce思想越来越受到重视。Hadoop是MapReduce的一个开源实现,由于其良好的扩展性和容错性,已得到越来越广泛的应用。Hadoop作为一个基础数据处理平台,虽然其应用价值已得到大家认可,但仍存在很多问题,以下是主要几个:

(1) Namenode/jobtracker单点故障。 Hadoop采用的是master/slaves架构,该架构管理起来比较简单,但存在致命的单点故障和空间容量不足等缺点,这已经严重影响了Hadoop的可扩展性。

(2) HDFS小文件问题。在HDFS中,任何block,文件或者目录在内存中均以对象的形式存储,每个对象约占150byte,如果有1000 0000个小文件,每个文件占用一个block,则namenode需要2G空间。如果存储1亿个文件,则namenode需要20G空间。这样namenode内存容量严重制约了集群的扩展。

(3) jobtracker同时进行监控和调度,负载过大。为了解决该问题,yahoo已经开始着手设计下一代Hadoop MapReduce(见参考资料1)。他们的主要思路是将监控和调度分离,独立出一个专门的组件进行监控,而jobtracker只负责总体调度,至于局部调度,交给作业所在的client。

(4) 数据处理性能。 很多实验表明,其处理性能有很大的提升空间。Hadoop类似于数据库,可能需要专门的优化工程师根据实际的应用需要对Hadoop进行调优,有人称之为“Hadoop Performance Optimization” (HPO)。

为了提高其数据性能,很多人开始优化Hadoop。总结看来,对于Hadoop,当前主要有几个优化思路:

(1) 从应用程序角度进行优化。由于mapreduce是迭代逐行解析数据文件的,怎样在迭代的情况下,编写高效率的应用程序,是一种优化思路。

(2) 对Hadoop参数进行调优。当前hadoop系统有190多个配置参数,怎样调整这些参数,使hadoop作业运行尽可能的快,也是一种优化思路。

(3) 从系统实现角度进行优化。这种优化难度是最大的,它是从hadoop实现机制角度,发现当前Hadoop设计和实现上的缺点,然后进行源码级地修改。该方法虽难度大,但往往效果明显。

以上三种思路出发点均是提高hadoop应用程序的效率。实际上,随着社会的发展,绿色环保观念也越来越多地融入了企业,因而很多人开始研究Green Hadoop,即怎样让Hadoop完成相应数据处理任务的同时,使用最少的能源(见参考资料[14][15])。

本文主要介绍了当前学术界的一些优化思路,有人试图从Hadoop自动配置角度对Hadoop进行优化,但更多的是从系统实现角度进行优化,概括其优化点和实验效果如下:

(1) 论文[6]试图从参数自动调优角度对Hadoop进行优化,论文只给出了可能的解决方案,并未给出实现,因而效果不可知。但它给出了一种Hadoop优化的新思路,即怎样对其190多个配置参数进行自动调整,使应用程序执行效率最高。

(2) 论文[7]提出prefetching和preshuffling机制,在不同负载不同规模集群下测试,效率提升了约73%。

(3) 论文[8]研究了影响Hadoop效率的五个因素,并通过提出相应的解决方案,使Hadoop效率提高了2.5~3.5倍。

(4) 论文[9]为Hadoop提供了一种索引机制– Trojan Index,同时提出了一种高效的join算法– Trojan Join,实验表明,效率比Hadoop和HadoopDB高很多。

除了学术界的优化,工业界也在不断进行优化以适应自己公司的产品需要,主要有:

(1)Baidu公司。baidu对Hadoop中关键组件使用C++进行了重写(包括map, shuffler和reducer等),经他们内部测试(5 nodes,40GB data),效率提升了约20%(见参考资料[4])。

(2)淘宝。淘宝针对自己集群特点(作业小,slot多,作业之间有依赖,集群共享,有些作业有时效性),对jobtracker和namenode进行了优化,据其官方博客称,其jobtracker有较大性能提升,且namenode吞吐量提升了8+倍(见参考资料[5])。但其具体优化方法,未公开。

2. 从应用程序角度进行优化

(1) 避免不必要的reduce任务

如果要处理的数据是排序且已经分区的,或者对于一份数据, 需要多次处理, 可以先排序分区;然后自定义InputSplit, 将单个分区作为单个mapred的输入;在map中处理数据, Reducer设置为空。

这样, 既重用了已有的 “排序”, 也避免了多余的reduce任务。

(2)外部文件引入

有些应用程序要使用外部文件,如字典,配置文件等,这些文件需要在所有task之间共享,可以放到分布式缓存DistributedCache中(或直接采用-files选项,机制相同)。

更多的这方面的优化方法,还需要在实践中不断积累。

(3) 为job添加一个Combiner

为job添加一个combiner可以大大减少shuffle阶段从map task拷贝给远程reduce task的数据量。一般而言,combiner与reducer相同。

(4) 根据处理数据特征使用最适合和简洁的Writable类型

Text对象使用起来很方便,但它在由数值转换到文本或是由UTF8字符串转换到文本时都是低效的,且会消耗大量的CPU时间。当处理那些非文本的数据时,可以使用二进制的Writable类型,如IntWritable, FloatWritable等。二进制writable好处:避免文件转换的消耗;使map task中间结果占用更少的空间。

(5) 重用Writable类型

很多MapReduce用户常犯的一个错误是,在一个map/reduce方法中为每个输出都创建Writable对象。例如,你的Wordcout mapper方法可能这样写:

public void map(...) {  …  for (String word : words) {    output.collect(new Text(word), new IntWritable(1));  }}

这样会导致程序分配出成千上万个短周期的对象。Java垃圾收集器就要为此做很多的工作。更有效的写法是:

class MyMapper … {  Text wordText = new Text();  IntWritable one = new IntWritable(1);  public void map(...) {    for (String word: words) {      wordText.set(word);      output.collect(wordText, one);    }  }}

(6) 使用StringBuffer而不是String

当需要对字符串进行操作时,使用StringBuffer而不是String,String是read-only的,如果对它进行修改,会产生临时对象,而StringBuffer是可修改的,不会产生临时对象。

(7)调试

最重要,也是最基本的,是要掌握MapReduce程序调试方法,跟踪程序的瓶颈。具体可参考:

http://www.cloudera.com/blog/2009/12/7-tips-for-improving-mapreduce-performance/

3. 对参数进行调优

3.1 参数自动调优

论文[6]试图从自动化参数调优角度对hadoop应用程序运行效率进行优化。Hadoop目前有190多个配置参数,其中大约有25个对hadoop应用程序效率有显著的影响。

论文首先分析了database优化思路。Database会根据用户输入的SQL建立一个代价模型:,其中y表示查询q优化目标(如运行时间),p表示q的查询计划,r表示为执行计划p而申请的资源量,d表示一些统计信息。数据库会根据该代价模型评估不同的查询计划,并选择一个最优的执行查询。这种数据库模型很难扩展应用到mapreduce环境中,主要是因为:

(1) mapreduce作业一般是采用C,C++或java编写,与声明性语言SQL有明显不同。

(2) 缺少有关输入数据的统计信息。Mapreduce作业通常是运行时解析动态输入文件的,因而运行之前schema或者统计信息均是未知的。

(3) 它们的优化空间不同。数据库的查询优化空间(主要是选择最优的plan)与mapreduce的优化空间(主要是配置参数调优)不同。

本论文提出了三种可行的方案,第一种是基于采样的方法,借鉴Terasort作业的思路,先对输入数据进行采样,然后通过样本估算不同配置下作业的执行时间,最后选择一种最优的配置。该方法需要解决的一个问题是,由于reduce阶段和map阶段存在数据依赖,因而map完成之前,reduce的所有信息均是未知的。有一种也是可行的思路是,执行作业之前,先采样选择一个样本组成一个小作业,然后执行该小作业以估算大作业性能。该方法也存在一个需要解决的问题,怎样采样才能使样本最能代表总体?

第二种是Late Binding,即延迟绑定,其思想是延迟设置其中的一个或多个参数,直到job已经部分执行,且这些参数可以确定。比如hadoop中的combiner操作实际就是采用的这一机制,作业在执行完map()之前不知道要不要进行combine。

第三种是Competition-based Approaches,其思想是,首先,同时执行多个配置有不同参数的task,然后,尽快决定哪种配置的task执行速度快,最后,杀掉其它task。

该文章完全是个调研性的论文,它先研究了数据库的一些调优方法,经过研究发现不可以直接将这些方法应用于mapreduce系统中,进而针对mapreduce独有的特点,提出了几种也许可行的方法,但论文中并未给出实现。

3.2 参数手工配置

3.2.1 Linux文件系统参数调整

(1) noatime 和 nodiratime属性

文件挂载时设置这两个属性可以明显提高性能。。默认情况下,Linux ext2/ext3 文件系统在文件被访问、创建、修改时会记录下文件的时间戳,比如:文件创建时间、最近一次修改时间和最近一次访问时间。如果系统运行时要访问大量文件,关闭这些操作,可提升文件系统的性能。Linux 提供了 noatime 这个参数来禁止记录最近一次访问时间戳。

(2) readahead buffer

调整linux文件系统中预读缓冲区地大小,可以明显提高顺序读文件的性能。默认buffer大小为256 sectors,可以增大为1024或者2408 sectors(注意,并不是越大越好)。可使用blockdev命令进行调整。

(3) 避免RAID和LVM操作

避免在TaskTracker和DataNode的机器上执行RAID和LVM操作,这通常会降低性能。

3.2.2 Hadoop通用参数调整

(1) dfs.namenode.handler.count或mapred.job.tracker.handler.count

namenode或者jobtracker中用于处理RPC的线程数,默认是10,较大集群,可调大些,比如64。

(2) dfs.datanode.handler.count

datanode上用于处理RPC的线程数。默认为3,较大集群,可适当调大些,比如8。需要注意的是,每添加一个线程,需要的内存增加。

(3) tasktracker.http.threads

HTTP server上的线程数。运行在每个TaskTracker上,用于处理map task输出。大集群,可以将其设为40~50。

3.2.3 HDFS相关配置

(1) dfs.replication

文件副本数,通常设为3,不推荐修改。

(2) dfs.block.size

HDFS中数据block大小,默认为64M,对于较大集群,可设为128MB或者256MB。(也可以通过参数mapred.min.split.size配置)

(3) mapred.local.dir和dfs.data.dir

这两个参数mapred.local.dir和dfs.data.dir 配置的值应当是分布在各个磁盘上目录,这样可以充分利用节点的IO读写能力。运行 Linux sysstat包下的iostat -dx 5命令可以让每个磁盘都显示它的利用率。

3.2.4 map/reduce 相关配置

(1) {map/reduce}.tasks.maximum

同时运行在TaskTracker上的最大map/reduce task数,一般设为(core_per_node)/2~2*(cores_per_node)。

(2) io.sort.factor

当一个map task执行完之后,本地磁盘上(mapred.local.dir)有若干个spill文件,map task最后做的一件事就是执行merge sort,把这些spill文件合成一个文件(partition)。执行merge sort的时候,每次同时打开多少个spill文件由该参数决定。打开的文件越多,不一定merge sort就越快,所以要根据数据情况适当的调整。

(3) mapred.child.java.opts

设置JVM堆的最大可用内存,需从应用程序角度进行配置。

3.2.5 map task相关配置

(1) io.sort.mb

Map task的输出结果和元数据在内存中所占的buffer总大小。默认为100M,对于大集群,可设为200M。当buffer达到一定阈值,会启动一个后台线程来对buffer的内容进行排序,然后写入本地磁盘(一个spill文件)。

(2) io.sort.spill.percent

这个值就是上述buffer的阈值,默认是0.8,即80%,当buffer中的数据达到这个阈值,后台线程会起来对buffer中已有的数据进行排序,然后写入磁盘。

(3) io.sort.record

Io.sort.mb中分配给元数据的内存百分比,默认是0.05。这个需要根据应用程序进行调整。

(4) mapred.compress.map.output/ Mapred.output.compress

中间结果和最终结果是否要进行压缩,如果是,指定压缩方式(Mapred.compress.map.output.codec/ Mapred.output.compress.codec)。推荐使用LZO压缩。Intel内部测试表明,相比未压缩,使用LZO压缩的TeraSort作业运行时间减少60%,且明显快于Zlib压缩。

3.2.6 reduce task相关配置

(1) Mapred.reduce.parallel

Reduce shuffle阶段copier线程数。默认是5,对于较大集群,可调整为16~25。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 黄金价格多少钱一克 现在黄金多少钱一克 今日黄金多少钱一克 中国今日金价多少一克 今日9999金价多少一克 黄金现在多少钱一克 金价今日价格多钱一克 老凤祥黄金多少钱一克 今天银价格多少一克 沉香价格多少钱一克 黄金今日价格多少一克 目前黄金价格多少一克 黄金市场价多少一克 白金价格今天多少一克 18k金价格今天多少一克 黄金市场价格多少一克 奇楠沉香多少钱一克 纯银价格今天多少一克 二手黄金多少钱一克 黄金价格是多少一克 今日国际金价多少一克 黄金现在什么价格一克 饰品金价格今日一克多少钱 黄金加工费多少一克 现在的黄金价格多少一克 今天国际金价多少一克 回收黄金价格多少一克 金条回收多少钱一克 现在黄金什么价格一克 黄金价格回收多少一克 2013年黄金价格多少一克 今日黄金回收多少一克 18k白金回收多少钱一克 现在回收黄金多少一克 2019年今日9999金价多少一克 9999黄金价格今天多少一克 黄金饰品价格今天多少一克 黄金手饰价格今天多少一克 黄金收购价格今天多少一克 明牌黄金价格今天多少一克 现在黄金首饰价格多少一克