hadoop - 数据分布如何在 HIVE 的分桶中发生?

标签 hadoop hive hdfs

我创建了一个如下表,其中包含 3 个存储桶,并向其中加载了一些数据。

create table testBucket (id int,name String)        
    partitioned by (region String)
    clustered by (id) into 3 buckets;    

我也设置了 bucketing 属性。 $set hive.enforce.bucketing=true;

但是当我列出 HDFS 中的表文件时,我可以看到创建了 3 个文件,正如我提到的 3 个存储桶。 但是数据只加载到一个文件中,其余 2 个文件只是空的。所以我很困惑为什么我的数据只加载到文件中?

那么有人可以向我解释一下分桶中的数据分布是如何发生的吗?

[test@localhost user]$ hadoop fs -ls /user/hive/warehouse/database2.db/buckettab/region=USA
Found 3 items
-rw-r--r--   1 user supergroup         38 2016-06-27 08:34 /user/hive/warehouse/database2.db/buckettab/region=USA/000000_0
-rw-r--r--   1 user supergroup          0 2016-06-27 08:34 /user/hive/warehouse/database2.db/buckettab/region=USA/000001_0
-rw-r--r--   1 user supergroup          0 2016-06-27 08:34 /user/hive/warehouse/database2.db/buckettab/region=USA/000002_0

最佳答案

分桶是一种将数据均匀分布到多个文件中的方法。创建多个存储桶,然后根据一些逻辑(主要是一些哈希算法)将每条记录放入其中一个存储桶。

Hive 的分桶功能可用于将表/分区数据分发/组织到多个文件中,以便在同一个文件中存在相似的记录。在创建 Hive 表时,用户需要提供用于分桶的列以及将数据存储到的分桶数。哪些记录到哪个桶是由用于分桶的列的哈希值决定的。

[Hash(column(s))] MOD [Number of buckets]

不同列类型的哈希值计算方式不同。对于 int 列,散列值等于 int 的值。对于字符串列,哈希值是通过对字符串中存在的每个字符进行一些计算来计算的。

每个桶的数据存储在HDFS表目录下的一个单独的HDFS文件中。在每个桶内,我们可以通过在创建表时提供​​ SORT BY 列来定义数据的排列。

让我们看一个例子

使用分桶创建 Hive 表

为了创建分桶表,我们需要使用 CLUSTERED BY 子句来定义要分桶的列并提供分桶数。以下查询创建一个表 Employee,使用 ID 列分桶到 5 个桶中。

CREATE TABLE Employee(
ID BIGINT,
NAME STRING, 
AGE INT,
SALARY BIGINT,
DEPARTMENT STRING 
)
COMMENT 'This is Employee table stored as textfile clustered by id into 5 buckets'
CLUSTERED BY(ID) INTO 5 BUCKETS
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS TEXTFILE;

将数据插入分桶表

我们在 Employee_old 表中有以下数据。

0: jdbc:hive2://localhost:10000> select * from employee_old;
+------------------+--------------------+-------------------+----------------------+--------------------------+--+
| employee_old.id  | employee_old.name  | employee_old.age  | employee_old.salary  | employee_old.department  |
+------------------+--------------------+-------------------+----------------------+--------------------------+--+
| 1                | Sudip              | 34                | 62000                | HR                       |
| 2                | Suresh             | 45                | 76000                | FINANCE                  |
| 3                | Aarti              | 25                | 37000                | BIGDATA                  |
| 4                | Neha               | 27                | 39000                | FINANCE                  |
| 5                | Rajesh             | 29                | 59000                | BIGDATA                  |
| 6                | Suman              | 37                | 63000                | HR                       |
| 7                | Paresh             | 42                | 71000                | BIGDATA                  |
| 8                | Rami               | 33                | 56000                | HR                       |
| 9                | Arpit              | 41                | 46000                | HR                       |
| 10               | Sanjeev            | 51                | 99000                | FINANCE                  |
| 11               | Sanjay             | 32                | 67000                | FINANCE                  |
+------------------+--------------------+-------------------+----------------------+--------------------------+--+

我们将从表 Employee_old 中选择数据并将其插入到我们的分桶表 Employee 中。

我们需要在将数据插入分桶表时将属性“hive.enforce.bucketing”设置为 true。这将强制分桶,同时将数据插入表中。

设置属性

0: jdbc:hive2://localhost:10000> 设置 hive.enforce.bucketing=true;

向Bucketed表employee中插入数据

0: jdbc:hive2://localhost:10000> INSERT OVERWRITE TABLE Employee SELECT * from Employee_old;

验证桶中的数据

执行 INSERT 查询后,我们可以验证在 HDFS 上的 Employee 表目录下创建了 5 个文件。

Name        Type
000000_0    file
000001_0    file
000002_0    file
000003_0    file
000004_0    file

每个文件代表一个桶。让我们看看这些文件的内容。

000000_0 的内容

所有具有 Hash(ID) mod 5 == 0 的记录都会进入此文件。

5,Rajesh,29,59000,BIGDATA
10,Sanjeev,51,99000,FINANCE

000001_0 的内容

所有具有 Hash(ID) mod 5 == 1 的记录都会进入此文件。

1,Sudip,34,62000,HR
6,Suman,37,63000,HR
11,Sanjay,32,67000,FINANCE

000002_0 的内容

所有具有 Hash(ID) mod 5 == 2 的记录都会进入此文件。

2,Suresh,45,76000,FINANCE
7,Paresh,42,71000,BIGDATA

000003_0 的内容

所有具有 Hash(ID) mod 5 == 3 的记录都会进入此文件。

3,Aarti,25,37000,BIGDATA
8,Rami,33,56000,HR

000004_0 的内容

所有具有 Hash(ID) mod 5 == 4 的记录都会进入此文件。

4,Neha,27,39000,FINANCE
9,Arpit,41,46000,HR

关于hadoop - 数据分布如何在 HIVE 的分桶中发生?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38105043/

相关文章:

hadoop - Spark 尝试连接到本地主机而不是配置的服务器

hadoop - 配置单元动态分区不起作用

hadoop - Ambari HDP 2.4添加主机指标监视器无法安装

hadoop - aqua studio 上的 HIVe sql

hadoop - 创建配置单元外部表时出错

mysql - 在 SQOOP 导入中避免倾斜并确定最佳映射器数量

Hadoop DFS 权限错误

java - 如何对 hadoop mapreduce 作业的键使用相似度算法

hadoop - 租期过期异常 : No lease error on HDFS (Failed to close file)

hadoop - 在 Hive 中按列采样