注:本文涉及书中2.4~2.6小结
横向扩展(scaling out)
横向扩展,即将数据存储在分布式文件系统中,一般为HDFS,由此允许Hadoop将MapReduce计算转移到存储有部分数据的各台机器上。
几个术语
1. 一个作业(job)与多个任务(task)
MapReduce作业(job)是客户端需要执行的一个工作单元,具体包括:输入数据、MapReduce程度和配置信息。
Hadoop将job分成若干个任务(task)来执行,其中包括两类任务:map任务和reduce任务。
2. 一个节点jobtracker与多个节点tasktracker
有两类节点控制着作业执行过程:一个jobtracker和一系列tasktracker。
嗯,就是与上述的job与task想对应,用来控制执行。
3. 输入分片(input split)
Hadoop将MapReduce的输入数据划分成等长的小数据块,就是输入分片(input split)或简称为“分片”。Hadoop为每个分片构建一个map任务。
分片的大小会影响Hadoop的负载均衡和执行时间,一般认为,合理的分片大小趋向于HDFS的一个块的大小。
Hadoop在存储有输入数据(HDFS中的数据)的节点上运行map任务,可以获得最佳性能,这就是所谓的“数据本地化优化”(data locality optimization),因为它无需使用宝贵的集群带宽资源。如图,展示了3种HDFS数据块运行map任务的情况.
(以下是我的个人理解)第一种情况:HDFS与map任务都在同一节点上,即“数据本地化优化”。第二种情况:HDFS与map任务不在同一节点上,但是仍都属于同一个服务器。第三种情况:HDFS与map任务不在同一节点上,且不属于同一个服务器,也就是说,HDFS上的数据需要跨服务器运行map任务,此时的效率最低。map任务将其输出写入本地硬盘,而非HDFS,因为map的输出只是中间结果,该中间结果需要reduce任务处理后才能产生最终的输出结果。
reduce任务可以有一个,也可以有多个,也可以没有reduce任务。
一个reduce任务的情况:
reduce任务不具备数据本地化的优势,单个reduce任务的输入通常来自所有map的输出。reduce的输出通过存储在HDFS块,第一个复本存储在本地节点上,其他复本存储在其他机架节点上。
多个reduce任务的情况:
当有多个reduce任务时,每个map任务会针对输出进行分区(partition),即为每个reduce任务建一个分区。如下图,此时将map任务与reduce任务之间的数据流成为shuffle(混洗)。分区由用户定义的partition函数控制,但通常用默认的partitioner通过hash函数来区分。
无reduce任务的情况:
此时map任务将结果直接写入HDFS
combiner函数
Hadoop允许用户针对map任务的输出知道一个combiner,combiner函数的输出作为reduce函数的输入。
然而,不是任何时候都可以用combiner的,具体的例子可以看书的2.4.2小结中最高气温和平均气温的实例。由此,虽然combiner能够有效减少mapper和reducer之间的数据传输量,但是在MapReduce作业中使用combiner函数需要慎重考虑。
Hadoop Streaming
Hadoop提供了MapReduce的API,使得我们可以使用非Java的其他语言来写自己的map和reduce函数,如Ruby和Python。
注:其他编程语言要通过标准输入/输出来写MapReduce程度。
Hadoop Pipes
Hadoop Pipes是Hadoop MapReduce的C++接口名称,使用套接字作为tasktracker与C++版本map或reduce函数的进程直接的通道。
网友评论