hive中的join操作及其数据倾斜
join操作是一个大数据领域一个常见的话题。归根结底是由于在数据量超大的情况下,join操作会使内存占用飙升。运算的复杂度也随之上升。在进行join操作时,也会更容易发生数据倾斜。这些都是需要考虑的问题。
过去了解到很多关于join操作的知识点,特此总结一下。
join操作可以分为三类:小表join小表、大表join小表、大表join大表
其中小表join小表是不需要考虑的,不会存在内存溢出,也不会因为数据倾斜导致查询缓慢。
一、大表join小表
大表join小表的解决方法也相对简单,那就是map-side-join。
所谓map-said-join就是将小表直接长期驻留在内存中,在map端完成join操作。
hive通过如下配置开启map-said-join:
SET hive.auto.convert.join=true;SET hive.mapjoin.smalltable.filesize=25000000;
其中,
hive.auto.convert.join
参数表示是否自动转换为mapjoin,
hive.mapjoin.smalltable.filesize
参数表示小表的大小阈值。如果小表的大小超过这个阈值,那么Hive将不会自动转换为mapjoin。
编写带有join操作的sql语句时要将小表放在join语句的右边,如下:
SELECT/*+MAPJOIN(small_table)*/
large_table.col1, small_table.col2
FROM
large_table JOIN small_table
ON
large_table.key= small_table.key;
二、大表join大表
大表join大表最常用的方法是bucket-map-join,即将大表拆分成小表,小表再做join操作。
所谓bucket-map-join就是将两个要进行join操作的表的join key上做hash bucket,将两张大表分成多张小表。join key经过hash后的值相同就分到同一个表中,此时只需要将hash相同的bucket进行join操作即可。需要注意的是,两个大表中较大的那个表所得出的hash bucket个数应该是较小的表所得出的hash bucket个数的整数倍。
各个小表依然复制到大表所在的map进行mapjoin
实现bucket-map-join的条件
1.启动bucket-map-join,set hive.optimize.bucketmapjoin = true;
2.一个表的bucket数是另一个表bucket数的整数倍
3.bucket列就是join key所在的列
4.必须是应用在map-join场景中
另一种大表join大表常用的方法是SMB join(Sort Merge Bucket Join)
SMB join相比于bucket-map-join而言多了两个限制条件:
1.要求必须有序
2.要求两个大表所生成的bucket数必须相同
下表给出两者对比:
bucket map joinSMB joinset hive.optimize.bucketmapjoin = true;set hive.optimize.bucketmapjoin = true;set hive.auto.convert.sortmerge.join=true;set hive.optimize.bucketmapjoin.sortedmerge = true;set hive.auto.convert.sortmerge.join.noconditionaltask=true;一个表的bucket数是另一个表bucket数的整数倍两个表的bucket数必须相同bucket列 == join列bucket列 == join列必须是应用在map join的场景中必须是应用在bucket map join 的场景中
需要注意的是,用户需要自己保证SMB join时数据的有序。如果不是有序的,会导致结果出错。
1.hive.enforce.sorting设置为true。开启强制排序时,插数据到表中会进行强制排序,默认false
2.插入数据时可以在sql中使用distributed c1 sort by c1 或者cluster by c1
另外,表创建时必须时CLUSTERED且SORTED,如下:
createtable test_smb_2(mid string,age_id string)CLUSTEREDBY(mid) SORTED BY(mid)INTO500 BUCKETS;
三、join操作中的数据倾斜
如果在join操作的过程中发生数据倾斜,那么就需要采用skew join来解决
skew join的打开方式:
#运行时set hive.optimize.skewjoin=true;#编译期set hive.optimize.skewjoin.compiletime=true;#开启union优化set hive.optimize.union.remove=true;
skew join对于数据倾斜的解决方案就是单独开一个新的job,并对发生倾斜的数据进行map join。两个任务完成后使用union将结果进行拼接。
版权归原作者 时代新人0-0 所有, 如有侵权,请联系我们删除。