Hive - Bucketing和Partitioning

时间:2015-12-04 20:00:01

标签: hadoop hive bigdata

我们应该基于什么来缩小是否在Hive中的一组列上使用分区或分段?

假设我们有一个庞大的数据集,我们有两列经常被查询 - 所以我明显的选择可能是根据这两列来制作分区,但是如果这会产生大量的小数据在大量目录中创建的文件,而不是基于这些列对数据进行分区的错误决定,并且可能是更好的选择。

我们能否定义一种方法,用以决定是否应该进行分组或分区?

2 个答案:

答案 0 :(得分:3)

暂停和分区不是唯一的,您可以同时使用它们。

我从相当长的蜂巢体验中得到的简短答案是"你应该总是使用分区,有时候你也可能想要使用#34;。

如果您有一个大表,分区有助于减少您查询的数据量。分区通常表示为HDFS上的目录。常见的用法是按年/月/日进行分区,因为大多数人按日期查询。 唯一的缺点是你不应该在具有大基数的列上进行分区。 基数是大数据中的基本概念,它是列可能具有的值的数量。 '美国州'例如,基数低(大约50),而例如' ip_number'有一个大基数(2 ^ 32个可能的数字)。 如果在具有高基数的字段上进行分区,则hive将在HDFS中创建大量目录,这是不好的(在namenode上额外的内存负载)。

暂停可能很有用,但在将数据插入表格时也必须遵守规则。 Hive不会检查您插入的数据是否按照其应有的方式进行了删除。 一个分块表必须执行CLUSTER BY,这可能会在您的处理过程中增加一个额外的步骤。 但是如果你做了很多连接,如果两个表以相同的方式(在相同的字段和相同数量的存储桶上)被删除,它们可以大大加快。此外,一旦你决定了桶的数量,你就不能轻易改变它。

答案 1 :(得分:0)

分区:

分区正在根据某些条件对输入数据进行分解/分割,例如:日期,国家/地区。

创建表日志(ts BIGINT,行STRING) 分手(dt STRING,国家STRING);

LOAD DATA LOCAL INPATH'input / hive / partitions / file1' INTO TABLE记录PARTITION(dt ='2012-01-01',country ='GB');

加载数据后在仓库中创建的文件:

/用户/蜂巢/仓库/日志/ DT = 2012-01-01 /国家= GB / file1的/

/用户/蜂巢/仓库/日志/ DT = 2012-01-01 /国家= GB / file2的/

/用户/蜂巢/仓库/日志/ DT = 2012-01-01 /国家= US / file3的/

/用户/蜂巢/仓库/日志/ DT = 2012-01-02 /国家= GB / file4将/

/用户/蜂巢/仓库/日志/ DT = 2012-01-02 /国家= US / file5 /

/用户/蜂巢/仓库/日志/ DT = 2012-01-02 /国家= US / file6

SELECT ts,dt,line 从日志 WHERE country ='GB';

此查询仅扫描file1,file2和file4。

Bucketing:

暂停进一步根据其他一些条件对输入数据进行分解/分割。

我们可能希望将表(或分区)组织到存储桶中有两个原因。

首先是启用更有效的查询。 Bucketing在桌面上施加了额外的结构,Hive在执行某些查询时可以利用这些结构。特别是,在同一列上打包的两个表的连接(包括连接列)可以有效地实现为地图侧连接。

表格的第二个原因是提高采样效率。使用大型数据集时,在开发或优化数据集的过程中尝试对数据集的一小部分进行查询非常方便。

让我们看看如何告诉Hive表格应该被删除。我们使用CLUSTERED BY子句指定要存储的列和存储桶的数量:

CREATE TABLE student(rollNo INT,name STRING)CLUSTERED BY(id)INTO 4 BUCKETS;

SELECT * FROM student TABLESAMPLE(BUCKET 1 out of 4 on rand());