一、Mapjoin案例

  1.需求:有两个文件,分别是订单表、商品表,

  订单表有三个属性分别为订单时间、商品id、订单id(表示内容量大的表),

  商品表有两个属性分别为商品id、商品名称(表示内容量小的表,用于加载到内存),

  要求结果文件为在订单表中的每一行最后添加商品id对应的商品名称。

  2.解决思路:

  将商品表加载到内存中,然后再map方法中将订单表中的商品id对应的商品名称添加到该行的最后,不需要Reducer,并在Driver执行类中设置setCacheFile和numReduceTask。

  3.代码如下:

  1. public class CacheMapper extends Mapper<LongWritable, Text, Text, NullWritable>{
  2.  
  3. HashMap<String, String> pdMap = new HashMap<>();
  4. //1.商品表加载到内存
  5. protected void setup(Context context) throws IOException {
  6.  
  7. //加载缓存文件
  8. BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("pd.txt"), "Utf-8"));
  9.  
  10. String line;
  11.  
  12. while(StringUtils.isNotEmpty(line = br.readLine()) ) {
  13.  
  14. //切分
  15. String[] fields = line.split("\t");
  16.  
  17. //缓存
  18. pdMap.put(fields[0], fields[1]);
  19.  
  20. }
  21.  
  22. br.close();
  23.  
  24. }
  25.  
  26. //2.map传输
  27. @Override
  28. protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, NullWritable>.Context context)
  29. throws IOException, InterruptedException {
  30. //获取数据
  31. String line = value.toString();
  32.  
  33. //切割
  34. String[] fields = line.split("\t");
  35.  
  36. //获取订单中商品id
  37. String pid = fields[1];
  38.  
  39. //根据订单商品id获取商品名
  40. String pName = pdMap.get(pid);
  41.  
  42. //拼接数据
  43. line = line + "\t" + pName;
  44.  
  45. //输出
  46. context.write(new Text(line), NullWritable.get());
  47. }
  48. }
  49.  
  50. public class CacheDriver {
  51. public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException, URISyntaxException {
  52. // 1.获取job信息
  53. Configuration conf = new Configuration();
  54. Job job = Job.getInstance(conf);
  55.  
  56. // 2.获取jar包
  57. job.setJarByClass(CacheDriver.class);
  58.  
  59. // 3.获取自定义的mapper与reducer类
  60. job.setMapperClass(CacheMapper.class);
  61.  
  62. // 5.设置reduce输出的数据类型(最终的数据类型)
  63. job.setOutputKeyClass(Text.class);
  64. job.setOutputValueClass(NullWritable.class);
  65.  
  66. // 6.设置输入存在的路径与处理后的结果路径
  67. FileInputFormat.setInputPaths(job, new Path("c://table1029//in"));
  68. FileOutputFormat.setOutputPath(job, new Path("c://table1029//out"));
  69.  
  70. //加载缓存商品数据
  71. job.addCacheFile(new URI("file:///c:/inputcache/pd.txt"));
  72.  
  73. //设置一下reducetask的数量
  74. job.setNumReduceTasks(0);
  75.  
  76. // 7.提交任务
  77. boolean rs = job.waitForCompletion(true);
  78. System.out.println(rs ? 0 : 1);
  79. }
  80. }

  

二、Reducejoin案例

  1.需求:同上的两个数据文件,要求将订单表中的商品id替换成对应的商品名称。

  2.解决思路:封装TableBean类,包含属性:时间、商品id、订单id、商品名称、flag(flag用来判断是哪张表),

    使用Mapper读两张表,通过context对象获取切片对象,然后通过切片获取切片名称和路径的字符串来判断是哪张表,再将切片的数据封装到TableBean对象,最后以产品id为key、TableBean对象为value传输到Reducer端;

    Reducer接收数据后通过flag判断是哪张表,因为一个reduce中的所有数据的key是相同的,将商品表的商品id和商品名称读入到一个TableBean对象中,然后将订单表的中的数据读入到TableBean类型的ArrayList对象中,然后将ArrayList中的每个TableBean的商品id替换为商品名称,然后遍历该数组以TableBean为key输出。

  3.代码如下:

  1. /**
  2. * @author: PrincessHug
  3. * @date: 2019/3/30, 2:37
  4. * @Blog: https://www.cnblogs.com/HelloBigTable/
  5. */
  6. public class TableBean implements Writable {
  7. private String timeStamp;
  8. private String productId;
  9. private String orderId;
  10. private String productName;
  11. private String flag;
  12.  
  13. public TableBean() {
  14. }
  15.  
  16. public String getTimeStamp() {
  17. return timeStamp;
  18. }
  19.  
  20. public void setTimeStamp(String timeStamp) {
  21. this.timeStamp = timeStamp;
  22. }
  23.  
  24. public String getProductId() {
  25. return productId;
  26. }
  27.  
  28. public void setProductId(String productId) {
  29. this.productId = productId;
  30. }
  31.  
  32. public String getOrderId() {
  33. return orderId;
  34. }
  35.  
  36. public void setOrderId(String orderId) {
  37. this.orderId = orderId;
  38. }
  39.  
  40. public String getProductName() {
  41. return productName;
  42. }
  43.  
  44. public void setProductName(String productName) {
  45. this.productName = productName;
  46. }
  47.  
  48. public String getFlag() {
  49. return flag;
  50. }
  51.  
  52. public void setFlag(String flag) {
  53. this.flag = flag;
  54. }
  55.  
  56. @Override
  57. public void write(DataOutput out) throws IOException {
  58. out.writeUTF(timeStamp);
  59. out.writeUTF(productId);
  60. out.writeUTF(orderId);
  61. out.writeUTF(productName);
  62. out.writeUTF(flag);
  63. }
  64.  
  65. @Override
  66. public void readFields(DataInput in) throws IOException {
  67. timeStamp = in.readUTF();
  68. productId = in.readUTF();
  69. orderId = in.readUTF();
  70. productName = in.readUTF();
  71. flag = in.readUTF();
  72. }
  73.  
  74. @Override
  75. public String toString() {
  76. return timeStamp + "\t" + productName + "\t" + orderId;
  77. }
  78. }
  79.  
  80. public class TableMapper extends Mapper<LongWritable, Text,Text,TableBean> {
  81. @Override
  82. protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
  83. //通过切片获取文件信息
  84. FileSplit split = (FileSplit) context.getInputSplit();
  85. String name = split.getPath().getName();
  86.  
  87. //获取一行数据、定义TableBean对象
  88. String line = value.toString();
  89. TableBean tb = new TableBean();
  90. Text t = new Text();
  91.  
  92. //判断是哪一张表
  93. if (name.contains("order.txt")){
  94. String[] fields = line.split("\t");
  95. tb.setTimeStamp(fields[0]);
  96. tb.setProductId(fields[1]);
  97. tb.setOrderId(fields[2]);
  98. tb.setProductName("");
  99. tb.setFlag("0");
  100. t.set(fields[1]);
  101. }else {
  102. String[] fields = line.split("\t");
  103. tb.setTimeStamp("");
  104. tb.setProductId(fields[0]);
  105. tb.setOrderId("");
  106. tb.setProductName(fields[1]);
  107. tb.setFlag("1");
  108. t.set(fields[0]);
  109. }
  110. context.write(t,tb);
  111. }
  112. }
  113.  
  114. public class TableReducer extends Reducer<Text,TableBean,TableBean, NullWritable> {
  115. @Override
  116. protected void reduce(Text key, Iterable<TableBean> values, Context context) throws IOException, InterruptedException {
  117. //分别创建用来存储订单表和产品表的集合
  118. ArrayList<TableBean> orderBean = new ArrayList<>();
  119. TableBean productBean = new TableBean();
  120.  
  121. //遍历values,通过flag判断是产品表还是订单表
  122. for (TableBean v:values){
  123. if (v.getFlag().equals("0")){
  124. TableBean tableBean = new TableBean();
  125. try {
  126. BeanUtils.copyProperties(tableBean,v);
  127. } catch (IllegalAccessException e) {
  128. e.printStackTrace();
  129. } catch (InvocationTargetException e) {
  130. e.printStackTrace();
  131. }
  132. orderBean.add(tableBean);
  133. }else {
  134. try {
  135. BeanUtils.copyProperties(productBean,v);
  136. } catch (IllegalAccessException e) {
  137. e.printStackTrace();
  138. } catch (InvocationTargetException e) {
  139. e.printStackTrace();
  140. }
  141. }
  142. }
  143. //拼接表
  144. for (TableBean ob:orderBean) {
  145. ob.setProductName(productBean.getProductName());
  146. context.write(ob,NullWritable.get());
  147. }
  148. }
  149. }
  150.  
  151. public class TableDriver {
  152. public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
  153. //job信息
  154. Configuration conf = new Configuration();
  155. Job job = Job.getInstance(conf);
  156.  
  157. //jar包
  158. job.setJarByClass(TableDriver.class);
  159.  
  160. //Mapper、Reducer
  161. job.setMapperClass(TableMapper.class);
  162. job.setReducerClass(TableReducer.class);
  163.  
  164. //Mapper输出数据类型
  165. job.setMapOutputKeyClass(Text.class);
  166. job.setMapOutputValueClass(TableBean.class);
  167.  
  168. //Reducer输出数据类型
  169. job.setOutputKeyClass(TableBean.class);
  170. job.setOutputValueClass(NullWritable.class);
  171.  
  172. //输入输出路径
  173. FileInputFormat.setInputPaths(job,new Path("G:\\mapreduce\\reducejoin\\in"));
  174. FileOutputFormat.setOutputPath(job,new Path("G:\\mapreduce\\reducejoin\\out"));
  175.  
  176. //提交任务
  177. if (job.waitForCompletion(true)){
  178. System.out.println("运行完成!");
  179. }else {
  180. System.out.println("运行失败!");
  181. }
  182. }
  183. }

  

Mapjoin和Reducejoin案例的更多相关文章

  1. mapjoin与reducejoin

    一.mapjoin 1.Mapper类 package com.css.mapjoin; import java.io.BufferedReader; import java.io.FileInput ...

  2. 使用MapReduce实现join操作

     在关系型数据库中,要实现join操作是非常方便的,通过sql定义的join原语就可以实现.在hdfs存储的海量数据中,要实现join操作,可以通过HiveQL很方便地实现.不过HiveQL也是转化成 ...

  3. 【大数据】Hive学习笔记

    第1章 Hive基本概念 1.1 什么是Hive Hive:由Facebook开源用于解决海量结构化日志的数据统计. Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表, ...

  4. MapReduce(四) 典型编程场景(二)

    一.MapJoin-DistributedCache 应用 1.mapreduce join 介绍 在各种实际业务场景中,按照某个关键字对两份数据进行连接是非常常见的.如果两份数据 都比较小,那么可以 ...

  5. 工作中常见的hive语句总结

    hive的启动: 1.启动hadoop2.开启 metastore 在开启 hiveserver2服务nohup hive --service metastore >> log.out 2 ...

  6. 大数据技术之Hive

    第1章 Hive入门 1.1 什么是Hive Hive:由Facebook开源用于解决海量结构化日志的数据统计. Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提 ...

  7. MR案例:Reduce-Join

    问题描述:两种类型输入文件:address(地址)和company(公司)进行一对多的关联查询,得到地址名(例如:Beijing)与公司名(例如:Beijing JD.Beijing Red Star ...

  8. MapReduce之MapJoin案例

    @ 目录 使用场景 优点 具体办法:采用DistributedCache 案例 需求分析 代码实现 使用场景 Map Join 适用于一张表十分小.一张表很大的场景. 优点 思考:在Reduce 端处 ...

  9. MR案例:Map-Join

    适用场景:一张表十分小[key不可重复].一张表非常大. 用法:在Job提交时,首先将小表加载到 DistributedCache 分布式缓存中,然后从DistributeCache中读取小表解析成 ...

随机推荐

  1. 工作环境换成Ubuntu18.04小记

    Linux汇总:https://www.cnblogs.com/dunitian/p/4822808.html#linux Ubuntu常用软件安装(小集合)http://www.cnblogs.co ...

  2. tomcat8 源码分析 | 组件及启动过程

    tomcat 8 源码分析 ,本文主要讲解tomcat拥有哪些组件,容器,又是如何启动的 推荐访问我的个人网站,排版更好看呦: https://chenmingyu.top/tomcat-source ...

  3. BZOJ 3613: [Heoi2014]南园满地堆轻絮(二分)

    题面: https://www.lydsy.com/JudgeOnline/problem.php?id=3613 题解: 考虑前面的数越小答案越优秀,于是我们二分答案,判断时让前面的数达到所能达到的 ...

  4. 时间函数(1):time,ctime,gmtime,localtime

    asctime(将时间和日期以字符串格式表示) #include<time.h> 定义函数 char * asctime(const struct tm * timeptr); 函数说明 ...

  5. 应用调试(四)系统调用SWI

    目录 应用调试(四)系统调用SWI 系统调用 SWI代码片段分析 分析sys_write 构造sys_hello 应用程序调用SWI 嵌入汇编语法 测试APP 参考 title: 应用调试(四)系统调 ...

  6. Kubernetes之ServiceAccount

    ServiceAccount 是什么 Service Account为Pod中的进程和外部用户提供身份信息.所有的kubernetes集群中账户分为两类,Kubernetes管理的serviceacc ...

  7. .NET面试题系列(十六)数据库面试题

    数据库事务的四大特性 原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚.因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响. ...

  8. 使用sessionStorage、localStorage存储数组与对象

    先介绍一下localStorage localStorage对象是HTML5的客户端存储持久化数据的方案.为了能访问到同一个localStorage对象,页面必须来自同一个域名(子域名无效),使用同一 ...

  9. 学习WPF

    http://www.cnblogs.com/prism/archive/2010/07/21/1781855.html 如何在WPF中画三角,以及把按钮设置成颜色渐变的样式:

  10. ue4 材质表达式分类

    绿色节点 颜色 Color Desaturation 数学 Math GO 字体 Font FontSample,FontSampleParameter 实用程序 Utility 常用: Desatu ...