十二道MR习题 - 3 - 交集并集差集
题目
有两个文件A和B,两个文件中都有几百万行数字,现在需要找出A文件和B文件中数字集合的交集、并集、以及A对B的差集。
简单说一下思路:
这个问题关键在于key和value的设计。这里我将文件中的数字设置为key,将文件名称设置为value。这样在reduce阶段很容易就能找出A、B两个文件中数字的交并差集了。
并集就是reduce阶段能输出的全部记录;交集则需要做下过滤,即一个记录中的value需要同时有A、B两个文件的名称;差集则是文件名称集合中只包含A或B的记录。
看下用MapReduce是如何实现的:
package com.zhyea.dev; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import java.io.IOException;
import java.util.Iterator; public class ContentCompare { public static class SplitterMapper extends Mapper<Object, Text, Text, Text> { private Text text = new Text(); @Override
public void map(Object key, Text value, Context context) {
try {
String fileName = ((FileSplit) context.getInputSplit()).getPath().getName();
text.set(fileName);
context.write(value, text);
} catch (Exception e) {
e.printStackTrace();
}
}
} public static class UnionReducer extends Reducer<Text, Text, Text, NullWritable> {
@Override
public void reduce(Text key, Iterable<Text> values, Context context) {
try {
context.write(key, NullWritable.get());
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public static class InterReducer extends Reducer<Text, Text, Text, NullWritable> {
@Override
public void reduce(Text key, Iterable<Text> values, Context context) {
try {
Iterator<Text> itr = values.iterator();
boolean flagA = false;
boolean flagB = false;
while (itr.hasNext()) {
String s = itr.next().toString();
if (s.equals("B")) {
flagB = true;
}
if (s.equals("A")) {
flagA = true;
}
}
if (flagA && flagB) {
context.write(key, NullWritable.get());
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public static class DiffAReducer extends Reducer<Text, Text, Text, NullWritable> {
@Override
public void reduce(Text key, Iterable<Text> values, Context context) {
try {
Iterator<Text> itr = values.iterator();
boolean flagA = false;
boolean flagB = false;
while (itr.hasNext()) {
String s = itr.next().toString();
if (s.equals("A")) {
flagA = true;
}
if (s.equals("B")) {
flagB = true;
}
}
if (flagA && !flagB) {
context.write(key, NullWritable.get());
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException { Configuration conf = new Configuration(); Job job = Job.getInstance(conf, "content-compare");
job.setJarByClass(ContentCompare.class); job.setMapperClass(SplitterMapper.class);
job.setReducerClass(DiffAReducer.class); job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class); job.setOutputKeyClass(Text.class);
job.setOutputValueClass(NullWritable.class); job.setNumReduceTasks(1); FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1])); System.exit(job.waitForCompletion(true) ? 0 : 1);
} }
用spark实现就简单的多了,这里我们很大程度上是受益于scala语法的简洁性:
package com.talkingdata.campaign
import org.apache.hadoop.io.{LongWritable, Text}
import org.apache.hadoop.mapred.{FileSplit, InputSplit, TextInputFormat}
import org.apache.spark.rdd.HadoopRDD
import org.apache.spark.{SparkConf, SparkContext}
object ContentCompare {
def main(args: Array[String]): Unit = {
val inputPath = args(0)
val outputPath = args(1)
val conf = new SparkConf().setAppName("content compare")
val sc = new SparkContext(conf)
val data = sc.hadoopFile[LongWritable, Text, TextInputFormat](inputPath)
val hadoopRDD = data.asInstanceOf[HadoopRDD[LongWritable, Text]]
hadoopRDD.mapPartitionsWithInputSplit[(String, String)](readFile)
.reduceByKey(_ + _)
.filter(p => p._2.length == 2)
.map(p => p._1)
.repartition(1)
.saveAsTextFile(outputPath)
def readFile(inputSplit: InputSplit, itr: Iterator[(LongWritable, Text)]) = {
val fileName = inputSplit.asInstanceOf[FileSplit].getPath.getName
itr.map(p => (p._2.toString, fileName))
}
}
}
上面的代码中列出了计算交集的方法。并集实在是没什么好说的,读取文件后,reduce或distinct一下就能实现了。
要计算差集的话只需要调整下filter中的函数值就可以了:
hadoopRDD.mapPartitionsWithInputSplit[(String, String)](readFile)
.reduceByKey(_ + _)
.filter(p => p._2.length == 1 && p._2 == "A")
.map(p => p._1)
.repartition(1)
.saveAsTextFile(outputPath)
#############
十二道MR习题 - 3 - 交集并集差集的更多相关文章
- 十二道MR习题 - 2 - 多文件保存
题目: 需要将MR的执行结果保存到3个文件中,该怎么做. 又是一个送分题. 对于Hadoop的MapReduce来说只需要设置一下reduce任务的数量即可.MR的Job默认reduce数量是1,需要 ...
- 十二道MR习题 - 4 - TopN问题
题目: 有一个很大的文件,这文件中的内容全部都是数字,要求尝试从这个文件中找出最大的10个数字. 分析: 看起来像是一个比较简单的问题.不用大数据框架的话,也能比较轻易的实现:就是逐个读取文件中的每个 ...
- 十二道MR习题 – 1 – 排序
题目: 一个文件,大小约为100G.文件的每一行都是一个数字,要求对文件中的所有数字进行排序. 对于这个题目,了解过Hadoop的同学可以笑而不语了.即使用spark实现也是非常简单的事情. 先说下如 ...
- (java/javascript) list 交集 并集 差集 去重复并集
java list 交集 并集 差集 去重复并集 package com; import java.util.ArrayList; import java.util.Iterator; import ...
- Python 求两个文本文件以行为单位的交集 并集 差集
Python 求两个文本文件以行为单位的交集 并集 差集,来代码: s1 = set(open('a.txt','r').readlines()) s2 = set(open('b.txt','r') ...
- 如何求ArrayList集合的交集 并集 差集 去重复并集
需要用到List接口中定义的几个方法: addAll(Collection<? extends E> c) :按指定集合的Iterator返回的顺序将指定集合中的所有元素追加到此列表的末尾 ...
- spark之交集并集差集拉链
spark之交集并集差集拉链 def main(args: Array[String]): Unit = { val sparkConf = new SparkConf().setMaster(&qu ...
- java 两个list 交集 并集 差集 去重复并集
前提需要明白List是引用类型,引用类型采用引用传递. 我们经常会遇到一些需求求集合的交集.差集.并集.例如下面两个集合: List<String> list1 = new ArrayLi ...
- java list 交集 并集 差集 去重复并集
package com; import java.util.ArrayList;import java.util.Iterator;import java.util.List; public clas ...
随机推荐
- 160706、Java HashMap工作原理及实现
1. 概述 从本文你可以学习到: 什么时候会使用HashMap?他有什么特点? 你知道HashMap的工作原理吗? 你知道get和put的原理吗?equals()和hashCode()的都有什么作用? ...
- Html5-Canvas 与 SVG 的比较
Canvas 与 SVG 的比较 Canvas 依赖分辨率 不支持事件处理器 弱的文本渲染能力 能够以 .png 或 .jpg 格式保存结果图像 最适合图像密集型的游戏,其中的许多对象会被频繁重绘 S ...
- SharePoint服务器端对象模型 完结
整个系列已完结,大概看了一眼,平均阅读量不到200.估计也没什么人看了,而且服务器端对象模型除了在某些企业开发中会用到,从2013时代开始其实已经不是SharePoint开发的最佳选择了.不过既然已经 ...
- mongodb3.0+ 版本内置数据压缩
mongodb3+版本之后支持zlib和snappy. 创建压缩的集合 db.createCollection( "email", {storageEngine:{wiredTig ...
- 剩余参数(rest arguments) Mixin
Mixin – Pug 中文文档 https://pug.bootcss.com/language/mixins.html 混入 Mixin 混入是一种允许您在 Pug 中重复使用一整个代码块的方法. ...
- 【opencv安裝】ubuntu16 opencv安装+测试
ubuntu16.04 install opencv2.4 to python2 and c++ 四大主流库比较: 对OpenCV的印象:功能十分的强大,而且支持目前先进的图像处理技术,体系十分完善, ...
- Python 模块之 pyexcel_xls
一.适用场景 在很多数据统计或者数据分析的场景中,我们都会使用到excel: 在一些系统中我们也会使用excel作为数据导入和导出的方式,那么如何使用python加以辅助我们快速进行excel数据做更 ...
- dedecms中的内容页中的变量
{dede:php runphp='yes'} var_dump($refObj->Fields); {/dede:php}
- linux环境配置时钟同步ntpd服务
配置: 服务器1:192.168.169.139 服务器2:192.168.169.140 服务器3:192.168.169.141 目的:NTP能与互联网的时间保持同步,而且本身也是一台NTP服务器 ...
- CRM——插件流程回顾
1. Django项目启动 自动加载文件 制作启动文件 1. 注册strak 在apps.py 类里面增加如下 def ready(self): from django.utils.module_lo ...