我在这里阅读了这篇文章:https://spark.apache.org/docs/latest/programming-guide.html(请参阅将函数传递给Spark),但我的用例是使用类型化数据集和我的案例类。我正在尝试使用单例对象来保存映射方法。我想知道如何最好地打包我需要的功能来优化我的舞台的性能(将数据集从一种类型转换为另一种类型,并写入镶木地板)。
目前,舞台步骤耗时非常长,大约300万行(约1.5小时),大约880 MB的数据输出到s3中的镶木地板。
我在群集模式下运行使用min executors = 3,max executors = 10,每个执行器上有4个内核,驱动程序内存为8gb。
-
高级编码部分:
我将一个案例类C1映射到另一个案例类C2。 C1和C2有大约16个字段,各种类型,如java.sql.Timestamp,Option [String] Option [Int],String,Int,BigInt。
case class C1(field1 : _, field2 : _, field3 : _, ...)
case class C2(field1 : _, field2 : _, field3 : _, ...)
为了从C1映射到C2,我需要从https://github.com/drtimcooper/LatLongToTimezone复制的非常大的java类 J的功能(静态方法)。
public class J {
public static String getValue((float) v) = ...
}
我已经在util类Util中编写了映射函数,它有许多其他由映射函数调用的有用函数。
======
基本上我的代码流程如下:
case class C1(field1 : _, field2 : _, field3 : _, ...)
case class C2(field1 : _, field2 : _, field3 : _, ...)
// very large java class J that only contains static methods
public class J {
public static String getValue((float) v) = ...
...
}
object Util {
def m1(i: Int): Int = ...
def m2(l: Option[BigDecimal], l2: Option[BigDecimal]): Int = {
J.getValue(l.get, l2.get)
}
...
def convert_C1_to_C2(c1: C1): C2 = {
C2(
field1 = m1(c1.field1),
field2 = m2(c1.field2, c1.field3),
...
}
}
dataframe.as[C1].map(Util.convert_C1_to_C2)
.mode(SaveMode.Overwrite)
.parquet("s3a://s3Path")
有更优化的方式来写这个吗?或者任何人都可以指出我这样做的任何明显错误?看看我的代码,我不确定为什么要花这么长时间才能完成任务。
我已经尝试过合并说,16个分区可以减少s3中的文件数量,但这似乎会让作业运行得慢得多。通常会有64个分区没有任何合并。