文章目录
大多数初学者可能会面临这样一个问题,MapReduce的运行机制是怎样的呢,接下来我是我的理解,希望能够帮到大家
MapReduce大致可以分为六个步骤,分别是input, split, map, shuffle, reduce, output 举个例子来说明:
1.input(输入) — 给定一个文档,其中有这样几行数据
Hello World
Hello Java
Hello C
Hello BigData
Hello World
2.split(切片) — 将给定的文档按行切分成key-value键值对
0 - Hello World
1 - Hello Java
2 - Hello C
3 - Hello BigData
4 - Hello World
3.map(映射) — 将拆分之后的键值对转换成新的key-value键值对(这里用空格间隔,所以拆分的时候也用空格),
(Hello,1)
(World,1)
(Hello,1)
(Java,1)
(Hello,1)
(C,1)
(Hello,1)
(BigData,1)
(Hello,1)
(World,1)
4.shuffle(派发) — 将相同的key放到一起
(Hello,1)
(Hello,1)
(Hello,1)
(Hello,1)
(Hello,1)
(World,1)
(World,1)
(Java,1)
(C,1)
(BigData,1)
当这些键值对放到一起之后,会进行一个整合,将其整理成一个list类型的key-value键值对
{Hello:1,1,1,1,1}
{World:1,1}
{Java:1}
{C:1}
{BigData:1}
5.缩减(reduce) — 把相同key的value加到一起
(Hello,5)
(World,2)
(Java,1)
(C,1)
(BigData,1)
6.output(输出):输出结果
放图来理解就是这样的画面
通过自动分割输入数据成一个有M个split的集,map调用被分布到多台机器上.输入的split能够在不同的机器上被并行处理.通过用分割函数分割中间key,来形成R个片(例如,hash(key) mod R),reduce调用被分布到多台机器上.分割数量®和分割函数由用户来指定.
上图显示了我们实现的MapReduce操作的全部流程.当用户的程序调用MapReduce的函数的时候,将发生下面的一系列动作(下面的数字和图中的数字标签相对应):
1.在用户程序里的MapReduce库首先分割输入文件成M个片,每个片的大小一般从 16到64MB(用户可以通过可选的参数来控制).然后在机群中开始大量的拷贝程序.
2.这些程序拷贝中的一个是master,其他的都是由master分配任务的worker.有M 个map任务和R个reduce任务将被分配.管理者分配一个map任务或reduce任务给一个空闲的worker.
3.一个被分配了map任务的worker读取相关输入split的内容.它从输入数据中分析出key/value对,然后把key/value对传递给用户自定义的map函数.由map函数产生的中间key/value对被缓存在内存中.
4.缓存在内存中的key/value对被周期性的写入到本地磁盘上,通过分割函数把它们写入R个区域.在本地磁盘上的缓存对的位置被传送给master,master负责把这些位置传送给reduce worker.
5.当一个reduce worker得到master的位置通知的时候,它使用远程过程调用来从map worker的磁盘上读取缓存的数据.当reduce worker读取了所有的中间数据后,它通过排序使具有相同key的内容聚合在一起.因为许多不同的key映射到相同的reduce任务,所以排序是必须的.如果中间数据比内存还大,那么还需要一个外部排序.
6.reduce worker迭代排过序的中间数据,对于遇到的每一个唯一的中间key,它把key和相关的中间value集传递给用户自定义的reduce函数.reduce函数的输出被添加到这个reduce分割的最终的输出文件中.
7.当所有的map和reduce任务都完成了,管理者唤醒用户程序.在这个时候,在用户程序里的MapReduce调用返回到用户代码.
在成功完成之后,mapreduce执行的输出存放在R个输出文件中(每一个reduce任务产生一个由用户指定名字的文件).一般,用户不需要合并这R个输出文件成一个文件–他们经常把这些文件当作一个输入传递给其他的MapReduce调用,或者在可以处理多个分割文件的分布式应用中使用他们.
参考文章,谷歌三大论文-------MapReduce