Fork me on GitHub

Hive的分区和分桶总结

目录

  • 背景
  • 第一部分 环境依赖
  • 第二部分 交互接口
  • 第三部分 任务提交
  • 参考文献及资料

背景

Hive将表划分为分区(partition)表和分桶(bucket)表。分区表在加载数据的时候可以指定加载某一部分数据,并不是全量的数据,可以让数据的部分查询变得更快。分桶表通常是在原始数据中加入一些额外的结构,这些结构可以用于高效的查询

https://data-flair.training/blogs/hive-partitioning-vs-bucketing/

https://blog.csdn.net/whdxjbw/article/details/82219022

第一部分 分区

第二部分 分桶

Hive分桶是相对分区进行更细粒度的划分。是将整个数据内容按照某列取hash值,对桶的个数取模的方式决定该条记录存放在哪个桶当中;具有相同hash值的数据进入到同一个文件中。如要安装name属性分为3个桶,就是对name属性值的hash值对3取摸,按照取模结果对数据分桶。如取模结果为0的数据记录存放到一个文件,取模为1的数据存放到一个文件,取模为2的数据存放到一个文件。

创建分桶表

在创建分桶表之前要执以下的命令,开启对分桶表的支持以及reduce个数

1
2
3
4
set hive.enforce.bucketing=true;

# 设置与桶相同的reduce个数(默认只有一个reduce)
set mapreduce.job.reduces=4;

创建分桶表

1
2
3
4
create table myhive1.user_buckets_demo(id int, name string)
clustered by(id)
into 4 buckets
row format delimited fields terminated by '\t';

如何向分桶表中导入数据

向分桶表中导入数据,不可以直接加载,需要先导入普通表,再导入分桶表中,这种和动态分区类似。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 创建普通表
create table user_demo(id int, name string)
row format delimited fields terminated by '\t';

# 准备数据文件 buckets.txt
cd /opt/module/hive-1.1.0-cdh5.14.2/data/test
vim user_bucket.txt

1 anzhulababy1
2 anzhulababy2
3 anzhulababy3
4 anzhulababy4
5 anzhulababy5
6 anzhulababy6
7 anzhulababy7
8 anzhulababy8
9 anzhulababy9
10 anzhulababy10

# 向普通标中导入数据
load data local inpath '/opt/module/hive-1.1.0-cdh5.14.2/data/test/user_bucket.txt' overwrite into table user_demo;

# 查看数据
select * from user_demo;

+---------------+-----------------+--+
| user_demo.id | user_demo.name |
+---------------+-----------------+--+
| 1 | anzhulababy1 |
| 2 | anzhulababy2 |
| 3 | anzhulababy3 |
| 4 | anzhulababy4 |
| 5 | anzhulababy5 |
| 6 | anzhulababy6 |
| 7 | anzhulababy7 |
| 8 | anzhulababy8 |
| 9 | anzhulababy9 |
| 10 | anzhulababy10 |
+---------------+-----------------+--+

# 加载数据到桶表user_buckets_demo中
insert into table user_buckets_demo select * from user_demo;

分桶表物理存储结构

分桶表表在hdfs上作为一个文件存在。

1
2
3
4
5
6
7
8
9
10
0: jdbc:hive2://node03:10000> dfs -ls /user/hive/warehouse/myhive1.db/user_buckets_demo;
+----------------------------------------------------+--+
| DFS Output |
+----------------------------------------------------+--+
| Found 4 items |
| -rwxr-xr-x 3 hadoop supergroup 30 2020-06-08 13:30 /user/hive/warehouse/myhive1.db/user_buckets_demo/000000_0 |
| -rwxr-xr-x 3 hadoop supergroup 45 2020-06-08 13:30 /user/hive/warehouse/myhive1.db/user_buckets_demo/000001_0 |
| -rwxr-xr-x 3 hadoop supergroup 47 2020-06-08 13:30 /user/hive/warehouse/myhive1.db/user_buckets_demo/000002_0 |
| -rwxr-xr-x 3 hadoop supergroup 30 2020-06-08 13:30 /user/hive/warehouse/myhive1.db/user_buckets_demo/000003_0 |
+----------------------------------------------------+--+

分桶表使用场景

  • 取样sampling更高效。没有分桶的话需要扫描整个数据集。
  • 提升某些查询操作效率,例如map side join

如何抽样查询桶表的数据

tablesample抽样语句语法:tablesample(bucket x out of y)

  • x表示从第几个桶开始取数据
  • y与进行采样的桶数的个数、每个采样桶的采样比例有关
1
2
3
4
select * from user_buckets_demo tablesample(bucket 1 out of 2);
-- 需要采样的总桶数=4/2=2
-- 先从第1个桶中取出数据
-- 1+2=3,再从第3个桶中取出数据

第三部分

参考文献及资料

1、

0%