大数据学习之十二——MapReduce代码实例:关联性操作

1.单表关联

"单表关联"要求从给出的数据中寻找所关心的数据,它是对原始数据所包含信息的挖掘。

实例描述
给出child-parent(孩子——父母)表,要求输出grandchild-grandparent(孙子——爷奶)表。

算法思想:

这个实例需要进行单表连接,连接的是左表的parent列和右表的child列,且左表和右表是同一个表。连接结果中除去连接的两列就是所需要的结果——"grandchild--grandparent"表。要用MapReduce解决这个实例,首先应该考虑如何实现表的自连接;其次就是连接列的设置;最后是结果的整理。MapReduce的shuffle过程会将相同的key会连接在一起,所以可以将map结果的key设置成待连接的列,然后列中相同的值就自然会连接在一起了。
1.map阶段将读入数据分割成child和parent之后,将parent设置成key,child设置成value进行输出,并作为左表;再将同一对child和parent中的child设置成key,parent设置成value进行输出,作为右表
2.为了区分输出中的左右表,需要在输出的value中再加上左右表的信息,比如在value的String最开始处加上字符1表示左表,加上字符2表示右表
3. reduce接收到连接的结果,其中每个key的value-list就包含了"grandchild--grandparent"关系。取出每个key的value-list进行解析,将左表中的child放入一个数组,右表中的parent放入一个数组,然后对两个数组求笛卡尔积就是最后的结果了

代码实例:

public class table01 {

static String INPUT_PATH="hdfs://master:9000/input/i.txt";

static String OUTPUT_PATH="hdfs://master:9000/output/singletable01";

static class MyMapper extends Mapper<Object,Object,Text,Text>{    //输入为字符串类型

Text output_key=new Text();

Text output_value=new Text();

protected void map(Object key, Object value, Context context) throws IOException, InterruptedException{

String[] tokens=value.toString().split(",");    //以,分割

if(tokens!=null && tokens.length==2){    //判断表分割成两列

output_key.set(tokens[0]);   //将child作为右表的key值,右表标记为2

output_value.set(2+","+value);

context.write(output_key, output_value);

output_key.set(tokens[1]);    //将parent列作为key值,作为左表,标记为1

output_value.set(1+","+value);

context.write(output_key, output_value);        //将一个表分割成了两个表

System.out.println(tokens[0]+"--"+tokens[1]);

}

}

}

static class MyReduce extends Reducer<Text,Text,Text,Text>{    //传入到MapReduce变成这样的格式:  lucy , {1,tom,lucy  2,lucy,mary}

Text output_key=new Text();

Text output_value=new Text();

protected void reduce(Text key,Iterable<Text> values,Context context) throws IOException,InterruptedException{

List<String> childs=new ArrayList();

List<String> grands=new ArrayList();

for(Text line:values){

String[] tokens=line.toString().split(",");

if(tokens[0].equals("1")){        //判断是左表的话,即parent作为key值的时候,将孩子加入队列中

childs.add(tokens[1]);

System.out.println(1+"--"+tokens[1]);

}

else if(tokens[0].equals("2")){      //右表,childs作为key值,将祖父母加入队列

grands.add(tokens[2]);

System.out.println(2+"--"+tokens[2]);

}

}

for(String c:childs){      //循环输出

for(String g:grands){

output_key.set(c);

output_value.set(g);

context.write(output_key, output_value);

}

}

}

}

public static void main(String[] args) throws Exception{

Path outputpath=new Path(OUTPUT_PATH);

Configuration conf=new Configuration();

Job job=Job.getInstance(conf);

FileInputFormat.setInputPaths(job, INPUT_PATH);

FileOutputFormat.setOutputPath(job,outputpath);

job.setMapperClass(MyMapper.class);

job.setReducerClass(MyReduce.class);

job.setOutputKeyClass(Text.class);

job.setOutputValueClass(Text.class);

job.waitForCompletion(true);

}

}

2.多表关联

实例描述
输入是两个文件,一个代表工厂表,包含工厂名列和地址编号列;另一个代表地址表,包含地址名列和地址编号列。要求从输入数据中找出工厂名和地址名的对应关系,输出"工厂名——地址名"表 。

算法思想:

多表关联和单表关联相似,都类似于数据库中的自然连接。相比单表关联,多表关联的左右表和连接列更加清楚。所以可以采用和单表关联的相同的处理方式,map识别出输入的行属于哪个表之后,对其进行分割,将连接的列值保存在key中,另一列和左右表标识保存在value中,然后输出。reduce拿到连接结果之后,解析value内容,根据标志将左右表内容分开存放,然后求笛卡尔积,最后直接输出。

public class table02 {

static String INPUT_PATH="hdfs://master:9000/doubletable";

static String OUTPUT_PATH="hdfs://master:9000/output/doubletable";

static class MyMapper extends Mapper<Object,Object,Text,Text>{

Text output_key=new Text();

Text output_value=new Text();

String tableName="";   //区分表名

protected void setup(Context context)throws java.io.IOException,java.lang.InterruptedException{

FileSplit fs=(FileSplit)context.getInputSplit();    //将多个表格区分开来

tableName=fs.getPath().getName();    //得到表名

System.out.println(tableName);

}

protected void map(Object key, Object value, Context context) throws IOException, InterruptedException{

String[] tokens=value.toString().split(",");

if(tokens!=null && tokens.length==2){

if(tableName.equals("l.txt")){     //如果是表一的话

output_key.set(tokens[1]);     //将addressID作为key值连接

output_value.set(1+","+tokens[0]+","+tokens[1]);    //1只是一个标记

}

else if(tableName.equals("m.txt")){     //如果是表二的话

output_key.set(tokens[0]);     //addressID是第一个属性

output_value.set(2+","+tokens[0]+","+tokens[1]);

}

context.write(output_key, output_value);

}

}

}

static class MyReduce extends Reducer<Text,Text,Text,Text>{

Text output_key=new Text();

Text output_value=new Text();

protected void reduce(Text key,Iterable<Text> value,Context context) throws IOException,InterruptedException{

List<String>  factorys=new ArrayList();

List<String> addrs=new ArrayList();

for(Text line:value){

String[] tokens=line.toString().split(",");

if(tokens[0].equals("1")){      //表一取出factory的值

factorys.add(tokens[1]);

}

else if(tokens[0].equals("2")){

addrs.add(tokens[2]);    //表二取出address的值

}

}

for(String c:factorys)       //循环输出

for(String g:addrs){

output_key.set(c);

output_value.set(g);

context.write(output_key,output_value);

}

}

}

public static void main(String[] args) throws Exception{

Path outputpath=new Path(OUTPUT_PATH);

Configuration conf=new Configuration();

FileSystem fs=outputpath.getFileSystem(conf);

if(fs.exists(outputpath)){

fs.delete(outputpath, true);

}

Job job=Job.getInstance(conf);

FileInputFormat.setInputPaths(job, INPUT_PATH);

FileOutputFormat.setOutputPath(job,outputpath);

job.setMapperClass(MyMapper.class);

job.setReducerClass(MyReduce.class);

job.setOutputKeyClass(Text.class);

job.setOutputValueClass(Text.class);

job.waitForCompletion(true);

}

}

原文地址:https://www.cnblogs.com/m-study/p/8379230.html

时间: 2024-10-07 20:43:24

大数据学习之十二——MapReduce代码实例:关联性操作的相关文章

大数据学习系列之二 ----- HBase环境搭建(单机)

引言 在上一篇中搭建了Hadoop的单机环境,这一篇则搭建HBase的单机环境 环境准备 1,服务器选择 阿里云服务器:入门型(按量付费) 操作系统:linux CentOS 6.8 Cpu:1核 内存:1G 硬盘:40G 2,配置选择 JDK:1.8 (jdk-8u144-linux-x64.tar.gz) Hadoop:2.8.2 (hadoop-2.8.2.tar.gz) HBase:1.6.2 (hbase-1.2.6-bin.tar.gz) 3,下载地址 官网地址: JDK: http

大数据学习之十五——sqoop的安装和使用

1.概念了解 sqoop主要用于hadoop与传统的数据库(mysql.postgresql...)间进行数据的传递,可以将一个关系型数据库(例如:MYSQL,Oracle,Postgrep等)中的数据导到hadoop的HDFS中,也可以将HDFS的数据导进到关系型数据库中. 2.sqoop的安装 (1)将压缩包sqoop-1.4.6.bin__hadoop-2.0.4-alpha.jar放在Linux的路径下,并修改配置文件/etc/profile export SQOOP_HOME=该压缩包

大数据学习系列之四 ----- Hadoop+Hive环境搭建图文详解(单机)

引言 在大数据学习系列之一 ----- Hadoop环境搭建(单机) 成功的搭建了Hadoop的环境,在大数据学习系列之二 ----- HBase环境搭建(单机)成功搭建了HBase的环境以及相关使用介绍.本文主要讲解如何搭建Hadoop+Hive的环境. 一.环境准备 1,服务器选择 本地虚拟机 操作系统:linux CentOS 7 Cpu:2核 内存:2G 硬盘:40G 说明:因为使用阿里云服务器每次都要重新配置,而且还要考虑网络传输问题,于是自己在本地便搭建了一个虚拟机,方便文件的传输以

大数据学习系列之五 ----- Hive整合HBase图文详解

引言 在上一篇 大数据学习系列之四 ----- Hadoop+Hive环境搭建图文详解(单机) 和之前的大数据学习系列之二 ----- HBase环境搭建(单机) 中成功搭建了Hive和HBase的环境,并进行了相应的测试.本文主要讲的是如何将Hive和HBase进行整合. Hive和HBase的通信意图 Hive与HBase整合的实现是利用两者本身对外的API接口互相通信来完成的,其具体工作交由Hive的lib目录中的hive-hbase-handler-*.jar工具类来实现,通信原理如下图

制定一份可实施的2018年大数据学习计划?

如何制定一份可实施的2018年大数据学习计划? 我们习惯了"间歇性踌躇满志.持续性混吃等死", 那么又该做点什么呢? 其实,要想做出改变并非难事,你缺少的只是一个计划(去做).学习大数据分析更是如此,因为大数据是一门综合性的学科,复杂且具有一定系统性,所以大数据的学习更加需要有一个明确的目标和计划,然后按部就班的执行. 那么如何才能制定出一份可行性强的大数据学习计划呢? 我们可以从以下几个方面去制定. 大数据学习交流群:716581014 如何制定一份可实施的2018年大数据学习计划?

好程序员大数据学习路线分享MAPREDUCE

好程序员大数据学习路线分享MAPREDUCE,需求:统计大量的文本文件中的单词出现的次数 1)整个运算需要分阶段 阶段一:并行局部运算 阶段二 :汇总处理,不同的阶段需要开发不同的程序 2)阶段之间的调用 3)业务程序(task程序)如何并发到集群并启动程序 4)如何监控task程序的运行状态,如何处理异常 ::这些问题是开发分布式程序都会面临的问题,完全可以封装成框架::MR 的结构 一个完整的MapReduce运行时有三类实例进程: 1)MRAppMaster : 负责整个程序的过程调度和状

大数据学习路线分享MapReduce全过程解析

大数据学习路线分享MapReduce全过程解析,移动数据与移动计算 在学习大数据的时候接触了移动数据和移动计算这两种联系紧密而又有很大不同的概念,其中移动计算也叫做本地计算. 在以前的数据处理中时使用的移动数据,其实就是将需要处理的数据传输到存放不同处理数据方式逻辑的各个节点上.这样做的效率很低,特别是大数据中的数据量是很大的,至少都是GB以上,更大的是TB.PB甚至更大,而且磁盘I/O.网络I/O的效率是很低的,这样处理起来就需要很长的时间,远远不能满足我们的要求.而移动计算就出现了. 移动计

大数据学习线路图

近期开始大数据的学习,在学习之前给给自己定义了一个大数据学习路线 大数据技术学习路线指南 一.Hadoop入门,了解什么是Hadoop 1.Hadoop产生背景2.Hadoop在大数据.云计算中的位置和关系3.国内外Hadoop应用案例介绍4.国内Hadoop的就业情况分析及课程大纲介绍5.分布式系统概述6.Hadoop生态圈以及各组成部分的简介7.Hadoop核心MapReduce例子说明二.分布式文件系统HDFS,是数据库管理员的基础课程1.分布式文件系统HDFS简介2.HDFS的系统组成介

大数据学习路线

偶遇大数据学习路线,赶上一次科技革命不容易,追求下,要有所作为! 一.Hadoop入门,了解什么是Hadoop 1.Hadoop产生背景2.Hadoop在大数据.云计算中的位置和关系3.国内外Hadoop应用案例介绍4.国内Hadoop的就业情况分析及课程大纲介绍5.分布式系统概述6.Hadoop生态圈以及各组成部分的简介7.Hadoop核心MapReduce例子说明 二.分布式文件系统HDFS,是数据库管理员的基础课程 1.分布式文件系统HDFS简介2.HDFS的系统组成介绍3.HDFS的组成