精选文章 hive join的优化

hive join的优化

作者:我叫周利东 时间: 2019-11-07 06:01:40
我叫周利东 2019-11-07 06:01:40

Common Join

最为普通的join策略,不受数据量的大小影响,也可以叫做reduce side join ,最没效率的一种join 方式. 它由一个mapreduce job
完成.

首先将大表和小表分别进行map 操作, 在map shuffle 的阶段每一个map output key 变成了table_name_tag_prefix + join_column_value , 但是在进行partition 的时候它仍然只使用join_column_value
进行hash.

每一个reduce 接受所有的map 传过来的split , 在reducce 的shuffle 阶段,它将map output key 前面的table_name_tag_prefix 给舍弃掉进行比较. 因为reduce 的个数可以由小表的大小进行决定,所以对于每一个节点的reduce 一定可以将小表的split 放入内存变成hashtable.
然后将大表的每一条记录进行一条一条的比较.

 

Map Join

Map Join 的计算步骤分两步,将小表的数据变成hashtable广播到所有的map 端,将大表的数据进行合理的切分,然后在map 阶段的时候用大表的数据一行一行的去探测(probe)
小表的hashtable. 如果join key 相等,就写入HDFS.

map join 之所以叫做map join 是因为它所有的工作都在map 端进行计算.

hive 在map join 上做了几个优化:

  • hive 0.6 的时候默认认为写在select 后面的是大表,前面的是小表, 或者使用 /*+mapjoin(map_table) */ 提示进行设定. hive
    0.7 的时候这个计算是自动化的,它首先会自动判断哪个是小表,哪个是大表,这个参数由(hive.auto.convert.join=true)来控制. 然后控制小表的大小由(hive.smalltable.filesize=25000000L)参数控制(默认是25M),当小表超过这个大小,hive 会默认转化成common join.
    你可以查看HIVE-1642.
  • 首先小表的Map 阶段它会将自己转化成MapReduce Local Task ,然后从HDFS 取小表的所有数据,将自己转化成Hashtable file 并压缩打包放入DistributedCache 里面.

     

    目前hive 的map join 有几个限制,一个是它打算用BloomFilter 来实现hashtable , BloomFilter 大概比hashtable
    省8-10倍的内存, 但是BloomFilter 的大小比较难控制.

    现在DistributedCache 里面hashtable默认的复制是3份,对于一个有1000个map 的大表来说,这个数字太小,大多数map 操作都等着DistributedCache 复制.

     

    Bucket Map Join

    hive 建表的时候支持hash 分区通过指定clustered by (col_name,xxx ) into number_buckets buckets 关键字.

    当连接的两个表的join key 就是bucket column 的时候,就可以通过

    hive.optimize.bucketmapjoin= true

    来控制hive 执行bucket map join 了, 需要注意的是你的小表的number_buckets 必须是大表的倍数.
    无论多少个表进行连接这个条件都必须满足.(其实如果都按照2的指数倍来分bucket, 大表也可以是小表的倍数,不过这中间需要多计算一次,对int 有效,long 和string 不清楚)

    Bucket Map Join 执行计划分两步,第一步先将小表做map 操作变成hashtable 然后广播到所有大表的map端,大表的map端接受了number_buckets 个小表的hashtable并不需要合成一个大的hashtable,直接可以进行map
    操作,map 操作会产生number_buckets 个split,每个split 的标记跟小表的hashtable 标记是一样的, 在执行projection 操作的时候,只需要将小表的一个hashtable 放入内存即可,然后将大表的对应的split
    拿出来进行判断,所以其内存限制为小表中最大的那个hashtable 的大小.

    Bucket Map Join 同时也是Map Side Join 的一种实现,所有计算都在Map 端完成,没有Reduce 的都被叫做Map Side Join ,Bucket
    只是hive 的一种hash partition 的实现,另外一种当然是值分区.

    create table a  (xxx) partition by (col_name)

    不过一般hive 中两个表不一定会有同一个partition key, 即使有也不一定会是join key. 所以hive 没有这种基于值的map side join,
    hive 中的list partition 主要是用来过滤数据的而不是分区. 两个主要参数为(hive.optimize.cp = true 和 hive.optimize.pruner=true)

    hadoop 源代码中默认提供map side join 的实现, 你可以在hadoop 源码的src/contrib/data_join/src 目录下找到相关的几个类.  其中TaggedMapOutput 即可以用来实现hash 也可以实现list , 看你自己决定怎么分区. Hadoop Definitive Guide 第8章关于map side join 和side
    data distribution 章节也有一个例子示例怎样实现值分区的map side join.

     

    Sort Merge Bucket Map Join

    Bucket Map Join 并没有解决map join 在小表必须完全装载进内存的限制, 如果想要在一个reduce 节点的大表和小表都不用装载进内存,必须使两个表都在join key
    上有序才行,你可以在建表的时候就指定sorted byjoin key 或者使用index 的方式.

    set hive.optimize.bucketmapjoin = true;

    set hive.optimize.bucketmapjoin.sortedmerge = true;

    set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;

    Bucket columns == Join columns == sort columns

    这样小表的数据可以每次只读取一部分,然后还是用大表一行一行的去匹配,这样的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个字节)

     

    Left Semi Join

    hive 中没有in/exist 这样的子句,所以需要将这种类型的子句转成left semi join. left semi join 是只传递表的join key给map 阶段 , 如果key 足够小还是执行map join,
    如果不是则还是common join.

     

     

    join 策略中的难点

    大多数只适合等值连接(equal join) ,

    范围比较和全外连接没有合适的支持

    提前分区,零时分区,排序,多种不同执行计划很难评价最优方案.

    没有考虑IO 比如临时表,网络消耗和网络延迟时间,CPU时间,

    最优的方案不代表系统资源消耗最少.

勿删,copyright占位
分享文章到微博
分享文章到朋友圈

上一篇:11.7课堂练习 5.4共享变量

下一篇:防SQL攻击(1) : springboot定义切面过滤请求参数

您可能感兴趣

  • B 站疯传,堪称最强,一整套数据分析课程,学完月薪30K+!

    2020魔幻之年,疫情下就业大受影响,很多岗位缩招,而数据分析相关工作岗位恋习Python(如数据分析师、数据挖掘师等岗位)却在增加。非专业数据分析岗位(如运营、市场、销售等岗位)也要求“数据分析”能力。大数据时代的未来,数据分析将是每个岗位的必备技能。 很多人知道数据分析非常重要,下载了一些资料,却觉得无从下手,很难学。为你推荐奈学教育精心打造的“全栈大数据分析师”课程, 本课通过多业务场...

  • 8.deltalake的merge四个案例场景

    本文主要是讲merge操作的四个案例。 1.数据去重 实际上,线上业务很多时候数据源在上报数据的时候,由于各种原因可能会重复上报数据,这就会导致数据重复,使用merge函数可以避免插入重复的数据。具体操作方法如下: sql MERGE INTO logsUSING newDedupedLogsON logs.uniqueId = newDedupedLogs.uniqueIdWHEN NOT...

  • 并行循环和嵌套循环_并行嵌套循环连接–嵌套循环连接和残留谓词的内侧

    并行循环和嵌套循环 This article is the second part of the Nested Loop Join Series. In the first part, Introduction of Nested Loop Join, we gave a brief introduction to Native, Indexed and Temporary Index Ne...

  • MySQL:互联网公司常用分库分表方案汇总

    点击上方 IT牧场 ,选择 置顶或者星标 技术干货每日送达! 作者:尜尜人物 cnblogs.com/littlecharacter/p/9342129.html 本文目录 一、数据库瓶颈 IO瓶颈 CPU瓶颈 二、分库分表 水平分库 水平分表 垂直分库 垂直分表 三、分库分表工具 四、分库分表步骤 五、分库分表问题 非partition key的查询问题 非partition key跨库跨...

  • 零编码制作报表可能吗?

    要回答这个问题,首先要明确啥程度算“零编码”? 以 Excel 为例,如果把写 Excel 公式(包括复杂一些的)看做零编码;而把写 Excel VBA 看做编码的话, 报表开发是可以零编码的! 但是,这有个前提:在数据(集)准备好的情况下才可以零编码! 为什么这么说? 我们知道报表开发主要分两个阶段: 第一阶段是为报表准备数据,也就是把原始数据通过 SQL/ 存储过程加工成数据集; 第二阶...

  • JAVA面试(全)

    Java 八大基本数据类型 八大基本类型 Byte,short,long,int,double,float,boolean,char 占用大小及其长度 数据类型 空间(字节B) 取值范围 byte 1 -2^7 ~ 2^7-1 short 2 -2^15~ 2^15-1 char 2 0 ~ 2^16-1 char无需符号位 int 4 -2^31 ~ 2^31-1 float 4 -2^3...

  • Hive库更新UDF步骤说明

    Hive 2.1.1 +cdh6.2.0 库更新UDF步骤说明 共有三种更新UDF的方式,整理如下: 名称 是否需要重启hive服务 Jar保存位置 是否支持 Sentry 适用场景 直接JAR配置 需要 Hdfs 不支持 开发场景 辅助JARs目录配置 需要 本地目录 不支持 防止意外覆盖文件的场景 可重载的辅助JAR配置 不需要 本地目录 支持 频繁更改UDF场景 选择“直接JAR配置”...

  • 你在滥用Python吗?初学者常会遇到的5个情景

    Python拥有众多学习者,可谓是如今许多编程初学者的首选语言。易学的语法、丰富的库和大量的社区都是Python飞速发展的主要原因。 6年前,在我掌握了一系列 Java 之后接触到Python时,经常发现自己在写Python代码时脑子里还想着Java。作为一个新手,我没有充分利用Python的优点,甚至在某些情况下,我滥用了它。 现在,我仍然看到一些初学者在没有先花时间阅读最佳实践和建议的情...

华为云40多款云服务产品0元试用活动

免费套餐,马上领取!
CSDN

CSDN

中国开发者社区CSDN (Chinese Software Developer Network) 创立于1999年,致力为中国开发者提供知识传播、在线学习、职业发展等全生命周期服务。