Hive分桶之BUCKET详解

Hive分桶之BUCKET详解Bucket1.对于每一个表(table)或者分区(partition),Hive可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分

Bucket
1.对于每一个表(table)或者分区(partition), Hive可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分。Hive也是 针对某一列进行桶的组织。Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。

2,把表(或者分区)组织成桶(Bucket)有两个理由:
(1)获得更高的查询处理效率。桶为表加上了额外的结构,Hive 在处理有些查询时能利用这个结构。
具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的实现。
比如JOIN操作。对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作。
那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。
(2)使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,
如果能在数据集的一小部分数据上试运行查询,会带来很多方便。
下面来一个例子:

Create table dz_test(
    id  bigint  comment’编号’,(ps:comment为注释)
    name string comment’姓名’
)comment’编号与姓名表’
Partitioned by(pdate string)
Clustered by(id)     按id分桶,自动哈希分桶
Sorted by(id)   按id排序
Into 4 buckets   分成4个桶
Row format delimited 设置创建的表在加载数据的时候,支持的列分隔符
Fields terminated by ‘\t’  每个字段按\t分割
Lines terminated by’\n’ stored as textfile; 按\n为断行符,指定导入的文件为纯文本。
Hive本身支持的文件格式只有:Text File,Sequence File,如果数据需要压缩,使用 [STORED AS SEQUENCE]

下面load数据:
插入数据之前需要设置参数hive.enforce.bucketing=true,以强制hive的reducer数目为分桶数。
如果不设置这个hive参数,最后的桶个数可能不是建表语句中的个数。
另外,也可以通过将参数mapred.reduce.tasks设置为桶的数目来控制reducer的数目,建议采用第一种方式。

Set hive.enforce.bucketing=true;
Load data local inpath’/home/Hadoop/.’ overwrite into table dz_test partition(pdate=2015-10)

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

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

查看表的结构:
hive> dfs -ls /user/hive/warehouse/dz_test; 
将显示有4个新建的文件。文件名如下(文件名包含时间戳,由Hive产生,因此 每次运行都会改变): 
attempt_201701221636_0016_r_000000_0 
attempt_201701221636_0016_r-000001_0 
attempt_201701221636_0016_r_000002_0 
attempt_201701221636_0016_r_000003_0 
第一个桶里包括用户ID和4,因为一个INT的哈希值就是这个整数本身,在这里 除以桶数(4)以后的余数:2
读取数据,看每一个文件的数据:
hive> dfs -cat /user/hive/warehouse/dz_test/*0_0; 
0 Nat 
4 Ann 
用TABLESAMPLE子句对表进行取样,我们可以获得相同的结果。这个子句会将 查询限定在表的一部分桶内,而不是使用整个表:
. 对桶中的数据进行采样:
hive> SELECT * FROM dz_test 
>TABLESAMPLE(BUCKET 1 OUT OF 4 ON id); 
0 Nat 
4 Ann 
桶的个数从1开始计数。因此,前面的查询从4个桶的第一个中获取所有的用户。 
对于一个大规模的、均匀分布的数据集,这会返回表中约四分之一的数据行。
我们也可以用其他比例对若干个桶进行取样(因为取样并不是一个精确的操作,因此这个 比例不一定要是桶数的整数倍)。
例如,下面的查询返回一半的桶:
7. 查询一半返回的桶数:
hive> SELECT * FROM dz_test 
>    TABLESAMPLE(BUCKET 1 OUT OF 2 ON id)0 Nat 
4 Ann 
2 Joe 
因为查询只需要读取和TABLESAMPLE子句匹配的桶,所以取样分桶表是非常高效 的操作。
如果使用rand()函数对没有划分成桶的表进行取样,即使只需要读取很 小一部分样本,也要扫描整个输入数据集: 
hive〉 SELECT * FROM dz_test 
> TABLESAMPLE(BUCKET 1 OUT OF 4 ON rand()); 
2 Doe 
①从Hive 0.6.0开始,对以前的版本,必须把mapred.reduce .tasks设为表中要填 充的桶的个数。
如果桶是排序的,还需要把hive.enforce.sorting设为true。 
②显式原始文件时,因为分隔字符是一个不能打印的控制字符,因此字段都挤在一起。 

https://blog.csdn.net/m0_37534613/article/details/55258928

今天的文章Hive分桶之BUCKET详解分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/67329.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注