遇到了一个一百多个分区,每个分区几十上百不等的小文件,要求去重后每个分区只输出一个文件。
再写出时设置了.coalesce(1),但是性能很差,每次都是卡在了save端,

在 Spark 中,coalesce 是一种用于减少分区数量的操作,可以将多个小分区合并成一个大分区。这可以提高计算性能,因为 Spark 在处理大分区时可以更高效地使用内存和 CPU 资源。以下是在 Spark 计算中使用 coalesce 进行优化的几种方法:

在读取数据时使用 coalesce:如果你的数据集已经被分成了太多的小分区,可以在读取数据时使用 coalesce 将其合并为更少的分区,这可以减少数据移动和网络开销,提高计算性能。

在计算过程中使用 coalesce:在计算过程中,如果你发现某些操作会将分区数增加到非常大的数量,你可以使用 coalesce 将分区数降至一个更合理的数量,以提高计算性能。

在缓存之前使用 coalesce:如果你需要对数据进行多次操作,可以在缓存之前使用 coalesce 将分区数减少到一个较小的数量,这可以减少缓存所需的内存,提高计算性能。

需要注意的是,使用 coalesce 操作需要根据你的数据集和计算任务进行调整。如果你的数据集非常大,可能需要更多的分区以充分利用集群中的计算资源。另外,如果使用 coalesce 后,某些分区变得太大,可能会导致内存不足或计算性能降低。

上代码:

		Dataset<Row> jsonDs = sparkSession.read().parquet(inputPath).coalesce(10);

        // 根据id去重
        Dataset<Row> distinct = jsonDs.filter((FilterFunction<Row>) value -> {
            if (value == null || StringUtil.isEmpty(value.getAs("id"))) {
                return false;
            }
            return true;
        }).dropDuplicates("id");

        distinct.withColumn("year", date_format(distinct.col("visit_time"), "yyyy"))
                .withColumn("month", date_format(distinct.col("visit_time"), "MM"))
                .withColumn("day", date_format(distinct.col("visit_time"), "dd"))
                .coalesce(1)
                .write().format("parquet").option("blockSize", "128m").mode("append")
                .partitionBy("year", "month", "day")
                .save(outputPath);

更多推荐