【发布时间】:2017-11-11 13:31:58
【问题描述】:
我有一个相当简单的工作,将日志文件转换为镶木地板。它正在处理 1.1TB 的数据(分成 64MB - 128MB 的文件 - 我们的块大小为 128MB),大约是 12000 个文件。
工作如下:
val events = spark.sparkContext
.textFile(s"$stream/$sourcetype")
.map(_.split(" \\|\\| ").toList)
.collect{case List(date, y, "Event") => MyEvent(date, y, "Event")}
.toDF()
df.write.mode(SaveMode.Append).partitionBy("date").parquet(s"$path")
它使用通用模式收集事件,转换为 DataFrame,然后以 parquet 形式写出。
我遇到的问题是,这可能会在 HDFS 集群上造成一点 IO 爆炸,因为它试图创建如此多的小文件。
理想情况下,我只想在分区“日期”内创建少量镶木地板文件。
控制这种情况的最佳方法是什么?是通过使用'coalesce()'吗?
这将如何影响在给定分区中创建的文件数量?它是否取决于我在 Spark 中工作的执行者数量? (目前设置为 100)。
【问题讨论】:
-
与问题无关,但你不应该收集你的数据(第一条语句),而是在你的
RDD上使用map -
@RaphaelRoth 这个收藏是不同的。这更像是过滤器 -> 映射github.com/apache/spark/blob/v2.1.1/core/src/main/scala/org/…
-
@user3030878 您是如何让
Spark准确写入 64 MB / 128 MB 文件的?我的Spark工作提供了微小的(每个 1-2 MB)文件(文件数 = 默认值 = 200)。我不能简单地调用repartition(n)来获得每个大约 128 MB 的文件,因为n在不同的工作中会有很大的不同。
标签: scala apache-spark