Apache Hive是一个开源的数据仓库系统,用于查询和分析大型数据集。Apache Hive中的数据可以分为以下三部分:
- 表
- 分区
- 桶
什么是Hive中的Bucketing?
Hive中的Bucketing是指将数据分解成不同的范围,也就是所谓的Bucket,为数据提供额外的结构,从而使其能够被用于更有效的查询。
为什么是 "桶"?
你已经看到,只有在分区数量有限的情况下,分区才会通过将HIVE表数据隔离到多个文件中而得到结果,如果对表进行分区会导致大量的分区。这就是 "桶 "的概念的来源。
当一个列的cardinality很高时,我们不能对它进行分区。非常多的分区将产生太多的Hadoop文件,这将增加节点的负载。这是因为节点将不得不保留每个分区的元数据,这将影响该节点的性能。
简单地说,如果你需要对有巨大数据的列运行查询,而这使得创建分区很困难的话,你可以使用Bucketing:

桶的作用是什么?
- 桶的概念是基于散列技术的。
- 当前列的值和所需的桶的数量的模块被计算出来(比方说,F(x) % 3)。
- 根据计算结果,将数据存储到相应的桶中。
- 具有相同桶状列的记录存储在同一桶内
- 这个函数要求你使用Clustered By子句将表划分为桶。

- Bucketing通过对表施加额外的结构来实现更有效的查询,下面是分区和Bucketing的文件结构的区别:

Hive桶的例子
Apache Hive支持桶状结构,正如这里所记录的。创建桶状列的步骤如下:
- 选择我们要创建表的数据库。
- 创建一个假表来存储数据。
- 将数据加载到表中。
- 在hive中启用bucketing
- 创建一个bucketing表
- 将假表的数据插入桶状表中。
use bucketdData;
create table emp_demo (Id int, Name string , Salary float)
row format delimited
fields terminated by ',' ;
load data local inpath '/home/codegyani/hive/emp_details' into table emp_demo;
set hive.enforce.bucketing = true;
create table emp_bucket(Id int, Name string , Salary float)
clustered by (Id) into 3 buckets
row format delimited
fields terminated by ',' ;
insert overwrite table emp_bucket select * from emp_demo;
在这里,我们可以看到,数据被分成了三个桶:

假设我们的桶中有以下数据:

根据哈希函数:
- 0号桶
6%3=0
3%3=0
所以,这些列被存储在 桶0里。
- 桶1
7%3=1
4%3=1
1%3=1
因此,这些列被存储在 桶1中。
Bucketed与非Bucketed查询性能对比
对于这个演示,我们将使用标准的tpc-ds表。大表的样本将是catalog_sales,store_sales,和store_returns。
主要是我们有三个用于查询的数据集:
- catalog_sales- 164 GB, 143 Million rows (Big)
- store_sales- 220 GB,28.7亿行(大)。
- store_returns- 25 GB, 2.87亿行 (中等)
下面的图表比较了作为桶状表与非桶状表查询访问的相同数据的三种不同变化。 查询1:Big-Medium表连接。这个查询在catalog_sales和store_returns表之间有一个连接。
查询2:连接2个大中型表。这个查询有一个2个连接。catalog_sales与store_returns连接,store_sales与store_returns连接。
查询3:两个大表的连接。这个查询在catalog_sales和store_sales表之间有一个连接。(是的,这个图形看起来不寻常。不,这不是一个错误。)

结论
蜂巢中的Bucketing对于优化前台和某些大数据集的连接是非常有用的。此外,蜂巢中的Bucketing对于带有Bucketing列和聚合的过滤器的查询来说更有效率。
希望这篇文章能帮助你了解蜂巢优化的基础知识。请继续关注即将发布的博客。