如何高效地对大量数据进行分区? [关闭]
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
分区!
【讨论】:
以上是关于如何高效地对大量数据进行分区? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章