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.代码实现:

  1. package cn.bigdata.mr.rjoin;
  2. import java.io.DataInput;
  3. import java.io.DataOutput;
  4. import java.io.IOException;
  5. import org.apache.hadoop.io.Writable;
  6.  
  7. public class InfoBean implements Writable {
  8.  
  9. private int order_id;
  10. private String dateString;
  11. private String p_id;
  12. private int amount;
  13. private String pname;
  14. private int category_id;
  15. private float price;
  16.  
  17. // flag=0表示这个对象是封装订单表记录
  18. // flag=1表示这个对象是封装产品信息记录
  19. private String flag;
  20.  
  21. public InfoBean() {
  22. }
  23.  
  24. public void set(int order_id, String dateString, String p_id, int amount, String pname, int category_id, float price, String flag) {
  25. this.order_id = order_id;
  26. this.dateString = dateString;
  27. this.p_id = p_id;
  28. this.amount = amount;
  29. this.pname = pname;
  30. this.category_id = category_id;
  31. this.price = price;
  32. this.flag = flag;
  33. }
  34.  
  35. public int getOrder_id() {
  36. return order_id;
  37. }
  38.  
  39. public void setOrder_id(int order_id) {
  40. this.order_id = order_id;
  41. }
  42.  
  43. public String getDateString() {
  44. return dateString;
  45. }
  46.  
  47. public void setDateString(String dateString) {
  48. this.dateString = dateString;
  49. }
  50.  
  51. public String getP_id() {
  52. return p_id;
  53. }
  54.  
  55. public void setP_id(String p_id) {
  56. this.p_id = p_id;
  57. }
  58.  
  59. public int getAmount() {
  60. return amount;
  61. }
  62.  
  63. public void setAmount(int amount) {
  64. this.amount = amount;
  65. }
  66.  
  67. public String getPname() {
  68. return pname;
  69. }
  70.  
  71. public void setPname(String pname) {
  72. this.pname = pname;
  73. }
  74.  
  75. public int getCategory_id() {
  76. return category_id;
  77. }
  78.  
  79. public void setCategory_id(int category_id) {
  80. this.category_id = category_id;
  81. }
  82.  
  83. public float getPrice() {
  84. return price;
  85. }
  86.  
  87. public void setPrice(float price) {
  88. this.price = price;
  89. }
  90.  
  91. public String getFlag() {
  92. return flag;
  93. }
  94.  
  95. public void setFlag(String flag) {
  96. this.flag = flag;
  97. }
  98.  
  99. /**
  100. * private int order_id; private String dateString; private int p_id;
  101. * private int amount; private String pname; private int category_id;
  102. * private float price;
  103. */
  104. @Override
  105. public void write(DataOutput out) throws IOException {
  106. out.writeInt(order_id);
  107. out.writeUTF(dateString);
  108. out.writeUTF(p_id);
  109. out.writeInt(amount);
  110. out.writeUTF(pname);
  111. out.writeInt(category_id);
  112. out.writeFloat(price);
  113. out.writeUTF(flag);
  114. }
  115.  
  116. @Override
  117. public void readFields(DataInput in) throws IOException {
  118. this.order_id = in.readInt();
  119. this.dateString = in.readUTF();
  120. this.p_id = in.readUTF();
  121. this.amount = in.readInt();
  122. this.pname = in.readUTF();
  123. this.category_id = in.readInt();
  124. this.price = in.readFloat();
  125. this.flag = in.readUTF();
  126.  
  127. }
  128.  
  129. @Override
  130. public String toString() {
  131. return "order_id=" + order_id + ", dateString=" + dateString + ", p_id=" + p_id + ", amount=" + amount + ", pname=" + pname + ", category_id=" + category_id + ", price=" + price ;
  132. }
  133. }
  1. package cn.bigdata.mr.rjoin;
  2. import java.io.IOException;
  3. import java.util.ArrayList;
  4. import org.apache.commons.beanutils.BeanUtils;
  5. import org.apache.hadoop.conf.Configuration;
  6. import org.apache.hadoop.fs.Path;
  7. import org.apache.hadoop.io.LongWritable;
  8. import org.apache.hadoop.io.NullWritable;
  9. import org.apache.hadoop.io.Text;
  10. import org.apache.hadoop.mapreduce.Job;
  11. import org.apache.hadoop.mapreduce.Mapper;
  12. import org.apache.hadoop.mapreduce.Reducer;
  13. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
  14. import org.apache.hadoop.mapreduce.lib.input.FileSplit;
  15. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
  16.  
  17. /**
  18. * 订单表和商品表合到一起
  19. order.txt(订单id, 日期, 商品编号, 数量)
  20. 1001 20150710 P0001 2
  21. 1002 20150710 P0001 3
  22. 1002 20150710 P0002 3
  23. 1003 20150710 P0003 3
  24. product.txt(商品编号, 商品名字, 价格, 数量)
  25. P0001 小米5 1001 2
  26. P0002 锤子T1 1000 3
  27. P0003 锤子 1002 4
  28. */
  29. public class RJoin {
  30.  
  31. static class RJoinMapper extends Mapper<LongWritable, Text, Text, InfoBean> {
  32. InfoBean bean = new InfoBean();
  33. Text k = new Text();
  34.  
  35. @Override
  36. protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
  37. String line = value.toString();
  38.  
  39. FileSplit inputSplit = (FileSplit) context.getInputSplit();
  40. String name = inputSplit.getPath().getName();
  41. System.out.println("kkkkkkkkkkkkkkkkkkkkkk"+name);
  42. // 通过文件名判断是哪种数据
  43. String pid = "";
  44. if (name.startsWith("order")) {
  45. String[] fields = line.split(",");
  46. // id date pid amount
  47. pid = fields[];
  48. bean.set(Integer.parseInt(fields[]), fields[], pid, Integer.parseInt(fields[]), "", , , "");
  49.  
  50. } else {
  51. String[] fields = line.split(",");
  52. // id pname category_id price
  53. pid = fields[];
  54. bean.set(, "", pid, , fields[], Integer.parseInt(fields[]), Float.parseFloat(fields[]), "");
  55.  
  56. }
  57. k.set(pid);
  58. context.write(k, bean);
  59. }
  60. }
  61.  
  62. static class RJoinReducer extends Reducer<Text, InfoBean, InfoBean, NullWritable> {
  63.  
  64. @Override
  65. protected void reduce(Text pid, Iterable<InfoBean> beans, Context context) throws IOException, InterruptedException {
  66. InfoBean pdBean = new InfoBean();
  67. ArrayList<InfoBean> orderBeans = new ArrayList<InfoBean>();
  68.  
  69. for (InfoBean bean : beans) {
  70. if ("".equals(bean.getFlag())) { //产品的
  71. try {
  72. BeanUtils.copyProperties(pdBean, bean);
  73. } catch (Exception e) {
  74. e.printStackTrace();
  75. }
  76. } else {
  77. InfoBean odbean = new InfoBean();
  78. try {
  79. BeanUtils.copyProperties(odbean, bean);
  80. orderBeans.add(odbean);
  81. } catch (Exception e) {
  82. e.printStackTrace();
  83. }
  84. }
  85. }
  86.  
  87. // 拼接两类数据形成最终结果
  88. for (InfoBean bean : orderBeans) {
  89.  
  90. bean.setPname(pdBean.getPname());
  91. bean.setCategory_id(pdBean.getCategory_id());
  92. bean.setPrice(pdBean.getPrice());
  93.  
  94. context.write(bean, NullWritable.get());
  95. }
  96. }
  97. }
  98.  
  99. public static void main(String[] args) throws Exception {
  100. Configuration conf = new Configuration();
  101.  
  102. conf.set("mapred.textoutputformat.separator", ",");
  103.  
  104. Job job = Job.getInstance(conf);
  105.  
  106. // 指定本程序的jar包所在的本地路径
  107. // job.setJarByClass(RJoin.class);
  108. // job.setJar("c:/join.jar");
  109.  
  110. job.setJarByClass(RJoin.class);
  111. // 指定本业务job要使用的mapper/Reducer业务类
  112. job.setMapperClass(RJoinMapper.class);
  113. job.setReducerClass(RJoinReducer.class);
  114.  
  115. // 指定mapper输出数据的kv类型
  116. job.setMapOutputKeyClass(Text.class);
  117. job.setMapOutputValueClass(InfoBean.class);
  118.  
  119. // 指定最终输出的数据的kv类型
  120. job.setOutputKeyClass(InfoBean.class);
  121. job.setOutputValueClass(NullWritable.class);
  122.  
  123. // 指定job的输入原始文件所在目录
  124. FileInputFormat.setInputPaths(job, new Path(args[]));
  125. // 指定job的输出结果所在目录
  126. FileOutputFormat.setOutputPath(job, new Path(args[]));
  127.  
  128. // 将job中配置的相关参数,以及job所用的java类所在的jar包,提交给yarn去运行
  129. /* job.submit(); */
  130. boolean res = job.waitForCompletion(true);
  131. System.exit(res ? : );
  132. }
  133. }

运行结果:

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. Hackertarget:一款发现攻击面的工具

    前言 https://github.com/ismailtasdelen/hackertarget 代码 主要通过这家公司提供的API查询相关数据实现的功能,API看起来可以用很久. #!/usr/b ...

  2. mac 查看隐藏文件及快速打开终端

    查看隐藏文件: 1.在目标目录打开终端,然后输入ls -al命令快速查看目标目录下的文件(包括隐藏文件) 2.快捷键shift+cmmand+.(显示或者隐藏) 打开终端方式: 1.设置组合快捷键,单 ...

  3. (IStool)删除新版本已废弃但可能会影响新版本运行的文件夹/文件

    需求:老版本服务器的某些文件或文件夹在新版本已弃用,新版本覆盖安装时需要将文件夹或文件删除 实现:覆盖安装完成后将对应目录下的文件删除 [InstallDelete] Type: files; Nam ...

  4. sql注入02

    第一关:基于错误的get单引号字符型注入 第二关:基于错误的get整形注入 第三关:基于错误的get单引号变形字符型注入 第四关:基础错误的双引号字符型注入 第五关: 第六关 第七关:导出文件get字 ...

  5. ffmpeg学习笔记-多线程音视频解码

    之前的视频解码仍然存在问题,那就是是在主线程中去完成解码的,会造成线程阻塞,这里将其改为多线程解码,使其主线程不被阻塞 前面介绍了音视频的主线程解码,那样会阻塞主线程,在前面学习了多线程以后,就可以对 ...

  6. Velocity 数值格式化(NumberTool工具类):保留两位小数和格式化千分位、取整

    Velocity 自带的工具类:NumberTool 实现数字格式化:保留两位小数和格式化千分位,以及取整. NumberTool 的 format(String format, Object obj ...

  7. MemCache在.NET中使用Memcached.ClientLibrary详解

    本文说明:memcached分布式缓存的负载均衡配置比例,数据压缩,socket的详细配置等,以及在.net中的常用方法 首先下载客户端的3个dll,ICSharpCode.SharpZipLib.d ...

  8. react新特性hook

    一.hook示例.   import React, { useState } from 'react'; function Example() { // 声明一个叫 “count” 的 state 变 ...

  9. mysql 启动出错

    错误:The server quit without updating PID file 看错误日志: Setting lower_case_table_names=2 because file sy ...

  10. java.net.UnknownHostException: MySQLMASTER: MySQLMASTER: 未知的名称或服务

    linux环境在连接Activemq的时候报以下信息,找了半天配了下host  OK了,记录一下. java.net.UnknownHostException: MySQLMASTER: MySQLM ...