hive分桶

分桶
单个分区或者表中的数据越来越大,分区不能细粒度的划分数据时,可以采用分桶去实现,
分桶是将数据集分解为更容易管理的若干部分的另一种技术

分桶的技术:
CLUSTERED BY (col_name, col_name, …)
[SORTED BY (col_name [ASC|DESC], …)] INTO num_buckets BUCKETS]

分桶的原理
跟MR的hashpartitioner是一样的
MR中:key的hash值模上reduce数量
hive中:按照分桶字段的hash值模上分桶的个数
hive也是针对某一列进行桶的组织,hive采用对列值进行hash,然后模上分桶的个数求余数决定记录存放在哪儿个桶中

分桶的意义
1、为了保存分桶查询的分桶结构(数据已经按照分桶字段进行了hash散列)
2、分桶表进行抽样和join操作时可以提高MR的查询效率

分桶的操作
create table t_stu(
sno int,
sname string,
sex string,
sage int,
sdept string
)
row format delimited
fields terminated by ‘,’
stored as textfile
;

load data local inpath ‘/data/students.txt’ into table t_stu;

分桶查询
select * from t_stu;

select * from t_stu cluster by (sno);

set mapreduce.job.reduces=4;

select * from t_stu cluster by (sno); 负责分区还负责排序,排序字段就是分区字段

select * from t_stu distribute by (sno) sort by (sage desc); 指定分区字段和排序字段,排序字段可和分区字段不一致,排序规则还可以指定

创建分桶表并加载数据
create table if not exists buc1(
sno int,
sname string,
sex string,
sage int,
sdept string
)
clustered by (sno) sorted by (sage desc) into 4 buckets
row format delimited
fields terminated by ‘,’
stored as textfile
;

使用load的方式进行加载数据(load方式加载数据不能体现分桶的结果)
load data local inpath ‘/data/students.txt’ into table buc1;

分桶表数据的加载
第一步:要在hive中创建一个临时表,将数据导入临时表中
第二步:通过对临时表查询的方式完成数据导入,分桶的实现就是对分桶的字段做了hash然后存放到对应的文件中,也就是说向分通表中插入数据的时候
必然要执行一次MR,这也就是为什么分桶表的数据基本上只能通过从结果集的查询插入方式导入

创建表
create table if not exists buc2(
sno int,
sname string,
sex string,
sage int,
sdept string
)
clustered by (sno) sorted by (sage desc) into 4 buckets
row format delimited
fields terminated by ‘,’
stored as textfile
;

加载数据(要注意reduce数量的设置与分桶数量一致) set mapreduce.job.reduces=4;
insert into table buc2
select * from t_stu
cluster by (sno)
;

现在设置reduce的数量与分桶的数量不一致
set mapreduce.job.reduces=3;

insert overwrite table buc2
select * from t_stu
cluster by (sno)
;
实际上数据分了3个桶,与表的设计不相符

解决办法
set hive.enforce.bucketing=true;(建议开启)
或者
设置reduce的数量和分桶数量一致
虽然开启了强制分桶,reduce数量与分桶数量不一致不影响分桶结果,但是
会导致效率问题,建议手动设置reduce数量与分桶数量一致

表的设计虽然年龄的排序按照降序排序,这只是一种美好的愿望
这种的实现还需要写sql的人去实现
首先保证分桶正确,即要set hive.enforce.bucketing=true;
或者设置reduce的数量和分桶数量一致
然后我们可以强制开启排序
set hive.enforce.sorting=true;
或者使用其他sql的实现

使用其他sql的实现
set mapreduce.job.reduces=4;
创建表
create table if not exists buc3(
sno int,
sname string,
sex string,
sage int,
sdept string
)
clustered by (sno) sorted by (sage desc) into 4 buckets
row format delimited
fields terminated by ‘,’
stored as textfile
;

加载数据
insert overwrite table buc3
select * from t_stu
distribute by (sno) sort by (sage desc)

select * from buc3;

要保证有序,reduce数量必须和分桶数量一致
可以使用set hive.enforce.sorting=true;
insert overwrite table buc2
select * from t_stu
cluster by (sno)
;
这种实现也保证数据是有序的

分桶的查询
查询全部
select * from buc3;
select * from buc3 tablesample(bucket 1 out of 1);

查询第一桶
select * from buc3 tablesample(bucket 1 out of 4);

select * from buc3 tablesample(bucket 1 out of 2);
select * from buc3 tablesample(bucket 1 out of 8);
select * from buc3 tablesample(bucket 1 out of 5);

分桶查询的计算
不压缩不拉伸
for 1-4
1 2 3 4

压缩
1 2 3 4

x:起始位置,s是总桶数(真实存在的),y是压缩后的桶数,n表示取的次数
x+(s/y)(n-1)

拉伸时:
相当于重新分区,第一桶就是分桶字段的hash值模上总桶数余数为0的数据

查询sno为奇数的数据
select * from buc3 tablesample (bucket 2 out of 2);
还可以有条件限制
select * from buc3 tablesample (bucket 1 out of 2) where sage<20;

注意:tablesample一定要紧跟在表名之后
select * from buc3 where sage<20 tablesample (bucket 1 out of 2); ##报错

查询前三行数据
select * from buc3 limit3;
查询前三行数据
select * from buc3 tablesample(3 rows);

select * from buc3 tablesample(20 percent);//查询20%的数据

select * from buc3 tablesample(20k);//查询一定大小的数据 B,K,M,G,T,P
0.8-1.5K,600G,一天会有多少条数据,波峰达到每小时多少数据,波谷每小时多少数据

要求随机抽取三行数据
select *,rand() from buc3;
select * from buc3 order by rand() limit 3;

本地模式(hive优化中的一种)
set hive.exec.mode.local.auto=true;
设置严格模式(hive优化中的一种)
分区
分桶

分桶的总结
1、定义clustered by(sno) 指定分桶字段
sorted by (sage desc) 指定数据的排序字段以及排序规则,
表示预期的数据就是以这里设置的字段进行排序
2、导数据clustered by(sno) 指定getpartitioner以哪儿个字段进行hash散列,并且排序的字段也是该字段,排序规则默认是正序排序
distribute by (sno) 指定以哪儿个字段进行hash散列
sorted by (sage desc) 指定数据的排序字段以及排序规则

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值