1.Map端Join解决数据倾斜  

  1.Mapreduce中会将map输出的kv对,按照相同key分组(调用getPartition),然后分发给不同的reducetask

  2.Map输出结果的时候调用了Partitioner组件(返回分区号),由它决定将数据放到哪个区中,默认的分组规

则为:根据key的hashcode%reducetask数来分发,源代码如下:

  1. public class HashPartitioner<K, V> extends Partitioner<K, V> {
  2. /** Use {@link Object#hashCode()} to partition. */
  3. public int getPartition(K key, V value,int numReduceTasks) {
  4. return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
  5. }
  6. }

  3.所以:如果要按照我们自己的需求进行分组,则需要改写数据分发(分组)组件Partitioner,自定义一个

CustomPartitioner继承抽象类:Partitioner,来返回一个分区编号

  4.然后在job对象中,设置自定义partitioner: job.setPartitionerClass(CustomPartitioner.class)

  5.自定义partition后,要根据自定义partitioner的逻辑设置相应数量的ReduceTask


  存在的问题:如若Mapper输出的一些Key特别多,另一些Key特别少就会产生数据倾斜,造成一些Reducer特别忙

,一些则比较闲,我们说Mapper端相同key的输出数据会发到同一个Redurce端,需要把key相同的放在一起才能进行

拼接,所以才需要Reducer。如果我们不需要Reducer就能做拼接,就不存在数据倾斜了。

  解决方案:Map端Join解决数据倾斜,我们为每一个MapTask准备一个表的全表。这种机制叫做Map Side Join。

当然这个表的全表不能很大 

2.map端join算法实现原理:

  原理阐述:1.适用于关联表中有小表的情形;2.可以将小表分发到所有的map节点,这样,map节点就可以在本地

对自己所读到的大表数据进行join并输出最终结果,可以大大提高join操作的并发度,加快处理速度;3.Hadoop提供

了一个Distributed Cache机制,能把文件在合适的时候发给MapTask,MapTask就可以从本地进行加载小表数据;

3.map端join代码实现示例: 

  :先在mapper类中预先定义好小表,进行join

  :并用distributedcache机制将小表的数据分发到每一个maptask执行节点,从而每一个maptask节点可以从本地加

载到小表的数据,进而在本地即可实现join

  :引入实际场景中的解决方案:一次加载数据库或者用distributedcache

代码:

  1. package cn.gigdata.hdfs.mr;
  2. import java.io.BufferedReader;
  3. import java.io.FileInputStream;
  4. import java.io.IOException;
  5. import java.io.InputStreamReader;
  6. import java.net.URI;
  7. import java.util.HashMap;
  8. import java.util.Map;
  9. import org.apache.commons.lang.StringUtils;
  10. import org.apache.hadoop.conf.Configuration;
  11. import org.apache.hadoop.fs.Path;
  12. import org.apache.hadoop.io.LongWritable;
  13. import org.apache.hadoop.io.NullWritable;
  14. import org.apache.hadoop.io.Text;
  15. import org.apache.hadoop.mapreduce.Job;
  16. import org.apache.hadoop.mapreduce.Mapper;
  17. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
  18. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
  19.  
  20. /**
  21. * 解决在Redue端的数据倾斜问题
  22. * @author Administrator
  23. */
  24.  
  25. public class MapSideJoin {
  26. public static class MapSideJoinMapper extends Mapper<LongWritable, Text, Text, NullWritable>{
  27.  
  28. // 用一个hashmap来加载保存产品信息表
  29. Map<String, String> pdInfoMap = new HashMap<String, String>();
  30. Text k = new Text();
  31. /**
  32. * 通过阅读父类Mapper的源码,发现 setup方法是在maptask处理数据之前调用一次 可以用来做一些初始化工作
  33. */
  34. @Override
  35. protected void setup(Mapper<LongWritable, Text, Text, NullWritable>.Context context) throws IOException, InterruptedException {
  36. //读取MapTask工作目录(已经存在,直接根据文件名进行读取)的文件,将数据放入HashMap中
  37. BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("pdts.txt")));
  38. String line;
  39. while(StringUtils.isNotEmpty(line = br.readLine())){
  40. String[] fields = line.split(",");
  41. pdInfoMap.put(fields[0], fields[1]);
  42. }
  43. br.close();
  44. }
  45.  
  46. //由于已经持有完整的产品信息表,所以在map方法中就能实现join逻辑了
  47. @Override
  48. protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
  49. String orderLine = value.toString();
  50. String fields[] = orderLine.split(",");
  51. //根据订单ID,在商品表中get到ID对应的商品名称
  52. String pdName = pdInfoMap.get(fields[2]);
  53. k.set(orderLine + "," + pdName);
  54. context.write(k, NullWritable.get());
  55. }
  56. }
  57.  
  58. public static void main(String[] args) throws Exception {
  59. Configuration conf = new Configuration();
  60.  
  61. Job job = Job.getInstance(conf);
  62.  
  63. job.setJarByClass(MapSideJoin.class);
  64.  
  65. job.setMapperClass(MapSideJoinMapper.class);
  66. job.setMapOutputKeyClass(Text.class);
  67. job.setMapOutputValueClass(NullWritable.class);
  68.  
  69. FileInputFormat.setInputPaths(job, new Path(args[0]));
  70. FileOutputFormat.setOutputPath(job, new Path(args[1]));
  71.  
  72. // 指定需要缓存一个文件到所有的maptask运行节点工作目录
  73. /* job.addArchiveToClassPath(archive); */// 缓存jar包到task运行节点的classpath中
  74. /* job.addFileToClassPath(file); */// 缓存普通文件到task运行节点的classpath中
  75. /* job.addCacheArchive(uri); */// 缓存压缩包文件到task运行节点的工作目录
  76. /* job.addCacheFile(uri) */// 缓存普通文件到task运行节点的工作目录
  77.  
  78. // 将产品表文件缓存到Maptask工作节点的工作目录中去(Map运行时将会得到改文件)
  79. job.addCacheFile(new URI("file:/F:/pduct/pdts.txt"));
  80.  
  81. //map端join的逻辑不需要reduce阶段,设置reducetask数量为0
  82. job.setNumReduceTasks(0);
  83.  
  84. boolean res = job.waitForCompletion(true);
  85. System.exit(res ? 0 : 1);
  86. }
  87. }

产品数据文件:pdts.txt

  1. P0001,sss,1001,2
  2. P0002,111,1000,3
  3. P0003,www,1002,4

订单数据文件:order.txt

  1. 1001,20150710,P0001,2
  2. 1002,20150710,P0001,3
  3. 1002,20150710,P0002,3
  4. 1003,20150710,P0003,3

运行结果文件:part-m-00000

  1. 1001,20150710,P0001,2,sss
  2. 1002,20150710,P0001,3,sss
  3. 1002,20150710,P0002,3,111
  4. 1003,20150710,P0003,3,www

  

Hadoop_22_MapReduce map端join实现方式解决数据倾斜(DistributedCache)的更多相关文章

  1. hadoop的压缩解压缩,reduce端join,map端join

    hadoop的压缩解压缩 hadoop对于常见的几种压缩算法对于我们的mapreduce都是内置支持,不需要我们关心.经过map之后,数据会产生输出经过shuffle,这个时候的shuffle过程特别 ...

  2. Spark性能调优之解决数据倾斜

    Spark性能调优之解决数据倾斜 数据倾斜七种解决方案 shuffle的过程最容易引起数据倾斜 1.使用Hive ETL预处理数据    • 方案适用场景:如果导致数据倾斜的是Hive表.如果该Hiv ...

  3. 【Spark篇】---Spark解决数据倾斜问题

    一.前述 数据倾斜问题是大数据中的头号问题,所以解决数据清洗尤为重要,本文只针对几个常见的应用场景做些分析 . 二.具体方法  1.使用Hive ETL预处理数据 方案适用场景: 如果导致数据倾斜的是 ...

  4. [MapReduce_add_3] MapReduce 通过分区解决数据倾斜

    0. 说明 数据倾斜及解决方法的介绍与代码实现 1. 介绍 [1.1 数据倾斜的含义] 大量数据发送到同一个节点进行处理,造成此节点繁忙甚至瘫痪,而其他节点资源空闲 [1.2 解决数据倾斜的方式] 重 ...

  5. map端join

    package my.hadoop.hdfs.mapreduceJoin; import java.io.BufferedReader; import java.io.FileInputStream; ...

  6. 专访周金可:我们更倾向于Greenplum来解决数据倾斜的问题

    周金可,就职于听云,维护MySQL和GreenPlum的正常运行,以及调研适合听云业务场景的数据库技术方案. 听云周金可 9月24日,周金可将参加在北京举办的线下活动,并做主题为<GreenPl ...

  7. MapReduce如何解决数据倾斜?

    数据倾斜是日常大数据查询中隐形的一个BUG,遇不到它时你觉得数据倾斜也就是书本博客上的一个无病呻吟的偶然案例,但当你遇到它是你就会懊悔当初怎么不多了解一下这个赫赫有名的事故. https://www. ...

  8. Spark性能优化之道——解决Spark数据倾斜(Data Skew)的N种姿势

    原创文章,同步首发自作者个人博客转载请务必在文章开头处注明出处. 摘要 本文结合实例详细阐明了Spark数据倾斜的几种场景以及对应的解决方案,包括避免数据源倾斜,调整并行度,使用自定义Partitio ...

  9. 061 hive中的三种join与数据倾斜

    一:hive中的三种join 1.map join 应用场景:小表join大表 一:设置mapjoin的方式: )如果有一张表是小表,小表将自动执行map join. 默认是true. <pro ...

随机推荐

  1. 使用PostMan测试WebService接口

    使用PostMan测试WebService接口 参考资料: 通过XML请求WebServer  https://blog.csdn.net/qq_33933408/article/details/53 ...

  2. 双目结构光三维扫描仪获得的三维点云模型(GIF)

  3. 10.Windows远程管理工具RAT----Metasploit基础----Metasploit模块----fsociety工具包

    Windows远程管理工具RAT QuasarRAT github.com/quasar/QuasarRAT 命令环境 MINGW64 (GCC编译器) mkdir RAT cd RAT git cl ...

  4. 关于使用Arduino做开发的理解

    转载自arduino中文社区 https://www.arduino.cn/thread-5414-1-1.html 见到很多人对Arduino的开发方法 .应用场景有误解,特别开个帖子说明下. 误解 ...

  5. WEB渗透技术之浅析路径遍历

    1. 发送 http://www.nuanyue.com/getfile=image.jgp 当服务器处理传送过来的image.jpg文件名后,Web应用程序即会自动添加完整路径,形如“d://sit ...

  6. java中JDBC是什么?

    [学习笔记] JDBC是什么? JDBC即(java database connectivity数据连接).JDBC是Sun公司编的一堆类和方法,都封装在java.sql包中.你可以利用这堆类和方法来 ...

  7. DB2部分查询SQL

    /* 部分SQL */ --添加主键 alter TABLE TABLE_SCHEMA.TABLE_NAME add constraint PK_TABLE_NAME primary key(COL1 ...

  8. Web安全小结之前端

  9. 轻松搭建CAS 5.x系列(2)-搭建HTTPS的SSO SERVER端

    概要说明 CAS要求,必须使用HTTPS的服务,否则就只等实现登录,无法实现单点登录.科普下HTTPS,网站有HTTP和HTTPS两种协议.HTTP是浏览器到网站之间是明文传输,比如你输入帐号名和密码 ...

  10. 服务返回的json数据过大,nginx无法返回给client

    现象:请求同样的服务器,N多个接口中,只有一个接口未返回:从日志看,请求已到后端服务,并返回 解决方案:配置nginx缓冲大小 ###Nginx的缓冲区的大小 proxy_buffer_size 5m ...