標籤:

Spark SQL生成的代碼怎麼調試?

如圖,Spark SQL的操作最終會轉換成Java類,對生成的代碼能不能調試呢?可以的怎麼操作呢?

-----
2016-10-13 14:55
補充eclipse調試相關信息(Janino by janino-compiler 在IDEA裡面調試源代碼跳不出來):

1. 修改 CodeGenerator.doCompile 方法:

2. 調試代碼以及情況:

這裡是通過SparkSQL生成代碼的結構 模擬的代碼,調試SparkSQL生成的代碼還沒弄。

--2016-10-13 19:10--

在eclipse上面調試是ok了的。這裡簡單列一下操作步驟:

1. 修改 codegen.CodeGenerator#doCompile 的三處代碼

diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeGenerator.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeGenerator.scala
index 16fb1f6..1023dfd 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeGenerator.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeGenerator.scala
@@ -854,7 +854,6 @@ object CodeGenerator extends Logging {
val parentClassLoader = new ParentClassLoader(Utils.getContextOrSparkClassLoader)
evaluator.setParentClassLoader(parentClassLoader)
// Cannot be under package codegen, or fail with java.lang.InstantiationException
- evaluator.setClassName("org.apache.spark.sql.catalyst.expressions.GeneratedClass")
evaluator.setDefaultImports(Array(
classOf[Platform].getName,
classOf[InternalRow].getName,
@@ -875,12 +874,12 @@ object CodeGenerator extends Logging {

logDebug({
// Only add extra debugging info to byte code when we are going to print the source code.
- evaluator.setDebuggingInformation(true, true, false)
+ evaluator.setDebuggingInformation(true, true, true)
s"
$formatted"
})

try {
- evaluator.cook("generated.java", code.body)
+ evaluator.cook(code.body)
recordCompilationStats(evaluator)
} catch {
case e: Exception =&>

2. 使用Scala-IDE
3. 打斷點調試,把 生成目錄的絕對路徑 添加到 源碼查找路徑(Source Lookup Path)。

(Spark SQL 2.0.0不合適用Option對象)

調試的代碼: spark-examples/AccessAnalyser.scala at master · winse/spark-examples · GitHub


目前的確沒有什麼好辦法在 Spark 內單步調試 codegen 出來的代碼,調試基本靠瞅… 另外就是 print 大法了,即在生成代碼的模板中添加 print 列印出相應信息。還有一個辦法是把生成的 Java 文件單獨拎出來,寫一個獨立的 main 函數調試,不過一般只有特別難搞的 bug 才會這麼大費周章。


沒有好辦法,對於Spark 2.x,可以用explain codegen來輔助分析生成的代碼。

如:explain codegen select 1+1


推薦閱讀:

矽谷之路57:深入淺出Spark(八)如何處理實時數據
矽谷之路54:深入淺出Spark(七)如何排序100TB
Spark里的DAG是怎麼回事?
Scala快速入門系列:聲明變數、控制結構與函數、常用數組操作
spark源碼分析--任務執行

TAG:Spark |