1.序列化与Writable接口

1.1.hadoop的序列化格式

  序列化和反序列化就是结构化对象和字节流之间的转换,主要用在内部进程的通讯和持久化存储方面

  hadoop在节点间的内部通讯使用的是RPC,RPC协议把消息翻译成二进制字节流发送到远程节点,远程节点再通过反序
列化把二进制流转成原始的信息  

  hadoop自身的序列化存储格式实现了Writable接口的类,他只实现了前面压缩和快速。但是不容易扩展也不跨语言
  我们先来看下Writable接口,Writable接口定义了两个方法:
  1.将数据写入到二进制流中
  2.从二进制数据流中读取数据
  

2.reduce端join算法实现

1.需求:

 

 假如数据量巨大,两表的数据是以文件的形式存储在HDFS中,需要用mapreduce程序来实现以下SQL查询运算:

   select  a.id,a.date,b.name,b.category_id,b.price from t_order a join t_product b on a.pid = b.id

2.实现机制:

  通过将关联的条件pid作为map输出的key,将两表满足join条件的数据并携带数据所来源的文件信息,发往同

一个reducetask,在reduce中进行数据的串联

3.代码实现:

package cn.bigdata.mr.rjoin;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.Writable; public class InfoBean implements Writable { private int order_id;
private String dateString;
private String p_id;
private int amount;
private String pname;
private int category_id;
private float price; // flag=0表示这个对象是封装订单表记录
// flag=1表示这个对象是封装产品信息记录
private String flag; public InfoBean() {
} public void set(int order_id, String dateString, String p_id, int amount, String pname, int category_id, float price, String flag) {
this.order_id = order_id;
this.dateString = dateString;
this.p_id = p_id;
this.amount = amount;
this.pname = pname;
this.category_id = category_id;
this.price = price;
this.flag = flag;
} public int getOrder_id() {
return order_id;
} public void setOrder_id(int order_id) {
this.order_id = order_id;
} public String getDateString() {
return dateString;
} public void setDateString(String dateString) {
this.dateString = dateString;
} public String getP_id() {
return p_id;
} public void setP_id(String p_id) {
this.p_id = p_id;
} public int getAmount() {
return amount;
} public void setAmount(int amount) {
this.amount = amount;
} public String getPname() {
return pname;
} public void setPname(String pname) {
this.pname = pname;
} public int getCategory_id() {
return category_id;
} public void setCategory_id(int category_id) {
this.category_id = category_id;
} public float getPrice() {
return price;
} public void setPrice(float price) {
this.price = price;
} public String getFlag() {
return flag;
} public void setFlag(String flag) {
this.flag = flag;
} /**
* private int order_id; private String dateString; private int p_id;
* private int amount; private String pname; private int category_id;
* private float price;
*/
@Override
public void write(DataOutput out) throws IOException {
out.writeInt(order_id);
out.writeUTF(dateString);
out.writeUTF(p_id);
out.writeInt(amount);
out.writeUTF(pname);
out.writeInt(category_id);
out.writeFloat(price);
out.writeUTF(flag);
} @Override
public void readFields(DataInput in) throws IOException {
this.order_id = in.readInt();
this.dateString = in.readUTF();
this.p_id = in.readUTF();
this.amount = in.readInt();
this.pname = in.readUTF();
this.category_id = in.readInt();
this.price = in.readFloat();
this.flag = in.readUTF(); } @Override
public String toString() {
return "order_id=" + order_id + ", dateString=" + dateString + ", p_id=" + p_id + ", amount=" + amount + ", pname=" + pname + ", category_id=" + category_id + ", price=" + price ;
}
}
package cn.bigdata.mr.rjoin;
import java.io.IOException;
import java.util.ArrayList;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
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; /**
* 订单表和商品表合到一起
order.txt(订单id, 日期, 商品编号, 数量)
1001 20150710 P0001 2
1002 20150710 P0001 3
1002 20150710 P0002 3
1003 20150710 P0003 3
product.txt(商品编号, 商品名字, 价格, 数量)
P0001 小米5 1001 2
P0002 锤子T1 1000 3
P0003 锤子 1002 4
*/
public class RJoin { static class RJoinMapper extends Mapper<LongWritable, Text, Text, InfoBean> {
InfoBean bean = new InfoBean();
Text k = new Text(); @Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString(); FileSplit inputSplit = (FileSplit) context.getInputSplit();
String name = inputSplit.getPath().getName();
System.out.println("kkkkkkkkkkkkkkkkkkkkkk"+name);
// 通过文件名判断是哪种数据
String pid = "";
if (name.startsWith("order")) {
String[] fields = line.split(",");
// id date pid amount
pid = fields[];
bean.set(Integer.parseInt(fields[]), fields[], pid, Integer.parseInt(fields[]), "", , , ""); } else {
String[] fields = line.split(",");
// id pname category_id price
pid = fields[];
bean.set(, "", pid, , fields[], Integer.parseInt(fields[]), Float.parseFloat(fields[]), ""); }
k.set(pid);
context.write(k, bean);
}
} static class RJoinReducer extends Reducer<Text, InfoBean, InfoBean, NullWritable> { @Override
protected void reduce(Text pid, Iterable<InfoBean> beans, Context context) throws IOException, InterruptedException {
InfoBean pdBean = new InfoBean();
ArrayList<InfoBean> orderBeans = new ArrayList<InfoBean>(); for (InfoBean bean : beans) {
if ("".equals(bean.getFlag())) { //产品的
try {
BeanUtils.copyProperties(pdBean, bean);
} catch (Exception e) {
e.printStackTrace();
}
} else {
InfoBean odbean = new InfoBean();
try {
BeanUtils.copyProperties(odbean, bean);
orderBeans.add(odbean);
} catch (Exception e) {
e.printStackTrace();
}
}
} // 拼接两类数据形成最终结果
for (InfoBean bean : orderBeans) { bean.setPname(pdBean.getPname());
bean.setCategory_id(pdBean.getCategory_id());
bean.setPrice(pdBean.getPrice()); context.write(bean, NullWritable.get());
}
}
} public static void main(String[] args) throws Exception {
Configuration conf = new Configuration(); conf.set("mapred.textoutputformat.separator", ","); Job job = Job.getInstance(conf); // 指定本程序的jar包所在的本地路径
// job.setJarByClass(RJoin.class);
// job.setJar("c:/join.jar"); job.setJarByClass(RJoin.class);
// 指定本业务job要使用的mapper/Reducer业务类
job.setMapperClass(RJoinMapper.class);
job.setReducerClass(RJoinReducer.class); // 指定mapper输出数据的kv类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(InfoBean.class); // 指定最终输出的数据的kv类型
job.setOutputKeyClass(InfoBean.class);
job.setOutputValueClass(NullWritable.class); // 指定job的输入原始文件所在目录
FileInputFormat.setInputPaths(job, new Path(args[]));
// 指定job的输出结果所在目录
FileOutputFormat.setOutputPath(job, new Path(args[])); // 将job中配置的相关参数,以及job所用的java类所在的jar包,提交给yarn去运行
/* job.submit(); */
boolean res = job.waitForCompletion(true);
System.exit(res ? : );
}
}

运行结果:

order_id=1002, dateString=20150710, p_id=P0001, amount=3, pname=sss, category_id=1001, price=2.0
order_id=1001, dateString=20150710, p_id=P0001, amount=2, pname=sss, category_id=1001, price=2.0
order_id=1002, dateString=20150710, p_id=P0002, amount=3, pname=111, category_id=1000, price=3.0
order_id=1003, dateString=20150710, p_id=P0003, amount=3, pname=www, category_id=1002, price=4.0

  

Hadoop_21_MapReduce程序实现Join功能的更多相关文章

  1. 为ASP.NET MVC应用程序使用高级功能

    为ASP.NET MVC应用程序使用高级功能 这是微软官方教程Getting Started with Entity Framework 6 Code First using MVC 5 系列的翻译, ...

  2. 微信小程序开发-蓝牙功能开发

    0. 前言 这两天刚好了解了一下微信小程序的蓝牙功能.主要用于配网功能.发现微信的小程序蓝牙API已经封装的很好了.编程起来很方便.什么蓝牙知识都不懂的情况下,不到两天就晚上数据的收发了,剩下的就是数 ...

  3. MySQL 的 join 功能弱爆了?

    大家好,我是历小冰,今天我们来学习和吐槽一下 MySQL 的 Join 功能. 关于MySQL 的 join,大家一定了解过很多它的"轶事趣闻",比如两表 join 要小表驱动大表 ...

  4. Java基础-输入输出-3.编写BinIoDemo.java的Java应用程序,程序完成的功能是:完成1.doc文件的复制,复制以后的文件的名称为自己的学号姓名.doc。

    3.编写BinIoDemo.java的Java应用程序,程序完成的功能是:完成1.doc文件的复制,复制以后的文件的名称为自己的学号姓名.doc. try { FileInputStream in = ...

  5. Java基础-输入输出-2.编写IoDemo.java的Java应用程序,程序完成的功能是:首先读取text.txt文件内容,再通过键盘输入文件的名称为iodemo.txt,把text.txt的内容存入iodemo.txt

    2.编写IoDemo.java的Java应用程序,程序完成的功能是:首先读取text.txt文件内容,再通过键盘输入文件的名称为iodemo.txt,把text.txt的内容存入iodemo.txt ...

  6. JAVA基础-输入输出:1.编写TextRw.java的Java应用程序,程序完成的功能是:首先向TextRw.txt中写入自己的学号和姓名,读取TextRw.txt中信息并将其显示在屏幕上。

    1.编写TextRw.java的Java应用程序,程序完成的功能是:首先向TextRw.txt中写入自己的学号和姓名,读取TextRw.txt中信息并将其显示在屏幕上. package Test03; ...

  7. 使用 python 实现 wc 命令程序的基本功能

    这里使用了 python 的基本代码实现了 Linux 系统下 wc 命令程序的基本功能. #!/usr/bin/env python #encoding: utf-8 # Author: liwei ...

  8. 图像处理控件ImageGear for .NET教程如何为应用程序 添加DICOM功能(2)

    在前面的一些关于图像处理控件ImageGear for .NET文章<图像处理控件ImageGear for .NET教程: 添加DICOM功能(1)>中讲解了如何对应用程序添加DICOM ...

  9. 系统设计 - IOS 程序插件及功能动态更新思路

    所用框架及语言 IOS客户端-Wax(开发愤怒的小鸟的连接Lua 和 Objc的框架),Lua,Objc, 服务端-Java(用于返回插件页面)        由 于Lua脚本语言,不需要编译即可运行 ...

随机推荐

  1. 初学django框架 (urls,include子路由,render模板渲染)(一)

    一.urls url的使用为了告诉django哪个url调用那一段代码 如上左图所示,后面的test,test1如下图所示,为视图函数,通过前面的路径,调用后面函数的代码: 只有输入正确的url才会在 ...

  2. QFramework 使用指南 2020(六):脚本生成(4)小结与补充

    我们花了四篇文章,介绍了 QF 中的脚本生成功能. 实际上 QF 中的脚本生成是有两种的,第一种就是我们现在学习的 ViewController + Bind 模式. 这种模式是为除 UGUI 以外的 ...

  3. centos(linux)-jdk配置

    1.清理系统默认自带的jdk 在安装centos时,可能系统会默认安装了例如openjdk等,需要先手动卸载 先执行:rpm -qa | grep jdk (查看已经自带的jdk): 卸载命名:sud ...

  4. 《剑指offer》树专题 (牛客10.25)

    考察的知识点主要在于树的数据结构(BST,AVL).遍历方式(前序,中序,后序,层次).遍历算法(DFS,BFS,回溯)以及遍历时借助的数据结构如队列和栈.由于树本身就是一个递归定义的结构,所以在递归 ...

  5. 义隆单片机学习笔记之(一) 硬件框架&资源下载

    参考网址: 点击链接或右键链接地址 (台湾义隆官网)http://www.emc.com.tw/chs/tech_8bit.asp (EM78P153K官方资料)http://www.emc.com. ...

  6. sleep(0) 的作用

    思考下面这两个问题: 假设现在是 2019-5-18 12:00:00.00,如果我调用一下 Thread.Sleep(1000) ,在 2019-5-18 12:00:01.00 的时候,这个线程会 ...

  7. PTA(Advanced Level)1048.Find Coins

    Eva loves to collect coins from all over the universe, including some other planets like Mars. One d ...

  8. IDEA插件之PMD

    1.是什么? PMD 是一个开源静态源代码分析器,它报告在应用程序代码中发现的问题.PMD包含内置规则集,并支持编写自定义规则的功能.PMD不报告编译错误,因为它只能处理格式正确的源文件.PMD报告的 ...

  9. 【AtCoder】AGC004

    AGC004 A - Divide a Cuboid 看哪一维是偶数,答案是0,否则是三个数两两组合相乘中最小的那个 #include <bits/stdc++.h> #define fi ...

  10. Python基础学习路径

    1. Python数据结构 1. 基本数据类型(整数.小数.字符) 1.基本数据类型有5种:int bool float complex long 2.每一种数据类型该如何定义 3.数据类型之间可以强 ...