在MapReduce框架下编写程序最重要的是理解从map到reducer数据是如何组织的,其中最核心的就是map到reducer的shuffle过程:“每个reducer接到的数据都是按key值排序后的,并且key值相同的记录会被分配到同一个reducer里面”,这一过程是框架自动完成,许多实例需要用到这一特性
一、实现方式
1.jar包
在框架下利用java可以进行map和reducer端的编写,然后使用一个main类来进行运行,
这里reducer只有一个
只有一个reducer,所有记录都排好序,信息集中,方便处理,会使得reducer数据很大,处理时间慢
2.hadoop流
利用脚本来编写hadoop的map和reducer端,脚本的输出和输入都是来自标准输入和标准输出,
这里reducer可以有多个,这里不需要主类配置参数,而是通过命令行配置参数
由于有多个reducer,每个reducer中的统计的信息分散的,所以对于计算全局信息,最后需要一个computer端(单机)来整合信息
二、编程思维
根据shuffle过程的特性,即所有数据已经排好序,所有的相同key值记录的数据也在同一个reducer里面,这样就可以方便解决很多问题,下面是典型问题
1.top100问题
思路:在reducer端算出top100,然后在computer端再计算一次top100(如果只有一个top)
细节:在reducer端计算top100时候,数据量比较大,不能把所有数据都放入内存然后排序,可以只保留100条记录的空间,利用行缓冲进行数据读取,进行堆排序
2.带权random问题(取出个数不定)
思路:在map端给每条记录分配一个随机数,然后利用shuffle机制对这些随机数排序,这就等同于把原始记录打乱了,在reducer端去取指定个数的记录
3.去重
思路:一般的思路是把所有数据放在一个map里面,这样容易爆内存,所以只有在map端按照要去重的元素排好序,然后在reducer端利用行缓冲,记录读取相邻的两个记录,如果相邻的记录不一样,说明读到了一个新记录,然后把这个数据存下来