何时应在Hive中使用分区和桶?

4

我了解Hive表中分区和桶的概念。但是我想知道的是,“什么时候我们需要使用分区,什么时候我们需要使用桶?”有哪些理想的场景适合使用分区和桶?

4个回答

4

使用分区和分桶的主要原因。

分区:

对表数据进行分区是为了水平分布负载。

例如:如果我们有一个名为“Parts”的非常大的表,并且经常运行“where”查询,限制结果为特定零件类型。

为了更快地响应查询,可以按(PART_TYPE STRING)对表进行分区。一旦对表进行了分区,它会改变Hive结构化数据存储的方式,Hive现在将创建反映分区结构的子目录,如下所示:

.../Parts/PART_TYPE = Engine-Part

.../Parts/Part_Type = Brakes

现在,如果您在“零件”表中运行带有WHERE PART_TYPE = 'Engine-Part'的查询,它只会扫描一个目录PART_TYPE =' Engine-Part' 的内容。

分区功能在Hive中非常有用。但同时,它可能需要很长时间来执行其他查询。

另一个缺点是,如果我们创建太多分区,就会创建大量的Hadoop文件和目录,这些文件和目录是不必要的,并且会成为NameNode的负担,因为NameNode必须将文件系统的所有元数据文件保存在内存中。

桶分配:

桶分配是另一种技术,可用于进一步将数据划分为更易管理的形式。

例如:假设“part_sale”表具有“sale_date”的顶级分区,并且进一步分区为“part_type”作为第二级分区。

这将导致太多的小分区。

.../part_sale/sale-date = 2017-04-18/part_type = engine_part1
.../part_sale/sale-date = 2017-04-18/part_type = engine_part2
.../part_sale/sale-date = 2017-04-18/part_type = engine_part3
.../part_sale/sale-date = 2017-04-18/part_type = engine_part4

如果我们把"part_sale"表进行分桶,并以"part_type"作为表的分桶列。该列的值将会由一个用户定义的数字进行哈希处理,划分到多个桶中。相同"part_type"的记录将始终存储在同一个桶中。您可以在创建表时指定桶的数量,这样桶的数量就是固定的,不会因数据而波动。

0

PARTITIONING 会在列中有少量唯一值且您想要使用所需的 WHERE 子句进行加载时使用。

BUCKETING 将用于 WHERE 子句中存在多个唯一值的情况。


0
Hive中的分区: 如果我们处理的是一个大表,并且经常运行带有WHERE子句的查询,限制结果为特定的分区列/列,则应利用Hive的分区概念。为了更快的查询响应,Hive表可以通过(partition_cols_name)进行分区。它有助于以逻辑方式组织数据,并且当我们使用分区列查询分区表时,它允许Hive跳过除相关子目录和文件之外的所有内容,因此如果正确地进行分区,则扫描变得容易。当基数(字段可能具有的可能值数量)不高时应该这样做。否则,如果有太多的分区,则对namenode造成负担。
Hive中的桶分配: 如果您想将数据根据具有高基数(字段可能具有的可能值数量)的字段进行分离,则应使用桶分配。如果我们只想根据某些特定字段获取数据样本而不是整个数据,则桶分配可能是一个不错的选择。如果涉及一些映射端连接,则桶分配表是一个不错的选择。

0
分区有助于在WHERE子句中消除数据,而桶则有助于将每个分区中的数据组织成多个文件,以便相同的数据集始终写入同一个桶中。这对于列的连接非常有帮助。 Hive Buckets实际上是将数据分解或减少为更易管理或相等部分的另一种技术。例如,我们有一个包含日期、员工姓名、员工ID、薪水、请假等列的表。在此表中,只需使用日期列作为顶级分区,将员工ID作为第二级分区会导致太多的小分区。我们可以使用哈希值进行桶分配,或者使用范围来桶分配数据。
当我们进行分区时,Hive分区和桶就是为每个列的唯一值创建一个分区。但是可能存在需要创建大量微小分区的情况。但是如果您使用桶,则可以将其限制为您选择的数量,并将数据分解为这些桶。在Hive中,分区是目录,但桶是文件。
在Hive中,默认情况下不支持桶分配。您需要设置以下变量才能启用桶分配:set hive.enforce.bucketing=true;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接