我遇到了一个长期而复杂的包含udf的火花作业的问题。
我一直遇到的问题是,尽管没有错误消息,但udf似乎没有被正确调用。
我知道调用不正确是因为输出被写入,udf只能计算的任何内容都是 NULL ,并且在本地调试时不会显示任何打印语句。
唯一的原因是该代码以前使用不同的输入数据来工作,这意味着错误必须与输入有关。
输入中的更改主要表示使用了不同的列名,这在代码中已解决。
在给出第一个“有效”输入的情况下执行打印语句。
这两个输入都是使用同一数据库中的相同系列步骤创建的,通过检查,这两个输入似乎都没有问题。
我以前从未经历过这种行为,任何可能导致这种行为的线索都会受到赞赏。
该代码是整体代码,缺乏灵活性-我正在努力进行重构,但要分解它并非易事。这是正在发生的事情的简短版本:
package mypackage
import org.apache.spark.sql.DataFrame
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.functions._
import org.apache.spark.util._
import org.apache.spark.SparkContext
import org.apache.spark.SparkContext._
import org.apache.spark.sql.types._
import scala.collection.{Map => SMap}
object MyObject {
def main(args: Array[String]){
val spark: SparkSession = SparkSession.builder()
.appName("my app")
.config("spark.master", "local")
.getOrCreate()
import spark.implicits._
val bigInput = spark.read.parquet("inputname.parquet")
val reference_table = spark.read.parquet("reference_table.parquet")
val exchange_rate = spark.read.parquet("reference_table.parquet")
val bigInput2 = bigInput
.filter($"column1" === "condition1")
.join(joinargs)
.drop(dropargs)
val bigInput3 = bigInput
.filter($"column2" === "condition2")
.join(joinargs)
.drop(dropargs)
<continue for many lines...>
def mapper1(
arg1: String,
arg2: Double,
arg3: Integer
): List[Double]{
exchange_rate.map(
List(idx1, idx2, idx3),
r.toSeq.toList
.drop(idx4)
.take(arg2)
)
}
def mapper2(){}
...
def mapper5(){}
def my_udf(
arg0: Integer,
arg1: String,
arg2: Double,
arg3: Integer,
...
arg20: String
): Double = {
println("I'm actually doing something!")
val result1 = mapper1(arg1, arg2, arg3)
val result2 = mapper2(arg4, arg5, arg6, arg7)
...
val result5 = mapper5(arg18, arg19, arg20)
result1.take(arg0)
.zipAll(result1, 0.0, 0.0)
.map(x=>_1*x._2)
....
.zipAll(result5, 0.0, 0.0)
.foldLeft(0.0)(_+_)
}
spark.udf.register("myUDF", my_udf_)
val bigResult1 = bigInputFinal.withColumn("Newcolumnname",
callUDF(
"myUDF",
$"col1",
...
$"col20"
)
)
<postprocessing>
bigResultFinal
.filter(<configs>)
.select(<column names>)
.write
.format("parquet")
}
}
回顾
此代码在两个输入文件中的每个文件上运行完毕。
udf仅在第一个文件上执行。
尽管所有非udf逻辑似乎都已成功完成,但使用第二个文件没有任何错误消息或任何内容。
任何帮助都将不胜感激!
答案 0 :(得分:0)
此处未调用UDF,因为火花 懒惰它不会调用UDF,除非您在数据帧上使用任何操作。您可以通过强制执行数据框操作来实现此目的。