如何有效地划分大量数据?

时间:2018-05-18 11:24:48

标签: scala amazon-web-services apache-spark amazon-s3 apache-spark-sql

我想知道在S3中存储它时分割Parquet数据的更有效方法。 在我的群集中,我目前有一个文件夹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天的范围,那么更推荐这两种选择中的哪一种? 哪种替代方案会更快?

3 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:1)

我强烈建议您不要在s3商店中安装许多文件夹。为什么? Spark使用S3连接器通过多个HTTP请求模仿目录树:树越深越宽,效率越低,尤其是因为AWS S3限制了HTTP请求

年/月/日命名方案适用于hive&火花,但如果你进入太深的深度(按天,按小时),那么你可能会遇到比你没有更好的表现。

答案 2 :(得分:1)

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

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

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进行分区!