Scala 如何在ApacheSpark中执行数据集的加权分区
我在ApacheSpark中有一个时间序列数据集,每个条目代表一个事件,类型我将调用Scala 如何在ApacheSpark中执行数据集的加权分区,scala,apache-spark,Scala,Apache Spark,我在ApacheSpark中有一个时间序列数据集,每个条目代表一个事件,类型我将调用eventType。我想对数据进行分区,并将数据写入到按天和eventType分区的存储中,如下所示: dataset.repartition(new Column("eventType"), new Column("year"), new Column("month"), new Column("day")) .write .partitionBy("eventType", "year", "m
eventType
。我想对数据进行分区,并将数据写入到按天和eventType
分区的存储中,如下所示:
dataset.repartition(new Column("eventType"), new Column("year"), new Column("month"), new Column("day"))
.write
.partitionBy("eventType", "year", "month", "day")
.json("output-path")
问题是,一种事件类型problemEvent
的发生频率通常是另一种的10倍,因此我在Spark中对某些任务的内存使用达到了极限。为了减少这些分区的大小,我可以创建一个额外的列散列
,当它随机取十个值中的一个时,它为所有事件类型取一个值,除了problemEvent
dataset.withColumn("hash", hashUdf($"eventType"))
然后我也可以对这个值进行分区(hashUdf
是一个用户定义的函数)。问题在于,当我写出数据时:
dataset.repartition(new Column("eventType"), new Column("year"), new Column("month"), new Column("day"), new Column("hash"))
.write
.partitionBy("eventType", "year", "month", "day", "hash")
.json("output-path")
然后我有了一个额外的目录../day=10/hash=uuid/part-..json
。我确实希望输出的目录结构与目录中的其他文件相同:
.../day=10/part-....json
.../day=10/part-....json
我也不确定我在这里所做的是否是惯用的,而且散列列感觉有点像黑客。有人能提出实现这一点的方法吗?减少problemEvents
的内存开销,同时保持良好的输出结构
数据在给定目录中的文件之间如何分解并不特别重要,文件大小或记录数都可以,但是设置maxRecordsPerFile
对内存没有任何影响。您可以提供散列来重新分区,而不是在partitionBy中,以保持相同的目录结构
dataset.repartition(new Column("eventType"), new Column("year"), new Column("month"), new Column("day"), new Column("hash"))
.write
.partitionBy("eventType", "year", "month", "day")
.json("output-path")
.../day=10/part-....json
.../day=10/part-....json
您将得到相同的目录结构
dataset.repartition(new Column("eventType"), new Column("year"), new Column("month"), new Column("day"), new Column("hash"))
.write
.partitionBy("eventType", "year", "month", "day")
.json("output-path")
.../day=10/part-....json
.../day=10/part-....json
您还可以在重新分区(int numPartitions,Column…partitionExprs)
中指定分区的数量建议:持久化您的数据帧,创建2个数据帧(一个用于problemEvents,另一个用于其他事件),并使用两个写入逻辑:标称一个用于otherEventsDF,problemEventsDF有一个特定的分区,它将按年、月、日进行分区,并写入名为/eventType=problemEvents/的目录。有可能,我希望避免为此编写自定义逻辑。这些文件将发送到S3,因此如果Spark API中没有什么东西可以执行,我可能会对数据进行分区,然后用该脚本映射文件名。是的!这正是我所需要的,我将运行更多的测试,但看起来不错,谢谢