码迷,mamicode.com
首页 > 其他好文 > 详细

Hive桶表

时间:2015-08-17 23:16:32      阅读:502      评论:0      收藏:0      [点我收藏+]

标签:

桶(bucket)是指将表或分区中指定列的值为key进行hash,hash到指定的桶中,这样可以支持高效采样工作。

抽样(sampling)可以在全体数据上进行采样,这样效率自然就低,它还是要去访问所有数据。而如果一个表已经对某一列制作了bucket,就可以采样所有桶中指定序号的某个桶,这就减少了访问量。

针对桶的操作,总共有四步:

1).开启桶的服务

    Hive > set hive.enforce.buketing=true;

2).创建桶表

首先,我们来看如何告诉Hive—个表应该被划分成桶。我们使用 Clustered By 子句来指定划分桶所用的列和划分的桶的个数。桶中的数据可以根据一个或多个列进行排序sorted by。由于这样对每个桶的连接变成了高效的归并排序(merge-sort),因此可以进一步提升map端连接的效率。

Hive > create table bucketed_user(id int ,name string) clustered by (id) sorted by(name) into 4 buckets row format delimited fields terminated by ‘\t‘ stored as textfile;

3).导入数据

物理上,每个桶是数据表(或分区)目录里的一个文件。它的文件名并不重要,但是桶n 是按照字典序排列的第 n 个文件。事实上,桶对应于MR的输出文件分区:一个作业产生的桶(输出文件)和reduce任务个数相同。

Hive > INSERT OVERWRITE TABLE bucketed_users SELECT * FROM users;

4).检查数据情况

我们可以通过查看刚才创建的bucketd_users表的布局来了解这一情况。运行如下命令:

Hive > dfs –ls /user/hive/warehouse/ bucketed_users;

将显示有4个新建的文件。文件名如下(文件名包含时间戳,由Hive产生,因此每次运行都会改变): 

attempt_201005221636_0016_r_000000_0 

attempt_201005221636_0016_r_000001_0 

attempt_201005221636_0016_r_000002_0 

attempt_201005221636_0016_r_000003_0 

5).查看桶中的数据,输入如下指令

Hive > dfs –cat /user/hive/warehouse/ bucketed_users /*;

6).桶中的数据进行采样

TableSample子句对表进行取样,我们可以获得相同的结果。这个子句会将查询限定在表的一部分桶内,而不是使用整个表:

hive> SELECT * FROM bucketed_users TABLESAMPLE(BUCKET 1 OUT OF 4 ON id);

对于一个大规模的、均匀分布的数据集,这会返回表中约四分之一的数据行。

我们也可以用其他比例对若干个桶进行取样(因为取样并不是一个精确的操作,因此这个比例不一定要是桶数的整数倍)。

因为查询只需要读取和TABLESAMPLE子句匹配的桶,所以取样分桶表是非常高效的操作。如果使用rand()函数对没有划分成桶的表进行取样,即使只需要读取很小一部分样本,也要扫描整个输入数据集:

Hive > SELECT * FROM users TABLESAMPLE (BUCKET 1 OUT OF 4 ON rand( ) );

1).设置环境变量

set hive.enforce.bucketing = true;

2).创建桶表

使用 Clustered By 子句来指定划分桶所用的列和划分的桶的个数。桶中的数据可以根据一个或多个列进行排序sorted by由于这样对每个桶的连接变成了高效的归并排序(merge-sort),因此可以进一步提升map端连接的效率。

 

hive> create table student0(id INT, age INT, name STRING)
    > partitioned by(stat_date STRING)
    > clustered by(id) sorted by(age) into 2 buckets
    > row format delimited fields terminated by ,; 
OK
Time taken: 0.292 seconds
hive> create table student1(id INT, age INT, name STRING) 
    > partitioned by(stat_date STRING) 
    > clustered by(id) sorted by(age) into 2 buckets 
    > row format delimited fields terminated by ,;
OK
Time taken: 0.215 seconds

3).插入数据 

[root@hadoop01 hive]# more bucket.txt
1,20,zxm
2,21,ljz
3,19,cds
4,18,mac
5,22,android
6,23,symbian
7,25,wp
hive> LOAD data local INPATH /root/hive/bucket.txt 
    > OVERWRITE INTO TABLE student0                  
    > partition(stat_date="20120802");
hive> from student0                                                   
    > insert overwrite table student1 partition(stat_date="20120802") 
    > select id,age,name where stat_date="20120802"                   
    > sort by age;

4).查看文件目录

hive> dfs -ls /user/hive/warehouse/student1/stat_date=20120802;
Found 2 items
-rw-r--r--   1 root supergroup         31 2015-08-17 21:23 /user/hive/warehouse/student1/stat_date=20120802/000000_0
-rw-r--r--   1 root supergroup         39 2015-08-17 21:23 /user/hive/warehouse/student1/stat_date=20120802/000001_0

5).查看tablesample数据

hive> select * from student1                     
    > TableSample(bucket 1 out of 2 on id); 
OK
6       23      symbian 20120802
2       21      ljz     20120802
4       18      mac     20120802
Time taken: 10.871 seconds, Fetched: 3 row(s)

注:tablesample是抽样语句,语法:TABLESAMPLE(BUCKET x OUT OF y)

y必须是table总bucket数的倍数或者因子。hive根据y的大小,决定抽样的比例。例如,table总共分了64份,当y=32时,抽取(64/32=)2个bucket的数据,当y=128时,抽取(64/128=)1/2个bucket的数据(此例子就是1)。

x表示从哪个bucket开始抽取。例如,table总bucket数为32,tablesample(bucket 3 out of 16),表示总共抽取(32/16=)2个bucket的数据,分别为第3个bucket和第(3+16=)19个bucket的数据。

Hive桶表

标签:

原文地址:http://www.cnblogs.com/skyl/p/4737847.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!