在这篇文章中,我们将会分享一些对Hadoop进行性能调优的方法,技巧。
这篇文章由我在阅读《Optimizing Hadoop for MapReduce》时,做的笔记,整理而成。
强烈建议读者去读一下上面重点标注的那本书。这本书,对如何对Hadoop进行性能调优,做了非常详细的介绍。
进行性能调优的方式
我们可以从下面的几个方面来对Hadoop进行优化:
- 优化HDFS
- 调整参数使CPU利用地更加充分
- 调整参数使内存利用地更加充分
- 调整参数使磁盘利用地更加充分
- 调整参数使网络利用地更加充分
- 对JVM进行调优
- 对操作系统进行调优
各个方面的具体参数
和CPU相关的参数
- mapred.tasktracker.map.tasks.maximum: TaskTracker上面,能够同时运行的map tasks的数量
- mapred.tasktracker.reduce.tasks.maximum: TaskTracker上面,能够同时运行的reduce tasks的数量
和磁盘相关的参数
- mapred.compress.map.output: 是否对mapper的输出进行压缩
- mapred.output.compress: 是否对job的输出进行压缩
- mapred.map.output.compression.codec: 启用哪个compression codec来对map的输出进行压缩
- mapred.local.dir: 存储mapper的中间结果的目录。如果指定了多个目录,那么就会均匀放置在不同的目录中。
- dfs.data.dir: DataNode用于存储数据的目录
和内存相关的参数
- mapred.child.java.opts: 为每个JVM task分配多大的内存
- mapred.child.ulimit: 指定为每个MapReduce job分配的最大虚拟内存
- io.sort.mb: 指定mapper的输出可以占用的内存
- io.sort.factor: 指定能够同时进行排序的文件的个数
- mapred.job.reduce.input.buffer.percent: Reducer端,用于保存mapper的输出结果的内存的大小
和网络相关的参数
- mapred.reduce.parallel.copies: 在Shuffle阶段,并行从mapper读取数据的线程的数量
- topology.script.file.name: 指定用于将DNS解析成主机的脚本的名称
hdfs-site.xml中和性能调优有关的参数
- dfs.access.time.precision: 文件访问时间戳的精确度。如果设置成0,则表示不启用文件访问时间戳。在负载很大的时候,能够提高性能。
- dfs.balance.bandwidthPerSec: 每个DataNode在rebalance block时,能够使用的最大带宽
- dfs.block.size: DataNode上block的大小
- dfs.data.dir: DataNode上用于存储数据的目录
- dfs.datanode.du.reserved: DataNode上保留的空间的大小
- dfs.datanode.handler.count: DataNode上处理block requests的handler的数量
- dfs.max.objects: 最多能够存储的object(包括文件,目录和block)的数量
- dfs.name.dir: NameNode上用于存储数据元数据的目录
- dfs.namenode.handler.count: NameNode上用于处理数据元数据的线程的数量
- dfs.name.edits.dir: NameNode上存储edit file的目录
- dfs.replication: 集群中,每个block的副本的数量
- dfs.replication.considerLoad: 当block在放置的时候,是否考虑data node的负载
core-site.xml中和性能调优有关的参数
- fs.default.name: 默认的文件系统
- hadoop.tmp.dir: 用于存储临时文件的目录
- fs.checkpoint.dir: Secondary NameNode用于存储checkpoints的目录
- io.file.buffer.size: 当读取或者写入文件时,可用的缓冲区的大小
和压缩相关的参数
- io.compression.codec: Hadoop用于确定是否支持特定compression codec
- mapreduce.map.output.compression: 是否对mapper的输出进行压缩
- mapreduce.map.output.compress.codec: 对mapper的输出进行压缩时,采用哪个compression codec
- mapreduce.output.fileoutputformat.compress: 是否对job的输出进行压缩
- mapreduce.output.fileoutputformat.compress.codec: 采用哪个compression codec对job的输出进行压缩
- mapreduce.output.fileoutputformat.compress.type: 对于SequenceFile,采用哪种压缩方式,可选值为NONE或者BLOCK
'
启用JVM重用
- mapred.job.reuse.jvm.num.tasks: 一个JVM能够运行的Task的最大值。设置成-1的话,则这个JVM可以运行无限个Tasks.
其他
这本书中,还详细介绍了如何确定Mapper或者Reducer的数量,如何确定一个HDFS集群中,需要多少个节点。
关于这部分内容,请自行查看这本书。