Hive系列(三)Hive分区后数据仍划分不均??Hive分桶教你怎么解决

Hive分桶:-Buckets

一:为什么要分桶?:–对数据的垂直切分解决方案

问这个前提是因为我们已经有分区了,为什么又分桶呢?

分区提供了一个隔离数据优化查询的便利方式,不过并非所有的数据都可形成合理的分区,尤其是需要确定合适大小的分区划分方式。

(总会有有的数据分区划分方式不合理,且没有更好的划分区的特征名了,可能导致有的分区数据过多,而某些分区没有什么数据的尴尬情况)

分桶是将数据集分解为更容易管理更细粒度划分的另一种技术。

二:分桶有什么用?:

  • 更高的查询处理效率(join)----(实际使用还没有感受这么深刻)

    Hive 在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的实现。比如JOIN操作。对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。

  • 使抽样(sampling)更高效

三:分桶遵循什么原理?

跟MR的HashPartitioner原理一样

  • MR是通过key的hash值 / 设置reduceTask的个数 来取模获取分区
  • Hive按照分桶字段的hash值 / 设置的分桶的个数 来取模获取分桶

当我们分区之后若是列值的区域还不够细分,我们将在分区的基础上,对列值再次进行分桶,通过对列值做Hash,然后除以设置的桶的个数求余来决定哪条记录存放在哪个桶里。

四:怎么分桶?:

第一步:创建分桶表:

create table xxx(
	employee string
)
clustered by (employee_id) into 2 buckets

注意点:

  • 分桶列必须是表中已有列,而分区不用

  • 分桶数是2的n次方

    因为分桶底层是hash表,取模操作太慢,我们是直接二进制与操作,当是2的n次方时,它与哈希值的与操作,对于存储数组在哪个下标的位置的控制权才能全权交给hash值得二进制来控制,并且刚好将hash值映射数组下标范围,没有超出。

  • 直接分文件,不是分文件夹

    • 分桶将表中的数据拆分到不同的文件中,解耦操作

    在这里插入图片描述

    • 分区将表中的数据逻辑化分到不同文件夹(区域)中

第二步:设置分桶规则:

因为分桶与MR的partition异曲同工,最后产生的文件数是由taskReduce来决定的,所以最后的reduce数量最好一定要和逻辑划分的分桶数量相等,不然可能出现一个reduce处理多个桶,导致产生的文件里有多个桶的数据。

-- 设置严格分桶模式
set hive.strict.checks.bucketing = true;
-- 开启强制分桶模式,会将reduce数量变成分桶的数量个数
set hive.enforce.bucketing=true;

第三步:必须用insert方式加载数据:(除非你把严格分桶模式关闭)

# 导表时一定要注意,导的表与目的地表的列名一致
insert into table xxx select employee_id from yyy;

五:都是为了提高查找效率,索引和分桶和分区?

索引和分区最大的区别就是索引不分割数据库,分区分割数据库。

索引其实就是拿额外的存储空间换查询时间,但分区已经将整个大数据库按照分区列拆分成多个小数据库了。

分区和分桶最大的区别就是分桶随机分割数据库,分区是非随机分割数据库。

因为分桶是按照列的哈希函数进行分割的,相对比较平均;而分区是按照列的值来进行分割的,容易造成数据倾斜。

其次两者的另一个区别就是分桶是对应不同的文件(细粒度),分区是对应不同的文件夹(粗粒度)。

注意:普通表(外部表、内部表)、分区表这三个都是对应HDFS上的目录,桶表对应是目录里的文件

猜你喜欢

转载自blog.csdn.net/qq_35050438/article/details/106817385
今日推荐