MapReduce功能实现十一---join
来源:互联网 发布:大数据时代的营销策略 编辑:程序博客网 时间:2024/06/08 08:45
MapReduce功能实现系列:
MapReduce功能实现一---Hbase和Hdfs之间数据相互转换
MapReduce功能实现二---排序
MapReduce功能实现三---Top N
MapReduce功能实现四---小综合(从hbase中读取数据统计并在hdfs中降序输出Top 3)
MapReduce功能实现五---去重(Distinct)、计数(Count)
MapReduce功能实现六---最大值(Max)、求和(Sum)、平均值(Avg)
MapReduce功能实现七---小综合(多个job串行处理计算平均值)
MapReduce功能实现八---分区(Partition)
MapReduce功能实现九---Pv、Uv
MapReduce功能实现十---倒排索引(Inverted Index)
MapReduce功能实现十一---join
前言:对两份数据data1和data2进行关键词连接是一个很通用的问题,在关系型数据库中Join是非常常见的操作,各种优化手段已经到了极致。在海量数据的环境下,不可避免的也会碰到这种类型的需求,例如在数据分析时需要从不同的数据源中获取数据。不同于传统的单机模式,在分布式存储下采用MapReduce编程模型,也有相应的处理措施和优化方法。
1.模拟数据:
[hadoop@h71 q1]$ vi mz.txt
zs 1
ls 2
ww 3
zl 2
qq 2
hh 1
[hadoop@h71 q1]$ vi jg.txt
1 beijing
2 tianjing
3 shanghai
2.将数据上传到hdfs上:
[hadoop@h71 q1]$ hadoop fs -mkdir /user/hadoop/m_in
[hadoop@h71 q1]$ hadoop fs -put mz.txt /user/hadoop/m_in
[hadoop@h71 q1]$ hadoop fs -put jg.txt /user/hadoop/m_in
3.[hadoop@h71 q1]$ vi MTjoin.java
import java.io.IOException;import java.util.Iterator;import java.util.StringTokenizer;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.Path;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.output.FileOutputFormat;import org.apache.hadoop.util.GenericOptionsParser; public class MTjoin { public static int time = 0; /* * 在map中先区分输入行属于左表还是右表,然后对两列值进行分割, * 保存连接列在key值,剩余列和左右表标志在value中,最后输出 */ public static class Map extends Mapper<Object, Text, Text, Text> { // 实现map函数 public void map(Object key, Text value, Context context) throws IOException, InterruptedException { String line = value.toString();// 每行文件 String relationtype = new String();// 左右表标识 // 输入文件首行,不处理 if (line.contains("name") == true || line.contains("addressed") == true) { return; } // 输入的一行预处理文本 StringTokenizer itr = new StringTokenizer(line); String mapkey = new String(); String mapvalue = new String(); int i = 0; while (itr.hasMoreTokens()) { // 先读取一个单词 String token = itr.nextToken(); // 判断该地址ID就把存到"values[0]" //charAt() 方法可返回指定位置的字符 if (token.charAt(0) >= '0' && token.charAt(0) <= '9') { mapkey = token; if (i > 0) { relationtype = "1"; } else { relationtype = "2"; } //break的作用是跳出当前循环块,continue用于结束循环体中其后语句的执行 continue; } // 存工厂名 mapvalue += token + " "; i++; } // 输出左右表 context.write(new Text(mapkey), new Text(relationtype + "+"+ mapvalue)); } } /* * reduce解析map输出,将value中数据按照左右表分别保存, * 然后求出笛卡尔积,并输出。 */ public static class Reduce extends Reducer<Text, Text, Text, Text> { // 实现reduce函数 public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException { // 输出表头 if (0 == time) { context.write(new Text("name"), new Text("address")); time++; } int factorynum = 0; String[] factory = new String[10]; int addressnum = 0; String[] address = new String[10]; Iterator ite = values.iterator(); while (ite.hasNext()) { String record = ite.next().toString(); int len = record.length(); int i = 2; if (0 == len) { continue; } // 取得左右表标识 char relationtype = record.charAt(0); // 左表 if ('1' == relationtype) { factory[factorynum] = record.substring(i); factorynum++; } // 右表 if ('2' == relationtype) { address[addressnum] = record.substring(i); addressnum++; } } // 求笛卡尔积 if (0 != factorynum && 0 != addressnum) { for (int m = 0; m < factorynum; m++) { for (int n = 0; n < addressnum; n++) { // 输出结果 context.write(new Text(factory[m]), new Text(address[n])); } } } } } public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); // 这句话很关键 conf.set("mapred.jar", "mt.jar"); String[] ioArgs = new String[] { "m_in", "m_out" }; String[] otherArgs = new GenericOptionsParser(conf, ioArgs).getRemainingArgs(); if (otherArgs.length != 2) { System.err.println("Usage: Multiple Table Join <in> <out>"); System.exit(2); } Job job = new Job(conf, "Multiple Table Join"); job.setJarByClass(MTjoin.class); // 设置Map和Reduce处理类 job.setMapperClass(Map.class); job.setReducerClass(Reduce.class); // 设置输出类型 job.setOutputKeyClass(Text.class); job.setOutputValueClass(Text.class); // 设置输入和输出目录 FileInputFormat.addInputPath(job, new Path(otherArgs[0])); FileOutputFormat.setOutputPath(job, new Path(otherArgs[1])); System.exit(job.waitForCompletion(true) ? 0 : 1); }}
4.执行:
[hadoop@h71 q1]$ /usr/jdk1.7.0_25/bin/javac MTjoin.java
[hadoop@h71 q1]$ /usr/jdk1.7.0_25/bin/jar cvf xx.jar MTjoin*class
[hadoop@h71 q1]$ hadoop jar xx.jar MTjoin
5.查看结果:
[hadoop@h71 q1]$ hadoop fs -cat /user/hadoop/m_out/part-r-00000
name address
hh beijing
zs beijing
qq tianjing
zl tianjing
ls tianjing
ww shanghai
- MapReduce功能实现十一---join
- MapReduce Join联结实现
- MapReduce之Join实现
- MapReduce实现join操作
- MapReduce Join联结实现
- MapReduce Join联结实现
- MapReduce实现join操作
- MapReduce实现join操作
- MapReduce实现join操作
- MapReduce实现join操作
- MapReduce实现join操作
- MapReduce实现join操作
- MapReduce实现join
- MapReduce实现join操作
- MapReduce 实现 join
- MapReduce之join实现方案
- MapReduce实现hive join操作
- <转>MapReduce实现的Join
- 讲真
- 关于“缺省”这个词
- RabbitMQ、ActiveMQ、ZeroMQ、Kafka之间的比较汇总
- Linux操作
- Gdevops 2017全球敏捷运维峰会即将登陆北京!
- MapReduce功能实现十一---join
- jsonp跨域请求可能遇到的问题
- hdu5909 Tree Cutting
- ibatis批量插入返回插入结果
- C# 实现完整功能的截图控件(1)-实现绘图工具栏控件 控件实现了截图、绘制矩形、圆形、箭头、线条、文字,还需要可以撤销绘制步骤、保存图形等功能,基本实现了跟QQ2008截图一样的功能,还可以更
- 1185 威佐夫游戏 V2(浮点数精度问题)
- oracle 表空间(数据文件)满了后 修改表空间大小
- 线程池
- ZZULIOJ【1095】时间间隔【数学】&&【函数】