hive-bucketing和分区

6qfn3psc  于 2021-06-02  发布在  Hadoop
关注(0)|答案(2)|浏览(423)

我们应该根据什么来缩小是否在Hive中的一组列上使用分区或bucketing?
假设我们有一个巨大的数据集,其中我们有两个最常被查询的列-因此我的明显选择可能是基于这两个列进行分区,但如果这会导致在大量目录中创建大量的小文件,那么基于这些列对数据进行分区将是一个错误的决定,也许扣扣是一个更好的选择。
我们是否可以定义一种方法,用它来决定我们是应该进行bucketing还是分区?

hof1towb

hof1towb1#

分区:
分区是根据某些条件(例如:日期、国家/地区)分解/划分输入数据。
创建按(dt string,country string)分区的表日志(ts bigint,line string);
将数据本地inpath'input/hive/partitions/file1'加载到表日志分区(dt='2012-01-01',country='gb');
加载数据后在仓库中创建的文件如下:
/用户/hive/warehouse/logs/dt=2012-01-01/country=gb/file1/
/用户/hive/warehouse/logs/dt=2012-01-01/country=gb/file2/
/用户/hive/warehouse/logs/dt=2012-01-01/country=us/file3/
/用户/hive/warehouse/logs/dt=2012-01-02/country=gb/file4/
/用户/hive/warehouse/logs/dt=2012-01-02/country=us/file5/
/用户/hive/warehouse/logs/dt=2012-01-02/country=us/file6
从日志中选择ts,dt,line,其中country='gb';
此查询将只扫描文件1、文件2和文件4。
扣件:
bucketing是基于其他一些条件进一步分解/划分输入数据。
我们可能希望将表(或分区)组织到存储桶中有两个原因。
首先是启用更高效的查询。bucketing对表施加了额外的结构,hive在执行某些查询时可以利用这些结构。特别是,在同一列(包括连接列)上扣接的两个表的连接可以有效地实现为Map端连接。
创建表的第二个原因是为了提高采样效率。在处理大型数据集时,在开发或优化数据集的过程中,对数据集的一小部分进行查询非常方便。
让我们看看如何告诉Hive一张table应该被扣住。我们使用clustered by子句指定要存储桶的列和存储桶的数量:
创建表student(rollno int,name string),由(id)聚集成4个bucket;
从student tablesample中选择*(rand()上4个bucket中的1个);

soat7uwm

soat7uwm2#

bucketing和partitioning不是独占的,可以同时使用。
从我相当长的配置单元经验来看,我的简短回答是“您应该始终使用分区,有时您可能也想使用bucket”。
如果您有一个大表,分区有助于减少查询的数据量。分区通常表示为hdfs上的目录。一个常见的用法是按年/月/日进行分区,因为大多数人是按日期查询的。唯一的缺点是不应该在基数很大的列上进行分区。基数是大数据中的一个基本概念,它是一列可能具有的值的数量例如,“美国州”的基数较低(大约50),而“ip号码”的基数较大(2^32个可能的数字)。如果在具有高基数的字段上进行分区,hive将在hdfs中创建大量目录,这是不好的(namenode上的额外内存负载)。
bucketing可能很有用,但在将数据插入表时也必须严格遵守规则。hive不会检查您插入的数据是否按预期方式进行了绑定。一个带方框的表必须执行一个cluster by,这可能会在处理过程中增加一个额外的步骤。但是,如果执行大量的联接,如果两个表以相同的方式(在相同的字段和相同数量的bucket上)绑定,则它们的速度会大大加快。而且,一旦你决定了桶的数量,你就不能轻易地改变它。

相关问题