posts - 28, comments - 37, trackbacks - 0, articles - 0

2012年6月3日


淘宝招聘hadoop工程师若干, 面向在校生(2014年毕业),工作地点:杭州或北京

Hadoop研发工程师
职位描述
您将负责:
1.预研、开发、测试hdfs/mapreduce/hive/hbase的功能、性能和扩展;
2.对有助于提升集群处理能力/高可用性/高扩展性的各种解决方案进行跟踪和落地;
3.解决海量数据不断增长面临的挑战,解决业务需求。

您需要具备:
1、熟练运用java语言;
2、熟悉jvm运行机制、熟悉linux;
3、至少熟悉hadoop、hbase、hive等软件之一;

 

有意者请发送邮件到 yuling.sh@taobao.com 

posted @ 2013-09-15 18:21 俞灵 阅读(932) | 评论 (1)编辑 收藏


mapreduce,一个jobmap个数, 每个map处理的数据量是如何决定的呢? 另外每个map又是如何读取输入文件的内容呢? 用户是否可以自己决定输入方式, 决定map个数呢? 这篇文章将详细讲述hadoop中各种InputFormat的功能和如何编写自定义的InputFormat.

 

简介: mapreduce作业会根据输入目录产生多个map任务, 通过多个map任务并行执行来提高作业运行速度, 但如果map数量过少, 并行量低, 作业执行慢, 如果map数过多, 资源有限, 也会增加调度开销. 因此, 根据输入产生合理的map, 为每个map分配合适的数据量, 能有效的提升资源利用率, 并使作业运行速度加快.

    mapreduce, 每个作业都会通过 InputFormat来决定map数量. InputFormat是一个接口, 提供两个方法:

InputSplit[] getSplits(JobConf job, int numSplits) throws IOException;

RecordReader<K, V> getRecordReader(InputSplit split,

                                     JobConf job,

                                     Reporter reporter) throws IOException;

    其中getSplits方法会根据输入目录产生InputSplit数组, 每个InputSplit会相应产生一个map任务, map的输入定义在InputSplit. getRecordReader方法返回一个RecordReader对象, RecordReader决定了map任务如何读取输入数据, 例如一行一行的读取还是一个字节一个字节的读取, 等等.

    下图是InputFormat的实现类:

       (暂时无法上传)

    这理详细介绍FileInputFormatCombineFileInputFormat, 其它不常用,有兴趣的可以自己查看hadoop源码.


 

FileInputFormat(旧接口org.apache.hadoop.mapred)

 

mapreduce默认使用TextInputFormatTextInputFormat没有实现自己的getSplits方法,继承于FileInputFormat, 因此使用了FileInputFormat的.

org.apache.hadoop.mapred.FileInputFormatgetSplits流程:

两个配置

mapred.min.split.size        (一个map最小输入长度),

mapred.map.tasks                (推荐map数量)

如何决定每个map输入长度呢? 首先获取输入目录下所有文件的长度和, 除以mapred.map.tasks得到一个推荐长度goalSize, 然后通过式子: Math.max(minSize, Math.min(goalSize, blockSize))决定map输入长度. 这里的minSizemapred.min.split.size, blockSize为相应文件的block长度. 这式子能保证一个map的输入至少大于mapred.min.split.size, 对于推荐的map长度,只有它的长度小于blockSize且大于mapred.min.split.size才会有效果. 由于mapred.min.split.size默认长度为1, 因此通常情况下只要小于blockSize就有效果,否则使用blockSize做为map输入长度.

因此, 如果想增加map, 可以把mapred.min.split.size调小(其实默认值即可), 另外还需要把mapred.map.tasks设置大.

如果需要减少map,可以把mapred.min.split.size调大, 另外把mapred.map.tasks调小.

这里要特别指出的是FileInputFormat会让每个输入文件至少产生一个map任务, 因此如果你的输入目录下有许多文件, 而每个文件都很小, 例如几十kb, 那么每个文件都产生一个map会增加调度开销. 作业变慢.

那么如何防止这种问题呢? CombineFileInputFormat能有效的减少map数量.


FileInputFormat(新接口org.apache.hadoop.mapreduce.lib.input)

Hadoop 0.20开始定义了一套新的mapreduce编程接口, 使用新的FileInputFormat, 它与旧接口下的FileInputFormat主要区别在于, 它不再使用mapred.map.tasks, 而使用mapred.max.split.size参数代替goalSize, 通过Math.max(minSize, Math.min(maxSize, blockSize))决定map输入长度, 一个map的输入要大于minSize,小于

Math.min(maxSize, blockSize).

    若需增加map,可以把mapred.min.split.size调小,mapred.max.split.size调大. 若需减少map, 可以把mapred.min.split.size调大, 并把mapred.max.split.size调小.


CombineFileInputFormat

顾名思义, CombineFileInputFormat的作用是把许多文件合并作为一个map的输入.

在它之前,可以使用MultiFileInputFormat,不过其功能太简单, 以文件为单位,一个文件至多分给一个map处理, 如果某个目录下有许多小文件, 另外还有一个超大文件, 处理大文件的map会严重偏慢.

CombineFileInputFormat是一个被推荐使用的InputFormat. 它有三个配置:

mapred.min.split.size.per.node 一个节点上split的至少的大小

mapred.min.split.size.per.rack   一个交换机下split至少的大小

mapred.max.split.size             一个split最大的大小

它的主要思路是把输入目录下的大文件分成多个map的输入, 并合并小文件, 做为一个map的输入. 具体的原理是下述三步:

1.根据输入目录下的每个文件,如果其长度超过mapred.max.split.size,block为单位分成多个split(一个split是一个map的输入),每个split的长度都大于mapred.max.split.size, 因为以block为单位, 因此也会大于blockSize, 此文件剩下的长度如果大于mapred.min.split.size.per.node, 则生成一个split, 否则先暂时保留.

2. 现在剩下的都是一些长度效短的碎片,把每个rack下碎片合并, 只要长度超过mapred.max.split.size就合并成一个split, 最后如果剩下的碎片比mapred.min.split.size.per.rack, 就合并成一个split, 否则暂时保留.

3. 把不同rack下的碎片合并, 只要长度超过mapred.max.split.size就合并成一个split, 剩下的碎片无论长度, 合并成一个split.

举例: mapred.max.split.size=1000

     mapred.min.split.size.per.node=300

      mapred.min.split.size.per.rack=100

输入目录下五个文件,rack1下三个文件,长度为2050,1499,10, rack2下两个文件,长度为1010,80. 另外blockSize500.

经过第一步, 生成五个split: 1000,1000,1000,499,1000. 剩下的碎片为rack1:50,10; rack210:80

由于两个rack下的碎片和都不超过100, 所以经过第二步, split和碎片都没有变化.

第三步,合并四个碎片成一个split, 长度为150.

 

如果要减少map数量, 可以调大mapred.max.split.size, 否则调小即可.

其特点是: 一个块至多作为一个map的输入,一个文件可能有多个块,一个文件可能因为块多分给做为不同map的输入, 一个map可能处理多个块,可能处理多个文件。


编写自己的InputFormat

 

    待续


 

posted @ 2012-07-03 22:17 俞灵 阅读(16418) | 评论 (2)编辑 收藏

Yarn做为hadoop下一代集群资源管理和调度平台, 其上能支持多种计算框架, 本文就简要介绍一下这些计算框架.


1.       MapReduce

首先是大家熟悉的mapreduce, MR2之前, hadoop包括HDFSmapreduce, 做为hadoop上唯一的分布式计算框架, 其优点是用户可以很方便的编写分布式计算程序, 并支持许多的应用, hive, mahout, pig. 但是其缺点是无法充分利用集群资源, 不支持DAG, 迭代式计算等. 为了解决这些问题, yahoo提出了Yarn (next generation mapreduce), 一个分布式集群集群资源管理和调度平台. 这样除了mapreduce, 还可以支持各种计算框架.

2.       Spark

Spark是一种与mapreduce相似的开源计算框架, 不同之处在于Spark在某些工作负载方面表现更优, 因为它使用了内存分布式数据集, 另外除了提供交互式查询外, 它还可以优化迭代工作负载.

3.       Apache HAMA

Apache Hama 是一个运行在HDFS上的BSP(Bulk Synchronous Parallel大容量同步并行) 计算框架, 主要针对大规模科学计算,如矩阵, 图像, 网络算法等.当前它有一下功能:

  • 作业提交和管理接口
  • 单节点上运行多个任务
  • 输入/输出格式化
  • 备份恢复
  • 支持通过Apache Whirr运行在云端
  • 支持与Yarn一起运行

4.       Apache Giraph

图像处理平台上运行这大型算法(page rank, shared connections, personalization-based popularity )已经很流行, Giraph采用BSP模型(bulk-synchronous parallel model),可用于等迭代类算法。

5.       Open MPI

这是一个高性能计算函数库,通常在HPCHigh Performance Computing)中采用,与MapReduce相比,其性能更高,用户可控性更强,但编程复杂,容错性差,可以说,各有所长,在实际应用中,针对不同 该应用会采用MPI或者MapReduce

6.       Apache HBase

HBase是一个hadoop数据库, 其特点是分布式,可扩展的,存储大数据。当有需要随机,实时读写的大数据时, 使用HBase很适合.

本文参考:

http://wiki.apache.org/hadoop/PoweredByYarn
http://www.oschina.net/p/open+mpi

http://incubator.apache.org/hama/
http://incubator.apache.org/giraph/

http://hbase.apache.org/

posted @ 2012-06-03 11:43 俞灵 阅读(3589) | 评论 (0)编辑 收藏