引言
- MapReduce设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的代码设计经验总结;
- 使用设计模式的目的:使用设计模式是为了提高编码效率、提高代码重用率、让代码更容易被他人理解、保证代码可靠性;
- 设计模式千万种,本文为您梳理出来最重要、最常用的几种设计模式,方便理解和掌握;
- 本文的每一种设计模式都搭配了实例程序,以及输入和输出,让您更好更快地理解;
计数(Counting)一
- 问题定义:在数据文件中包含大量的记录,每条记录中包含了某个实体的若干数值属性,目标问题是要计算每个实体的某个数值属性的函数表达式值,例如求和、平均值等;
- 具体问题描述:现在有一个英文文件,需要统计其中每个单词的个数(wordcount);
- 解决方案:在map中分离每个单词,传入reduce,在reduce中将每个单词的value相加;
- 程序:
1 | package wordcountTest; |
- 示例输入输出:
1 | 输入:一篇英文文章,单词之间用空格分割 |
计数(Counting)二
- 具体问题描述:输入文件为两列,分别为用户手机号和流量数,现需要统计每个用户的总流量数;
- 解决方案:map中将每个用户的手机号、流量分别作为key和value传入reduce,由reduce来统计总流量数;
- 程序:
1 | package wordcountTest; |
- 示例输入输出:
1 | 输入:用户手机号和流量,用空格分割 |
分类(classfication)
- 问题定义:在数据文件中包含大量的记录,每条记录中包含了某个实体的若干属性,目标问题是在给定一个计算函数的情况下,将此计算函数计算后得到的结果相同的实体放在一起;
- 具体问题描述:输入数据为两列,分别是手机号和其访问的网址,目的是统计同一个网址有哪些手机号访问过;
- 解决方案:map阶段把网址、手机号分别作为key、value传入reduce,由reduce实现分类;
- 程序:
1 | package wordcountTest; |
- 示例输入输出:
1 | 输入:手机号和网址,用空格分割 |
- 说明:本程序并不能实现将每一个网址放入单独的文件输出,这是因为在“shuffle”过程中,计算出的partitionID相同的key被分到一个reduce中,然而,不同的key的partitionID可能相同,即同一个key肯定被分到同一个reduce,但是同一个reduce中可能有不同的key,所以上述算法不能实现完全分类。关于shuffle请参考我的另一篇博客Mapreduce过程详解
过滤(filtering)
- 问题定义:在数据文件中包含大量的记录,每条记录中包含了某个实体的若干属性,目标问题是在将符合某个条件的记录取出(或进行格式转换);
- 具体问题描述:输入文件为三列:手机号、属性、访问网站,目标是将属性为0的记录过滤掉;
- 解决方案:map中将前两列作为key,最后一列为value,判断属性后输出过滤结果即可,不需要reduce过程;
- 程序:
1 | package wordcountTest; |
- 示例输入输出
1 | 输入:手机号、属性、网站 |
排序(Sorting)
- 问题定义:在数据文件中包含大量的记录,每条记录中包含了某个实体的若干属性,目标问题是在将记录按照一定规则排序后输出;
- 具体问题描述:输入为三列,手机号、上行流量、下行流量,要求计算每个手机号的总流量并按照从小到大的顺序输出;
- 解决方案:在map中将上下行流量相加,得出总流量,以<手机号,总流量>形式输出;reduce中将每个手机号按照总流量从小到大的顺序排序后输出;
- 程序:
1 | package wordcountTest; |
- 示例输入输出:
1 | 输入:手机号、上行流量、下行流量,以空格分割 |
去重计数(Distinct Counting)
- 问题定义:在数据文件中包含大量的记录,每条记录中包含了某个实体的若干属性,目标问题是在计算某几个属性组合后去掉相同重复组合后,其中某一属性的统计值;
- 具体问题的描述:输入为两列,手机号、访问网址,要求统计每个网址都有几种手机号访问;
- 解决方案:map中将网址作为key、手机号作为value,发送给reduce;计数、去重的工作都由reduce完成;去重的工作由HashSet完成;
- 程序:
1 | package wordcount_test; |
- 示例输入输出:
1 | 输入:手机号、访问网址,用空格分割 |
相关计数(Cross-Correlation)
- 问题定义:输入若干数组,每个数组是由若干实体构成,目标问题是计算数组中实体以一定条件要求成对出现的次数或概率;
- 具体问题描述:输入数据是2列,手机号、访问网址,现在需要统计每个手机号访问每个网址的次数;
- 解决方案:Stripes方法–map中将手机号作为key、访问网址和计数值1作为value,reduce中进行统计;Pairs方法–map中将手机号和访问网址作为key、计数值1作为value,reduce中进行统计;
- 程序:
1 | Stripes方法: |
1 | pairs方法: |
- 示例输入输出:
1 | 输入:手机号、网址,中间用空格分割 |