美文网首页
Hive 分桶详解

Hive 分桶详解

作者: 博弈史密斯 | 来源:发表于2018-12-24 16:33 被阅读0次

    1分桶

    1.1什么是分桶?和分区有什么区别?

    分区:Hive在查询数据的时候,一般会扫描整个表的数据,会消耗很多不必要的时间。有些时候,我们只需要关心一部分数据,比如WHERE子句的查询条件,那这时候这种全表扫描的方式是很影响性能的。从而引入了分区的概念。分区就是对数据进行分类,这样在查询的时候,就可以只是针对分区查询,从而不必全表扫描。

    一个目录对应一个分区

    分桶:并非所有的数据集都可形成合理的分区,特别之前所提到过的要确定合适的划分大小的疑虑。对于每一个表或者分区,可以进一步细分成桶,桶是对数据进行更细粒度的划分。Hive默认采用对某一列的每个数据进行hash(哈希),使用hashcode对 桶的个数求余,确定该条记录放入哪个桶中。

    分桶实际上和 MapReduce中的分区是一样的。分桶数和reduce数对应。

    一个文件对应一个分桶

    1.2如何创建一个分桶?

    1.2.1 语法格式

    CREATE [EXTERNAL] TABLE <table_name>

    (<col_name> <data_type> [, <col_name> <data_type> ...])]

    [PARTITIONED BY ...]

    CLUSTERED BY (<col_name>)

    [SORTED BY (<col_name> [ASC|DESC] [, <col_name> [ASC|DESC]...])]

    INTO <num_buckets> BUCKETS

    • CLUSTERED BY (<col_name>):以哪一列进行分桶

    • SORTED BY (<col_name> [ASC|DESC]:对分桶内的数据进行排序

    • INTO <num_buckets> BUCKETS:分成几个桶

    具体解释:

    只能对一列进行分桶。表可以同时分区和分桶,当表分区时,每个分区下都会有<num_buckets> 个桶。当使用 SORTED BY … 在桶内排序时,指定排序的列和指定分桶的列无需相同。ASC 为升序选项,DESC 为降序选项,默认排序方式是升序。<num_buckets> 指定分桶个数,也就是表目录下小文件的个数。

    1.2.2 创建分桶实例

    (1)创建一个student表:

    hive> create table student(
    
    st_id int,
    
    st_name string,
    
    st_sex string,
    
    st_age int,
    
    st_dept string
    
    )
    
    clustered by(st_dept) sorted by(st_age desc) into 3 buckets
    
    row format delimited fields terminated by ',';
    
    //  sorted by可以省略
    

    (2)查看表结构:

    hive> desc formatted student;
    
    Num Buckets:            3  
    

    导入数据有两种,一种是通过文件导入,但是并不会真正的分桶 ;一种是通过从其他表插入的方式导入数据,这种方式才能真正的分桶;

    (3)建一个普通的student1表

    hive> create table student1(st_id int,st_name string,st_sex string,st_age int,
    
    > st_dept string)  row format delimited fields terminated by ',';
    

    (4)导入数据到student1表

    hive> load data local inpath '/hive/student.txt' into table student1;
    

    (5)导入数据到分桶的表

    方法一:

    <pre>//打开强制分桶开关:</pre>
    
    hive (myhive)> set hive.enforce.bucketing=true;
    
    //设置reduces数为-1:
    
    hive (myhive)> set mapreduce.job.reduces=-1;
    
    //通过其他表插入数据
    
    hive (myhive)> insert into table student select id, name from stu ;
    

    (通过这种方法,得到的分桶对应的文件,数据是无序的,也就是 sorted by 或 sort by无效)

    如果没有设置 bucketing属性,我们需要自己设置和分桶个数相匹配的reducer个数。

    方法二:

    //关闭强制分桶开关:
    
    hive (myhive)> set hive.enforce.bucketing=false;
    
    //设置reduces数和分桶数一致:
    
    hive (myhive)> set mapreduce.job.reduces=3;
    
    //通过其他表插入数据,要添加 distribute by 以及 sort by。
    
    hive (myhive)> insert into table student select id, name from stu distribute by st_dept;
    

    注意:hive.enforce.bucketing为true时,reduce要设为-1;

    hive.enforce.bucketing为false时,reduce要设为和分桶数一致;

    如果bucketing为 true,reduce又设成大于1的输,会执行两个job。

    (为什么通过 load data 的方式导入数据到 student表,并不会分桶?

    load data只是把文件上传到 表所在的HDFS目录下。并没有做其他操作。)

    总结:我们发现其实桶的概念就是MapReduce的分区的概念,两者完全相同。物理上每个桶就是目录里的一个文件,一个作业产生的桶(输出文件)数量和reduce任务个数相同。

    而分区表的概念,则是新的概念。分区代表了数据的仓库,也就是文件夹目录。每个文件夹下面可以放不同的数据文件。通过文件夹可以查询里面存放的文件。但文件夹本身和数据的内容毫无关系。

    桶则是按照数据内容的某个值进行分桶,把一个大文件散列称为一个个小文件。这些小文件可以单独排序。如果另外一个表也按照同样的规则分成了一个个小文件。

    分桶的好处:

    1、两个表join的时候,就不必要扫描整个表,只需要匹配相同分桶的数据即可。效率当然大大提升。

    2、同样,对数据抽样的时候,也不需要扫描整个文件。只需要对每个分区按照相同规则抽取一部分数据即可。

    2 分桶抽样查询

    对于非常大的数据集,有时用户需要使用的是一个具有代表性的查询结果而不是全部结果。Hive可以通过对表进行抽样来满足这个需求。

    查询表stu_buck中的数据。

    hive (myhive)> select * from student tablesample(bucket 1 out of 3 on id);
    
    

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

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

    x表示从哪个bucket开始抽取,如果需要取多个分区,以后的分区号为当前分区号加上y。例如,table总bucket数为4,tablesample(bucket 1 out of 2),表示总共抽取(4/2=)2个bucket的数据,抽取第1(x)个和第3(x+y)个bucket的数据。

    注意:x的值必须小于等于y的值,否则

    FAILED: SemanticException [Error 10061]: Numerator should not be bigger than denominator in sample clause for table stu_buck

    数据块抽样

    Hive提供了另外一种按照百分比进行抽样的方式,这种是基于行数的,按照输入路径下的数据块百分比进行的抽样。

    
    hive (myhive)> select * from student tablesample(0.1 percent) ;
    
    

    提示:这种抽样方式不一定适用于所有的文件格式。另外,这种抽样的最小抽样单元是一个HDFS数据块。因此,如果表的数据大小小于普通的块大小128M的话,那么将会返回所有行。

    喜欢的朋友可以关注下公众号:圳鹏科技

    相关文章

      网友评论

          本文标题:Hive 分桶详解

          本文链接:https://www.haomeiwen.com/subject/sxmzkqtx.html