文章目录
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上的目录,桶表对应是目录里的文件