使用Spark将文件写入HDFS时,不使用分区时速度非常快。而不是那样,当我使用分区来写入文件时,写入延迟增加了因子〜24。
对于同一文件,无分区写入大约需要600毫秒。使用Id编写分区(将生成正好1.000个分区,因为文件中有1.000个ID),大约需要14秒。
你们中的一些人是否有同样的经历,写一个分区文件需要很长时间?造成这种情况的根本原因可能是Spark需要为每个分区创建1.000个文件夹和文件? 你知道如何加快它的速度吗?
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)
答案 0 :(得分:1)
Spark执行程序与HDFS通信以写入它们拥有的数据,这取决于分区后数据在群集中的传播方式。
显然,对于较小的数据块,与顺序写入整个文件相比,建立从多个执行器节点到HDFS和写入的连接的时间会更多。
如何避免这种情况:
默认情况下,spark使用Hash分区程序对数据进行分区(哈希键和具有相同哈希值的键转到同一节点)尝试指定范围分区程序,请在下面找到示例代码段:
以下代码段使用哈希分区程序 yourRdd.groupByKey()。saveAsTextFile(" HDFS PATH");
以下代码段使用我们的自定义范围分区程序
它创建了RangePartitioner(8, yourRdd)
中提到的8个分区,通过8个连接写入将是更好的选择,然后写入1000个连接。
val tunedPartitioner = new RangePartitioner(8, yourRdd)
val partitioned = yourRdd.partitionBy(tunedPartitioner).saveAsTextFile("HDFS PATH");
同样,这是要写入的数据与您创建的分区数量之间的权衡。