Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何在ApacheSpark中执行数据集的加权分区_Scala_Apache Spark - Fatal编程技术网

Scala 如何在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

我在ApacheSpark中有一个时间序列数据集,每个条目代表一个事件,类型我将调用
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中没有什么东西可以执行,我可能会对数据进行分区,然后用该脚本映射文件名。是的!这正是我所需要的,我将运行更多的测试,但看起来不错,谢谢