• 微信公众号:美女很有趣。 工作之余,放松一下,关注即送10G+美女照片!

Hive的分桶表

开发技术 开发技术 3小时前 2次浏览

【分桶概述】

  Hive表分区的实质是分目录(将超大表的数据按指定标准细分到指定目录),且分区的字段不属于Hive表中存在的字段;分桶的实质是分文件(将超大文件的数据按指定标准细分到分桶文件),且分桶的字段必须在Hive表中存在。

 
  分桶的意义在于:
    1. 可以提高多表join的效率(因为通过分桶已经将超大数据集提取出来了。假如原数据被分了4个桶,此时2表join的时候只需要读取符合条件的一个分桶,则理论上效率可提升4倍)
    2. 加速数据抽样的效率(理由同上,只需要按照指定规则抽取指定分桶的数据即可,不需要扫描全表)
 
  需要Hive表分桶的时候,我们可以观察到Reduce的任务数量 = 分桶的数量,也就是最终产生的分桶文件的个数,因为分桶表就是通过MapReduce任务计算而来。由此可见,其实桶的概念就是MapReduce的分区的概念,两者完全相同。
  需要注意的是,不论每次插入分桶表的数据量有多少,对应分桶里面是否需要写入新的数据,Reduce总会启动分桶数量那么多的task去计算,故可能产生许多空白文件(原因是reduce写的时候,不知道会不会有数据需要输出,所以默认初始化了一个文件)。
  为了避免产生大量空白文件,给namenode增加无谓的压力,我们可以通过以下设置方法告知reduce作业不要产生空白文件:
//导入jar包
import org.apache.hadoop.mapreduce.lib.output.LazyOutputFormat;
//使用LazyOutputFormat
LazyOutputFormat.setOutputFormatClass(job, TextOutputFormat.class);

 

  分桶表取样语法的核心:

select * from tableName tablesample(bucket x out of y on colum)。其中:
x:表示从第x个桶中抽取数据
y:表示每y个桶中抽取一次数据(必须是分桶数量的倍数 or 因子)

 

【用法简介】

1.开启支持分桶

set hive.enforce.bucketing=true;    -- 默认:false --

  设置为 true 之后,mr 运行时会根据 bucket 的个数自动分配 reduce task的个数。

  当然,用户也可以通过 mapred.reduce.tasks 自己设置 reduce 任务个数,但分桶时不推荐使用。注意:一次作业产生的桶(文件数量)和 reduce task 个数一致)

 

2.往分桶表中加载数据

/* 往分桶表中插入数据的语法类似下面 */
insert into table bucket_table select columns from tbl;    -- 全新插入 --

insert overwrite table bucket_table select columns from tbl;    -- 覆盖重写 --

 

3.分桶表数据抽样

/*
抽样语法:TABLESAMPLE(BUCKET x OUT OF y)。其中:
x:表示从第x个桶中抽取数据
y:表示每y个桶中抽取一次数据(必须是分桶数量的倍数 or 因子)
*/
select * from bucket_table tablesample(bucket 1 out of 4 on columns);

 

【用法举例】

1. 假设本地文件 /root/hivedata/ft 中有以下内容:

zhang   12
lisi    34
wange   23
zhouyu  15
guoji   45
xiafen  48
yanggu  78
liuwu   41
zhuto   66
madan   71
sichua  89

 

2. 新建Hive常规表并导入本地文件:

hive> CREATE TABLE ft( id INT, name STRING, age INT)
      > ROW FORMAT DELIMITED FIELDS TERMINATED BY't';
OK
Time taken: 0.216 seconds

hive> load data local inpath'/root/hivedata/ft' into table ft;
Loading data to table hehe.ft
Table hehe.ft stats: [numFiles=1, totalSize=127]
OK
Time taken: 1.105 seconds

hive> select *from ft;
OK
1    zhang    12
2    lisi    34
3    wange    23
4    zhouyu    15
5    guoji    45
6    xiafen    48
7    yanggu    78
8    liuwu    41
9    zhuto    66
10    madan    71
11    sichua    89
NULL    NULL    NULL
Time taken: 0.229 seconds, Fetched: 12 row(s)

 

3. 创建分桶表:

hive> create table fentong(
    > id  int,
    > name string,
    > age int,)clustered by(age) into 4 buckets        -- 以字段age来划分成4个桶 --
    > row format delimited fields terminated by ',';

  每行数据具体落入几号分桶的规则如下:

    1. 用表中指定的字段值(比如age)来除以桶的个数4;
    2. 结果取余数,也就是求模(若余数为0就放到1号桶,余数为1就放到2号桶,余数为2就放到3号桶,余数为3就放到4号桶)

 

4. 给分桶表导入数据:

hive> insert into table fentong select name,age from ft;

 

5. 查询分桶表数据以确认正确导入:

hive> select * from  fentong

 

6. 我们来看看分桶表的数据如何使用:

hive> select id, name, age from fentong tablesample(bucket 1 out of 4 on age);
OK
NULL    NULL    NULL
6    xiafen    48
1    zhang    12

hive> select id, name, age from fentong tablesample(bucket 2 out of 4 on age);
OK
11    sichua    89
8    liuwu    41
5    guoji            45

hive> select id, name, age from fentong tablesample(bucket 3 out of 4 on age);
OK
9    zhuto    66
7    yanggu    78
2    lisi    34

 

 


程序员灯塔
转载请注明原文链接:Hive的分桶表
喜欢 (0)