Hadoop 用于文件写入的Spark分区非常慢

Hadoop 用于文件写入的Spark分区非常慢,hadoop,apache-spark,hdfs,parquet,hadoop-partitioning,Hadoop,Apache Spark,Hdfs,Parquet,Hadoop Partitioning,当使用Spark将文件写入HDFS时,在不使用分区的情况下速度相当快。相反,当我使用分区写入文件时,写入延迟增加了因数~24 对于同一个文件,无分区写入大约需要600毫秒。按Id使用分区写入(将精确生成1.000个分区,因为文件中有1.000个Id),大约需要14秒 你们中的一些人是否有编写分区文件需要很长时间的经验?根本原因是什么,可能Spark需要为每个分区创建1000个文件夹和文件? 你知道如何加快速度吗 val myRdd = streamedRdd.map { case ((id, m

当使用Spark将文件写入HDFS时,在不使用分区的情况下速度相当快。相反,当我使用分区写入文件时,写入延迟增加了因数~24

对于同一个文件,无分区写入大约需要600毫秒。按Id使用分区写入(将精确生成1.000个分区,因为文件中有1.000个Id),大约需要14秒

你们中的一些人是否有编写分区文件需要很长时间的经验?根本原因是什么,可能Spark需要为每个分区创建1000个文件夹和文件? 你知道如何加快速度吗

val myRdd = streamedRdd.map { case ((id, metric, time), value) => Record(id, metric, getEpoch(time), time, value) }

val df = myRdd.toDF

df.write.mode(SaveMode.Append)
.partitionBy("id")
.parquet(path)

Spark执行器与HDF通信以写入它们拥有的数据,这取决于分区后数据在集群中的分布方式

显然,对于较小的数据块,与按顺序写入整个文件相比,建立从多个执行器节点到HDF的连接并进行写入的时间会更长

如何避免这种情况:

默认情况下,spark使用散列分区器对数据进行分区(散列该键,具有相同散列的键进入同一节点)。请尝试指定范围分区器,请查找以下示例片段:

以下代码段使用哈希分区器 yourRdd.groupByKey().saveAsTextFile(“HDFS路径”)

下面的代码段使用了我们的自定义范围分区器 它创建了8个分区,如
RangePartitioner(8,yourRdd)
中所述,通过8个连接进行写入比通过1000个连接进行写入更好

val tunedPartitioner = new RangePartitioner(8, yourRdd)
val partitioned = yourRdd.partitionBy(tunedPartitioner).saveAsTextFile("HDFS PATH");

同样,这是要写入的数据和您创建的分区数量之间的折衷。

您可以包括您使用的代码吗?这个想法很好,但它不适用于数据帧。你能给出一个重新划分数据并将其保存到拼花地板的例子吗?@alexeipab你目前不能使用自定义分区器进行分区。您唯一能做的就是使用重分区按列进行分区。或者,您可以使用myDF.rdd.partitionBy()对数据帧底层的rdd进行分区。