Hive 分区、分桶和排序表 - 多个插入

Posted

技术标签:

【中文标题】Hive 分区、分桶和排序表 - 多个插入【英文标题】:Hive Partitioned, Bucketed and Sorted table - multiple inserts 【发布时间】:2019-11-13 09:50:46 【问题描述】:

你好,很抱歉,很长的文字,

我们使用 hive 1.2.0 并按日期分区表,按客户 ID 分桶并按客户 ID 排序。 (我知道,它不应该按同一件事进行排序,但这样做是有意义的)。

当我们测试性能时,我们使用了已经存在的表,因此每个分区有 128 个文件(表有 128 个桶)。性能影响很大。

但我注意到,在实时环境中,所有插入都会创建额外的 128 个文件。我期待看到 Hive 插入到已经存在的文件中。如果我们每小时填写一次表格,我们可以预期 24 x 128 个文件,所有文件都已排序。但这不再是真正排序的了——它是每个文件排序的。我敢肯定它仍然很重要,但它会影响性能。表每天有约 1 亿行。并且由于一些后续/延迟条目,一个分区的实际插入次数可能大于 24 - 它可能是 30-40。

我们目前正在考虑每周进行压缩工作,但这真的很令人沮丧:)。最初,这是一个 Spark 管道,然后需要从“Spark 临时表”插入 Hive,因为 Spark 无法写入此类表,现在我们正在研究是否有可能进行 compaction 作业。 .

有什么建议/建议吗?

提前致谢!

【问题讨论】:

【参考方案1】:

我没有明白你到底想问什么。

但是根据你的问题。

根据客户 ID 创建排序桶是个好主意 肯定会提供性能优化,主要是在像 SMB 这样的连接中 和桶连接,你会看到很大的改进。

众所周知,如果您插入到buckted table hive 将创建 _copy 的新存储桶不会编辑或更新现有的 bucket 相反,它将创建一个具有新值的新存储桶。

如果您正处于应用程序的设计阶段,我建议您根据可以作为运行 ID 的技术分区再创建 1 个分区子句。 例如,如果您每小时运行一次进程,那么您可以基于小时创建新分区,或者它可以是您可以生成的任何唯一 ID

所以你的直接结构会像

table_name/<date>/<hour>/bucketes_files

您无法编辑现有存储桶。

其他解决方法是与您的主表一起创建一个临时表,将您的数据保存 1 天左右,然后用新数据加入此表并插入覆盖主表,这样您的 bucktes 将保存所有数据排序 customer_id 并且不会有文件副本,因为我们将数据插入到现有表中

【讨论】:

谢谢。我害怕我会看到这样的事情。问题是 - 就像我在长问题中提到的那样 - 我们继续接收特定日期的数据,即使是接下来的一两天。确实是非常不幸的事情。我的想法是继续压缩的想法——我将简单地创建一个每周工作,该工作将在周末运行并从例如复制数据。两周前,从原始表中删除所有内容,然后一口气将其写回。感谢你的回答。我很快就会接受它作为答案 - 只是想继续希望一段时间:) 是的,同意压缩在您的场景中也是一个好主意。在考虑这个之前只是一个重要的指针。虽然每天将数据加载到主表中,但创建另一个将数据保存一段时间的表也可能是 15 天。以便为压缩期间的最坏情况做好准备。还有另外一种方法是创建两个表 1,它将按原样保存数据(重复的存储桶),并创建另一个具有相同结构的表,每当数据进入表 1 或每天或特定之后,该表将从 table1 插入覆盖您的处理过程中可能每周进行一次 invetervals。 同意 - 我肯定会在删除之前进行备份。但我仍然觉得奇怪的是 Hive 不提供此功能... Hive 有其局限性,但编辑现有(存储桶)和搜索、排序和比较每个新键(customer_id)和文件中的数据的复杂性和耗时过程是有道理的在现有非常大的文件中的确切位置插入。

以上是关于Hive 分区、分桶和排序表 - 多个插入的主要内容,如果未能解决你的问题,请参考以下文章

Hive(大数据)- 分桶和索引之间的区别

深入理解Hive分区与分桶

分区和分桶区别

hive分桶表实践

Hive基础知识

hive扫描分区不超过400个