如何高效地对大量数据进行分区? [关闭]

Posted

技术标签:

【中文标题】如何高效地对大量数据进行分区? [关闭]【英文标题】:How to efficiently partition a large amount of data? [closed] 【发布时间】:2018-05-18 11:24:48 【问题描述】:

我想知道在将 Parquet 数据存储在 S3 中时,什么是更有效的分区方式。 在我的集群中,我目前有一个文件夹data,其中包含大量 Parquet 文件。我想更改保存数据的方式以简化数据检索。 我有两个选择。一种选择是将 Parquet 文件存储在以下文件夹路径中:

PARTITION_YEAR=2017/PARTITION_MONTH=07/PARTITION_DAY=12/my-parquet-files-go-here

PARTITION_DATE=20170712/my-parquet-files-go-here

如果我需要使用 spark.read.parquet 在 Spark 中读取 7 天的范围,那么这两种选择中的哪一种更推荐? 哪个替代方案更快?

【问题讨论】:

第一个选项对我来说很好。分区越多,文件夹的数量就越多。第二个选项将在同一文件夹中为每一天创建文件夹。因此,您的文件夹中将有近 365 个目录,仅用于 1 年的数据。而在第一个选项的情况下,您的数据将被很好地分区和隔离。 @ShrinivasDeshmukh:您是否将PARTITION_DATE=20170712/my-parquet-files-go-here 作为第一个选项?它将创建更少的文件夹。我没听错吗? 不,PARTITION_YEAR=2017/PARTITION_MONTH=07/...我提到了这个选项 PARTITION_DATE=20170712/my-parquet-files-go-here,这将在您的主文件夹中创建更多目录。 PARTITION_YEAR=2017/PARTITION_MONTH=07/... 这将形成一个树结构,其根部将是“年”文件夹,月份将是第一个子文件夹,“日期”将是第二个子文件夹。跨度> 为什么这个问题被否决??? 【参考方案1】:

由于在这两种情况下,您都以每日粒度存储数据,鉴于在读取时的适当实现,这两者应该是等效的,但前者允许您根据需要定义更好的粒度修剪:您可以轻松获取数据全年、一个月或一天(或两者的组合),glob patterns 得到很好的支持。

我鼓励您使用更灵活的前一种解决方案,因为对于您当前的用例,效率不会发生显着变化。

【讨论】:

【参考方案2】:

我强烈建议您不要在您的 s3 存储中拥有很多很多文件夹。为什么? Spark 使用 S3 连接器通过多个 HTTP 请求模拟目录树:树越深越宽,效率就越低,尤其是因为 AWS S3 会限制 HTTP 请求

年/月/日命名方案与 hive 和 spark 配合得很好,但如果您深入(按天、按小时),那么您可能会遇到比不这样做时更差的性能。

【讨论】:

【参考方案3】:

答案很简单……这取决于您将如何查询数据!

如果您只是在几天范围内查询,那么第二个选项是最简单的:

SELECT ...
FROM table
WHERE date BETWEEN ... AND ...

如果您按月和日进行分区,则必须编写使用两个字段的 WHERE 子句,如果所需的 7 天范围跨越两个飞蛾(例如 2018-05-27 到 2015-06),这将是困难的-02):

SELECT ...
FROM table
WHERE (month = 5 and date BETWEEN 27 AND 31) OR
      (month = 6 and date BETWEEN 1 AND 2)

这是使分区工作的最佳方式,但编码效率不高。

因此,如果您在 date 上使用 WHERE,则按 date 分区!

【讨论】:

以上是关于如何高效地对大量数据进行分区? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

对 Hive 数仓表进行高效小文件合并

对 Hive 数仓表进行高效小文件合并

如何高效地向Redis写入大量的数据

如何高效地向Redis写入大量的数据

如何高效地向Redis写入大量的数据

如何计算/处理大量数据? [关闭]