MapReduce案例之多表关联

标签: mapreduce 关联 | 发表时间:2015-05-01 22:15 | 作者:seandeng888
出处:http://www.iteye.com

1       多表关联

1.1              多表关联

多表关联和单表关联类似,它也是通过对原始数据进行一定的处理,从其中挖掘出关心的信息。

1.2              应用场景

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

1.3              设计思路

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

1.4              程序代码

    程序代码如下所示:

  import java.io.IOException;

import java.util.*;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.fs.Path;

import org.apache.hadoop.io.IntWritable;

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("factoryname") ==  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]"

                 if (token.charAt(0) >= '0' && token.charAt(0) <= '9') {

                    mapkey = token;

                     if (i > 0) {

                        relationtype = "1";

                    }  else {

                        relationtype = "2";

                    }

                     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("factoryname"),  new Text("addressname"));

                 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.job.tracker", "192.168.1.2:9001");

        String[] ioArgs =  new String[] { "MTjoin_in", "MTjoin_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);

    }

}

 

 



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [mapreduce 关联] 推荐:

MapReduce案例之多表关联

- - 行业应用 - ITeye博客
1       多表关联. 1.1              多表关联. 多表关联和单表关联类似,它也是通过对原始数据进行一定的处理,从其中挖掘出关心的信息. 1.2              应用场景. 输入是两个文件,一个代表工厂表,包含工厂名列和地址编号列;另一个代表地址表,包含地址名列和地址编号列.

MapReduce案例之单表关联

- - 行业应用 - ITeye博客
1       单表关联. 1.1              单表关联. "单表关联"这个实例要求从给出的数据中寻找所关心的数据,它是对原始数据所包含信息的挖掘. 1.2              应用场景. 实例中给出child-parent(孩子——父母)表,要求输出grandchild-grandparent(孙子——爷奶)表.

Mapreduce小结

- MAGI-CASPER/Peter Pan - 博客园-唯有前进值得敬仰
读完mapreduce论文小结一下. 1.MapReduce是一个编程模型,封装了并行计算、容错、数据分布、负载均衡等细节问题. 输入是一个key-value对的集合,中间输出也是key-value对的集合,用户使用两个函数:Map和Reduce. Map函数接受一个输入的key-value对,然后产生一个中间key-value 对的集合.

Hadoop MapReduce技巧

- - 简单文本
我在使用Hadoop编写MapReduce程序时,遇到了一些问题,通过在Google上查询资料,并结合自己对Hadoop的理解,逐一解决了这些问题. Hadoop对MapReduce中Key与Value的类型是有要求的,简单说来,这些类型必须支持Hadoop的序列化. 为了提高序列化的性能,Hadoop还为Java中常见的基本类型提供了相应地支持序列化的类型,如IntWritable,LongWritable,并为String类型提供了Text类型.

MapReduce原理

- - C++博客-牵着老婆满街逛
       MapReduce 是由Google公司的Jeffrey Dean 和 Sanjay Ghemawat 开发的一个针对大规模群组中的海量数据处理的分布式编程模型. MapReduce实现了两个功能. Map把一个函数应用于集合中的所有成员,然后返回一个基于这个处理的结果集. 而Reduce是把从两个或更多个Map中,通过多个线程,进程或者独立系统并行执行处理的结果集进行分类和归纳.

MapReduce优化

- - 行业应用 - ITeye博客
相信每个程序员在 编程时都会问自己两个问题“我如何完成这个任务”,以及“怎么能让程序运行得更快”. 同样,MapReduce计算模型的多次优化也是为了更好地解答这两个问题. MapReduce计算模型的优化涉及了方方面面的内容,但是主要集中在两个方面:一是计算性能方面的优化;二是I/O操作方面的优化.

Spark与Mapreduce?

- - 崔永键的博客
我本人是类似Hive平台的系统工程师,我对MapReduce的熟悉程度是一般,它是我的底层框架. 我隔壁组在实验Spark,想将一部分计算迁移到Spark上. 年初的时候,看Spark的评价,几乎一致表示,Spark是小数据集上处理复杂迭代的交互系统,并不擅长大数据集,也没有稳定性. 但是最近的风评已经变化,尤其是14年10月他们完成了Peta sort的实验,这标志着Spark越来越接近替代Hadoop MapReduce了.

Google Percolator替代MapReduce

- Hao - Solidot
Google在新一代内容索引系统中放弃了MapReduce,替代者是尚不为人知的分布式数据处理系统Percolator. The Register报道,Percolator是一种增量处理平台,它能持续更新索引系统,无需从头重新处理一遍整个系统. Google的工程师计划在下个月举行的年度USENIX Symposium 会议上公布Percolator相关论文.

下一代Hadoop MapReduce

- Jia - NoSQLFan
本文来自Hadoop Summit大会的一个演讲稿,主讲是Hadoop核心开发团队的Arun C Murthy (@acmurthy),同时他也是Yahoo!刚刚剥离的Hadoop独立公司Hortonworks的 Founder和架构师. 演讲中他讲述了现在的Hadoop存在的一些问题和集群上限,并展望了下一代Hadoop和其MapReduce将会得到的巨大提升.

MapReduce执行流程

- - CSDN博客云计算推荐文章
MapReduce的大体流程是这样的,如图所示:. 由图片可以看到mapreduce执行下来主要包含这样几个步骤. 1.首先对输入数据源进行切片. 2.master调度worker执行map任务. 3.worker读取输入源片段. 4.worker执行map任务,将任务输出保存在本地. 5.master调度worker执行reduce任务,reduce worker读取map任务的输出文件.