一 Common JOIN/Reduce Side JOIN/Shuffle JOIN

这三种其实都是一种连接方案:即在Reduce端做JOIN操作。一般情况下,如果不手动指定MapJoin或者不满足MapJoin的条件,一般Hive解析器会将Join操作转换成ReduceJoin. 他会经历完整的Map

->Shuffle->Reduce三个阶段

Map阶段: 读取表中数据,输出的时候以JoinKey作为OutputKey,如果有多个关联条件,然后这些会组合成一个key, 输出的时候以SELECT字段或者WHERE条件需要的列作为OutputValue,同时还会包含表的tag信息,以此标志这个value属于哪一个表

Shuffle阶段:根据key进行partition操作并且根据key进行排序,可以确保相同的key在同一个Reduce之中

Reduce阶段:根据key值完成JOIN操作,通过不同的tag来识别不同表中的数据

我们考虑个问题:在Reduce端做JOIN,肯定各个Reduce端要去对应Map端取数据,其中的shuffle过程想必都是知道的,所以如果表态大,会有大量的磁盘I/O和网络I/O操作,所以这种情况下,如果是大表之间JOIN是不太适合这种方案的。

适合场景:

两张表大小相当,而且表不是很大的适合可以使用这种方式,顺便集合一下Hive中Reduce的调优是没有问题的:

#比如开启中间压缩和最终输出压缩:但是CPU会增加,但是HDFS 写的时间会减少

sethive.exec.compress.intermediate=true;

setmapred.map.output.compression.codec=org.apache.hadoop.io.

compress.SnappyCodec

sethive.exec.compress.output=true;

setmapred.output.compression.codec=org.apache.hadoop.io.compress.

GZipCodec

#设置set mapred.max.split.size调大一点:CPU可以适当的减少

二 MapSide Join/Broadcast JOIN

如果有一张小表和大表做JOIN,那么这个时候,我们使用Reduce 端做JOIN是不太划算的,因为我们完全可以避免去跑Reduce。

在Map端直接读入小表进内存,然后在和大表JOIN,JOIN完毕,数据直接写入HDFS,完全没有必要去走Reduce

首先我们需要确定什么小表,它是由什么决定的呢?它是由hive.mapjoin.smalltable.filesize来决定,默认是hive.mapjoin.smalltable.

filesize=25000000,大约23M左右。

在以前如果需要使用MapJoin只能通过Hint提示/*+mapjoin(表名)*/

比如这种:

SELECT/*+MAPJOIN(time_dim)*/ count(*) FROM store_sales

sJOIN time_dim t ON s.ss_old_time_sk = t.t_tim_sk;

才能使用MapJoin,现在已经有参数可以控制是否自动转换成MapJoin,这个转换有参数:hive.auto.convert.join=true来控制,默认就是true.

原理:

1客户端本地执行的task1,它会扫描小表的的数据,然后将其转换成hashtable的数据结构,并写入本地的文件中,

/tmp/hadoop/479fb43b-6fc4-4aa8-846c-a052944ad02d/hive_2015-03-18_15-18-13_374_8641342742824793758-1/-local-10003/HashTable-Stage-3/MapJoin-mapfile01--.hashtable

2之后将该文件加载到DistributedCache中,

Uploaded1 File to:file:/tmp/hadoop/479fb43b-6fc4-4aa8-846c-a052944ad02d/hive_2017-03-18_15-18-13_374_8641342742824793758-1/-local-10003/HashTable-Stage-3/MapJoin-mapfile01--.hashtable

3Task 2 是一个没有Reduce的task,启动之后扫描大表,在map阶段,根据大表每一条记录然后去和DistributedCache中对应hashtable关联,然后输出结果,所以有多少个maptask就有多少个文件

三 SMBJOIN (Sort-Merge-Bucket)

我们试想一个场景:2张大表参与JOIN, 都是上千万或者上亿条记录,

假设这时候,这两张表中小表可能数据太多,不太适合加载进内存,那么MapJoin肯定是不合适的,那么ReduceJOIN呢?假设A表有数据4000万条,B表有数据6000万条,这时候ReduceJOIN首先肯定大量网络I/O和磁盘I/O,另外A表数据需要逐条和B表数据进行匹配吧,这个效率肯定不行。所以SMB JOIN可以带来性能很大的提升

首先: 两张表都是可以分桶的,在创建表的时候需要指定:

CREATETABLE(……) CLUSTERED BY (col_name) SORTED BY

(col_name)INTO bucketsNum BUCKETS

其次:两张表分桶的列必须是JOIN KEY

最后:需要设置一些bucket相关的参数

在导入数据值前,我们需要设置hive.enfoce.bucketing=true,如果我们没有设置,我们就需要设置与桶数匹配的reducer数目,并在查询的时候需要添加CLUSTER BY子句

然后,我们希望SMB JOIN转换成SMB Map JOIN需要设置一下参数:

sethive.auto.convert.sortmerge.join=true;

set hive.optimize.bucketmapjoin = true;

set hive.optimize.bucketmapjoin.sortedmerge =true;

原理:

在Map JOIN的时候,两个表是以相同的方式划分通的,则处理左边表的某个桶的时候,Mapper是知道表内对应的记录也在右边表的相同的桶内。因此Mapper只需要获取那个桶,然后进行连接就可以,就不用去每一条数据都去匹配一次。

桶中的数据可以根据一个列或者多个列排序,这样每个桶的JOIN就变成了MERGE SORT,可以进一步提升Map JOIN的效率

四 Skew Join

真实数据中数据倾斜是一定的, hadoop 中默认是使用

hive.exec.reducers.bytes.per.reducer =1000000000

也就是每个节点的reduce 默认是处理1G大小的数据,如果你的join 操作也产生了数据倾斜,那么你可以在hive 中设定

set hive.optimize.skewjoin = true; 
set hive.skewjoin.key = skew_key_threshold (default = 100000)

hive 在运行的时候没有办法判断哪个key 会产生多大的倾斜,所以使用这个参数控制倾斜的阈值,如果超过这个值,新的值会发送给那些还没有达到的reduce, 一般可以设置成你

(处理的总记录数/reduce个数)的2-4倍都可以接受.

倾斜是经常会存在的,一般select 的层数超过2层,翻译成执行计划多于3个以上的mapreduce job 都很容易产生倾斜,建议每次运行比较复杂的sql 之前都可以设一下这个参数. 如果你不知道设置多少,可以就按官方默认的1个reduce 只处理1G 的算法,那么  skew_key_threshold  =1G/平均行长. 或者默认直接设成250000000(差不多算平均行长4个字节)

Hive的连接(join)方案相关推荐

  1. Hive Join Strategies hive的连接策略

    2019独角兽企业重金招聘Python工程师标准>>> Common Join 最为普通的join策略,不受数据量的大小影响,也可以叫做reduce side join ,最没效率的 ...

  2. Hive的Map Join与Common Join

    笼统的说,Hive中的Join可分为Common Join(Reduce阶段完成join)和Map Join(Map阶段完成join). 一.Hive Common Join 如果不指定MapJoin ...

  3. HiveQL学习笔记(三):Hive表连接

    本系列是本人对Hive的学习进行一个整理,主要包括以下内容: 1.HiveQL学习笔记(一):Hive安装及Hadoop,Hive原理简介 2.HiveQL学习笔记(二):Hive基础语法与常用函数 ...

  4. Hive map side join入门及测试

    什么是MapJoin? MapJoin顾名思义,就是在Map阶段进行表之间的连接.而不需要进入到Reduce阶段才进行连接.这样就节省了在Shuffle阶段时要进行的大量数据传输.从而起到了优化作业的 ...

  5. Hive left semi join ,select 和 where中不能出现右表字段/不会生成笛卡尔积

    1 left semi join的时间比in的时间短,比in高效 2 left semi join时select中不能出现右表的字段,不然报错 3  left semi  join 时on中出现左表字 ...

  6. 轻松玩转hive中各种join之间的关系以及使用

    hive编程是整个数据仓库操作的核心,而各种业务之间的join是hive的核心,所以熟练明白滴掌握hive中的各种join是数据仓库开发工程师必备的技能.    hive中的join只支持等值join ...

  7. hive 内连接 左外连接 右外连接 满外连接 左半开连接 交叉连接 多表连接 隐式连接

    目录 hive outline hive 内连接 inner join hive 左外连接 left join hive 右外连接 right join hive 满外连接 full join hiv ...

  8. hive之Map Join使用方法

    目录 介绍 mapjoin的使用方法 结语 介绍 MAPJION会把小表全部加载到内存中,在map阶段直接拿另外一个表的数据和内存中表数据做匹配,由于在map端是进行了join操作,省去了reduce ...

  9. Hive优化之Join(三)

    1.Join算法概述   Hive拥有多种join算法,包括Common Join,Map Join,Bucket Map Join,Sort Merge Buckt Map Join等,下面对每种j ...

最新文章

  1. jquery封装插件
  2. Java5的 线程并发库
  3. 微电子学与计算机期刊投稿模板,微电子学与计算机投稿要求
  4. windows关闭svnserver_Windows停SVN服务的搭建和使用(二)-Win32Svn
  5. 2019沙雕失误瞬间!哈哈哈哈笑出猪叫...
  6. java xml 表达式语言_中级Java开发工程师笔试题
  7. 人脸检测三个算法比较
  8. Hibernate怎么提升数据库查询的性能 (1)
  9. CodeForces 48C D - The Race (Fraction,数学)
  10. Windows Server 2008 R2 Enterpris服务器上安装一个Moodle
  11. uni-app 小程序项目获取openid
  12. 解除excel打开密码
  13. cad渐开线齿轮轮廓绘制_CAD画齿轮的方法
  14. xshell个人免费版
  15. 爬虫学习笔记,从基础到部署。
  16. java script jsp_JSP和Java Script问题
  17. linux 不能开启443端口
  18. SPSS Statistics下载
  19. 多项式算法2:NTT(快速数论变换)
  20. 安排CCleaner系统清理

热门文章

  1. golang后端php前端,Golang如何接收前端的参数
  2. 作为技术人员,经常遇到没有接触过的技术,有时是点滴的小技能,有时可能是大的一个研究课题,那么我们如何进行技术研究呢?
  3. 乌班图安装pycharm
  4. 涉密专用服务器审计系统,国产专用服务器主机审计
  5. html js倒计时不准确,js倒计时代码:第2个倒计时为什么会不正常?
  6. java.util.list 报错_Java 报错 .updateValue' has an unsupported return type: interface java.util.List...
  7. navicat连接mysql报错ssh_Navicat 连接SSH方式连接mysql报错 ssh:expected key exchange group packet...
  8. centos7源码安装ntp_如何安装和配置 Chrony 作为 NTP 客户端?
  9. linux+tar+man,Linux常用命令
  10. D* Lite(D star lite) 算法 python