如何处理 hive 分区以提高性能与过度分区

Posted

技术标签:

【中文标题】如何处理 hive 分区以提高性能与过度分区【英文标题】:How to deal with hive partitioning for performance versus over-partitioning 【发布时间】:2017-08-16 20:12:20 【问题描述】:

我们有一个非常大的 Hadoop 数据集,其中包含十多年的历史交易数据 - 6.5B 行并且还在不断增加。我们按年和月对它进行了分区。

性能不佳的原因有很多。几乎我们所有的查询都可以通过 customer_id 进一步限定,但是我们有 500 个客户并且增长很快。如果我们将查询范围缩小到给定月份,我们仍然需要扫描所有记录以找到一个客户的记录。数据现在存储为 Parquet,因此主要的性能问题与扫描记录的所有内容无关。

我们犹豫是否要为客户添加分区,因为如果我们有 120 个年月分区,并且每个分区中有 500 个客户,这将产生 60K 分区,这比 Hive Metastore 可以有效处理的还要大。我们还犹豫在 customer_id 上进行分区,因为有些客户很大,有些客户很小,所以我们有自然的数据倾斜。

理想情况下,我们可以对使用频率较低的历史数据进行分区,使用一个规则(可能是年 + 客户 ID)和使用另一个规则(如年/月 + 客户 ID)的当前数据。曾考虑使用多个数据集,但随着时间的推移对其进行管理似乎需要更多的工作和更改等等。

Hive 的策略或功能是否提供了一种方法来处理这种我们“想要”大量分区以提高性能但受到元存储限制的情况?

我也对分桶的好处感到困惑。例如,基于客户 ID 的合适分桶似乎以与分区类似的方式提供帮助。然而 Hortonworks “strongly recommends against” 桶(没有解释为什么)。其他几个页面建议分桶对采样很有用。 Hortonworks 的另一个好 discussion of bucketing 表明 Hive 无法像使用分区一样对存储桶进行修剪。

我们使用的是最新版本的 Hive/Hadoop(从 CDH 5.7 迁移到 AWS EMR)。

【问题讨论】:

我的 2 美分:使用列格式存储每个条带上每一列的最小/最大计数器(允许跳过扫描,特别是如果您的数据在 INSERT 上被明智地排序),例如 ORC。调整 Hive 配置 cf。 slideshare.net/Hadoop_Summit/… pp.12-21。然后合并分区。并且不要将柱状文件存储在 S3 (杀死随机访问,因此跳过扫描功能)... 您似乎概述了一个解决方案,为什么不保留 2 个不同分区的表? 我的 2 美分,继续 - 关于 ORC 调优slideshare.net/Hadoop_Summit/orc-file-optimizing-your-big-data(顺便说一句,Parquet 也不是一个糟糕的选择......) 感谢 Samson 和 @alex-libov。我已经澄清了这个问题。我们确实考虑过添加第二个以不同方式分区的表,但这会产生大量管理开销(定期归档旧数据、通过视图管理访问等) 您可以尝试 hive 索引,在 customer_id 列上创建索引并保持分区不变,即年和月,看看它是如何进行的。 【参考方案1】:

在真正的 60K 分区中,对于 Hive 来说不是什么大问题。我有一个有表的大约 2MM 分区的经验,它工作得非常快。您可以在链接https://andr83.io/1123 上找到一些详细信息当然您需要仔细编写查询。我还可以推荐使用 ORC 格式,支持索引和布隆过滤器。

【讨论】:

以上是关于如何处理 hive 分区以提高性能与过度分区的主要内容,如果未能解决你的问题,请参考以下文章

大数据之Hive:hive的小文件如何处理

Hive如何处理大量小文件

如何处理旧条目?单独的表、分区或只是索引?

Apache spark如何计算分区以及在executor中如何处理分区

若linux 的分区硬盘满,如何处理?

vsan 节点部署,如果遇到磁盘分区删不到,如何处理?