標籤:

想研讀下spark的源碼,怎麼搭閱讀和調試的環境呢?

能提高閱讀和調試效率~~


這個問題被很多人問過,很早就想寫一下。尤其是如何在 IntelliJ IDEA 中單步調試 Spark。

若無特殊說明,本篇均以撰稿時最新的 Spark 2.0 SNAPSHOT 和 IntelliJ IDEA 2016 為基礎,並以 SBT 為主要 build 工具。

IDE 選擇

Spark 的主力 IDE 無疑是 IntelliJ IDEA。在 Databricks 我也見過直接用 Vim、Sublime 的同事,然而但凡用 IDE 的,清一色是 IDEA,從沒見過誰用 Eclipse 和/或 NetBeans。所以,作為主力 contributor 的日常 IDE,IDEA 一定是最馴順的。(就個人體驗而言,IDEA 也是我用過的最好的 Java/Scala IDE。)

有一點需要提前說明的是,不要指望讓 IDEA 全權搞定工程導入、build、test、debug 的全部環節。出於歷史原因,Spark 採用了 Maven 和 SBT 兩套 build 系統,二者互相交織,再加上引入了 assembly jar,使得整個 build 系統變得對 IDE 不那麼友好。截至撰稿為止,我尚未見過任何一套可以在單個 IDE 內搞定全套流程的方法。不過不用緊張,debugger 還是可以用的。

Build Spark

在將 Spark 工程導入 IDEA 之前,最好先 build 一遍 Spark,至少完成編譯步驟。這是因為編譯過程中還會自動生成一些源碼。尤其是 Spark 2.0 中 SQL parser 改用 ANTLR 實現。如果不經編譯直接將工程導入 IDEA,parser 相關的 class 會出現引用缺失。

Build Spark 的詳細步驟參見官網文檔。這裡只提一些額外的注意事項。

首先,請努力建設有中國特色的社會主義個人網路訪問渠道。(聽說朝廷要大力發展大數據來著?呵呵。)

其次,和一般理解不同,build Spark 其實不需要單獨安裝 Scala 和 SBT。Spark 源碼中的 build/sbt 腳本會自動下載指定版本的 SBT,而 SBT 在 build Spark 的過程中又會自動下載指定版本的 Scala。所以除非你需要脫離 Spark 單獨使用 Scala,否則無須另行安裝。對於 Maven,build/mvn 腳本的行為也類似。

最後就是 profile 「套餐」的選擇。這部分內容官網文檔中已經有所涉及。詳細的 profile 定義請參見 Spark 根目錄下的 pom.xml。此外,目前 Spark 同時支持 Scala 2.10 和 2.11,其中 Spark 2.0 默認啟用 2.11。查看 pom.xml 的時候會看到 scala-2.10 和 scala-2.11 這兩個 profile。但用 SBT build 時,啟用這兩個 profile 需要用 -D 而不是 -P,如:

build/sbt -Dscala-2.10 -Phive clean assembly/assembly

簡單說,這是因為 Spark 的 SBT build 對 Scala 版本的設置做了特殊處理,標準的 Maven -P 參數是無效的。

注意:正在開發中的 Spark 2.0 已經取消了 assembly jar,把上述的 assembly/assembly 替換為 package 即可。

工程導入

新近版本的 IDEA 對 SBT 的支持已經改進了很多,早就不再需要 sbt-idea 插件。此外,由於 Spark 同時使用 Maven 和 SBT 兩套 build 系統,用 Maven 和 SBT 都可以順利導入。社區里,不同的開發者對 SBT 和 Maven 的偏好各有不同。我印象里 Cloudera 的人相對來說更喜歡 Maven,因為 Maven 對 release publishing 更友好,更方便他們將 Spark 集成進 CDH。而 Databricks 內一般用 SBT 的更多,主要是因為 SBT REPL 開發體驗更流暢。

我個人的偏好比較分裂——工程導入用 Maven,build 和 test 用 SBT。選擇依據主要是最大化日常開發的迭代速度。

IDEA 在導入 SBT 工程的時候會出現全局卡死的情況。整個導入過程是同步的,完成之前無法執行任何操作。偏偏 SBT 的依賴解析又極慢,再配合中國特色的社會主義和諧網路,每回導入打個坐,一年下來不是升仙就是成佛了吧……

用 Maven 導入 IDEA 工程,這個問題就緩解了許多。Maven 的依賴解析更快,而且 IDEA 的 Maven 支持更成熟,整個解析過程是非同步的,不影響其他操作。導入方法也極簡單:File / Open,選定 Spark 根目錄下的 pom.xml,確定即可。

用 Maven 導入工程的另一個優點是,在 IDEA 的 Maven tool window(View &> Tool Windows &> Maven Projects)里可以很方便地調整 active profiles。假設當前 branch 開發的功能僅和 Hadoop 2.2 下的 Spark SQL 的 Hive 集成相關,那麼就可以打開 hadoop-2.2 和 hive profile,關閉其他的 profile。這樣一來,無關的 sub-project 就不會被激活,代碼索引、依賴解析更快,內存佔用也更低。

SBT 配置

Spark SBT build 中包含多個 sub-project,日常開發調試時經常需要切換到不同的 sub-project。因此我會簡單調整一下 SBT 的 prompt string,以便顯示當前的 project 名稱。這步並非必須。

在 $HOME/.sbt/0.13/global.sbt 中添加以下內容即可:

import scala.Console.{BLUE, RESET, UNDERLINED}

shellPrompt := { state =&>
val projectId = Project.extract(state).currentProject.id
s"$BLUE${UNDERLINED}sbt ($projectId)&>$RESET "
}

效果如下:

$ ./build/sbt -Phive -Phive-thriftserver
...
sbt (spark)&> project hive
...
sbt (hive)&>

調試

一個困擾著很多初學者,甚至是一些已經有相當 Spark 開發經驗的工程師的問題,就是如何在 IDEA 中調試 Spark(注意這裡指的是 Spark 本身,而不是基於 Spark 開發的應用)。可能是由於 SBT / Maven 混用以及使用 assembly jar 的緣故,在 IDEA 里直接 build 和調試 Spark 並不方便,往往會碰到一些奇怪的錯誤,以至於 IDEA 完全退化成一個代碼閱讀工具和編輯器。這個問題實際上可以通過遠程調試很好地解決。

以下以監聽模式(listen mode)為例演示如何在 IDEA 內「遠程」調試本地 SBT 內啟動的 Spark test case。

在 IDEA 中建立 Remote Debugging Configuration

選取菜單項 Run &> Edit Configurations... 點擊左上角加號,選取 Remote 建立一套遠程調試配置,並命名為「Remote Debugging (listen)」:

默認的配置剛好合用:

  • Transport:Socket,目標程序與 debugger 間通過 socket 通訊
  • Debugger mode:Listen,debugger 擔任伺服器預先啟動並在指定埠監聽,等待目標程序主動連入
  • Host / Port:Debugger 監聽的地址和埠,默認為 localhost:5005

點擊 Debug 建立配置並啟動 remote debugger 開始監聽。今後需要再次啟動 remote debugger 時,按 F9 選擇建立好的「Remote Debugging (listen)」配置即可。

在 SBT 中啟用遠程調試

假設我們要調試一個跟 Spark SQL Hive 集成有關的 bug。首先,在 Spark 源碼樹 sql/hive 這個 sub-project 中挑個合適的 test suite(比如 HiveQuerySuite),添加一個用於復現該 bug 的 test case foo。然後進入 SBT:

$ ./build/sbt -Phive -Phive-thriftserver
...
sbt (spark)&>

切換至 hive sub-project:

sbt (spark)&> project hive
...
sbt (hive)&>

設置監聽模式遠程調試選項:

sbt (hive)&> set javaOptions in Test += "-agentlib:jdwp=transport=dt_socket,server=n,suspend=n,address=localhost:5005"

(依具體情況,server、suspend、address 三個參數可以按需調整。各參數含義、取值參見 Oracle 官方文檔。)

注意:一般情況下,運行 test case 並不需要特地切換當前 sub-project。但 SBT 中的 settings key 是跟著當前 sub-project 走的。調試 hive sub-project 下的 test case 必須在 hive sub-project 下設置 javaOptions。

最後啟動我們的 test case:

sbt (hive)&> testOnly *.HiveQuerySuite -- -t foo

(末尾的 -t foo 是傳遞給 ScalaTest runner 的命令行參數,表示只運行 test suite 中的 foo 這個 test case。其他參數及用法參見 ScalaTest 文檔。)

在 remote debugger 已經成功啟動並處於監聽模式的前提下,此時 SBT 應該能夠自動連入 remote debugger,事先在 IDEA 里設置了斷點的話,也會生效。

在 SBT 中關閉遠程調試

一旦在 SBT REPL 中設置了上述的 javaOptions,整個 SBT session 中執行任何 test 都會嘗試連接 remote debugger。調試結束後,要關閉遠程調試,可以執行以下命令清除先前的設置:

sbt (hive)&> session clear

其他

sparkShell task

Spark SBT build 中定義了一個 SBT task sparkShell,可以直接在 SBT 內啟動一個 Spark shell。做簡單測試時很方便。


Windows + IDEA + SBT 打造Spark源碼閱讀環境-guozhongxin"s blog

這是我寫的一篇日誌 是spark源碼閱讀環境的全攻略

Spark源碼是有Scala語言寫成的,目前,IDEA對Scala的支持要比eclipse要好,大多數人會選在在IDEA上完成Spark平台應用的開發。因此,Spark源碼閱讀的IDE理所當然的選擇了IDEA。

  • IDEA,有兩個版本:Ultimate Edition Community Edition,後者是free的,而且完全能滿足學習者所有的需求
  • Scala,Spark是用Scala語言寫成的,在本地編譯執行需要這個包
  • SBT,scala工程構建的工具
  • Git,IDEA自動下載SBT插件時可能會用到的工具
  • Spark Source Code,Spark源碼

Spark源碼閱讀環境的安裝步驟安裝Scala。

完成後,在windows命令行中輸入scala,檢查是否識別此命令。

如果不識別,查看環境變數Path中是否有....scalain(我的電腦右鍵,屬性 -&> 高級系統設置 -&> 環境變數),沒有的手動將Scala文件夾下的bin目錄的路徑

安裝SBT

運行SBT的安裝程序,運行完成後,重新打開windows命令行,輸入sbt,檢查是否識別此命令。沒有的話,手動配置環境變數,添加...sbtin

運行完SBT的安裝程序之後,並不意味著完成了sbt的安裝,在windows命令放下輸入sbt後,SBT會自動的下載安裝它所需要的程序包,請耐心等待全部下載成功。

安裝Git

運行Git的安裝程序,安裝完成後,重新打開windows命令行,檢查時候識別git命令。

安裝IDEA安裝IDEA的Scala插件

打開IDEA,在『Welcome to IntelliJ IDEA』界面的『Quick Start』欄,點擊Configure,選擇Plugins。

在彈出的窗口中可以看到已安裝的插件,現在IDEA默認還沒有Scala的插件。需要點擊左下角的Install JetBrains plugin...,在搜索框中輸入『scala』,點擊安裝。安裝完成後可能會要求重啟一下IDEA。

解壓縮Spark Source Code包導入Spark工程

在歡迎界面『Quick Start』欄或者是在主界面的菜單欄File下,選Import Project,找到解壓之後的spark工程文件夾,OK。

選擇import project from external model中的SBT project,(這個選項只有在安裝了IDEA的Scala插件才會有)。

下一步,選擇Project SDK為JDK,最好勾上Use auto-import,然後點擊Finish。這時,IDEA會自動下載安裝SBT所需的各個包,沒有裝Git的話可能會報錯。

因為Spark是一個比較大的工程,所需的包也很多,這個過程也會特別慢,請耐心等待。

導入完成

導入完成後,自動打開工程,要等一段時間,等待sbt對這個工程進行編譯。


跟樓上類似,我是用Intellij Idea的,Berkerley的不少人也用Idea。在 Spark 目錄下一行命令搞定,./sbt/sbt gen-idea, 然後用 IntelliJ Idea 直接打開目錄,就可以導入Spark 的工程了,具體見我博客 Spark開發環境的配置


老問題了,不過我還是回答下吧。我曾經按照網路上的各種教程搭建 Apache Spark 源碼閱讀環境,但到最後幾步總是會出現許多莫名其妙的問題,最後靜下心來閱讀官方給的文檔,配合 IDEA 搭建了一套自己感覺還挺舒適的閱讀、構建和調試環境。全新的 Ubuntu 14.04 LTS / OS X 下,Apache Spark 1.2 和 Apache Spark 1.4.1 源碼測試沒問題。

簡單來說,就是現在命令行環境下按照官方教程編譯源碼,這一塊只要跟著教程就不會有問題,編譯成功後 IDEA 打開項目,在 Project Structure 的 Module 設置中,將 Avro 生成源碼的目錄,以及 Hive 0.12 / 0.13 對應源碼的目錄,標記為 src 目錄,rebuild 即可。

另外,1.4.1 版本有個小 bug,需要額外修改 pom.xml 文件,否則 reimport 之後會出現 `NoClassDefFoundError ` 異常。在最新版的 Spark 源碼中已經解決了這個問題。

效果如下圖(1.2.1):

具體步驟可參考我自己寫的一篇小文:介紹 | Apache Spark 源碼分析


應該說這個和是不是Spark項目沒什麼關係。

建議你使用intellij idea,在spark目錄下執行"sbt/sbt gen-idea",會自動生成.idea項目,導入即可。

idea我不熟,還需要做一些其他的插件配置(python, sbt等)和環境設置。

你也可以使用Eclipse看,Eclipse有scala IDE,把Spark項目當maven工程導入。但是子項目之間的依賴會有點問題,會報錯。

推薦使用前者,向Databricks的開發者看齊;我使用的是後者,我直接依賴了編譯好的包就不會報錯了,純讀源碼的話也勉強可以跟蹤和調試。

另外,我也看有的Committer用vim看spark代碼的,所以怎麼看源碼都無所謂,你熟悉就好,而且這和是不是Spark項目也沒什麼關係。:)


卸了dota


@連城 已經回答得很詳細了, 但是看下來我感覺更加適合比較熟練的spark開發者, 我這裡再補充一個自己寫的相對入門級別的流程, 是我的一篇個人博客

Spark+Intellij 舒服的源碼開發環境配置

裡面主要講到了

  • 導入spark項目到intellij, 包括配置maven依賴之類的, 實現閱讀代碼跳轉無障礙
  • 配置編譯, 打包, 遠程調試環境, 使得修改源碼和單步追蹤調試變得簡單

我寫這個的目的主要是為了給自己做一個筆記, 然後每次改動不大的情況下, 重新編譯打包到啟動遠程調試也只要10秒不到, 所以還算是比較流暢的開發和學習spark源碼的體驗


可以參考:Reading Spark Souce Code in IntelliJ IDEA 用Intellij IDEA 15直接打開源碼下的pom.xml就可以導入項目,既可以高效的閱讀代碼,也可以修改代碼編譯spark,一步到位。

Updated 2016.12

重寫整理了搭建Spark源碼研讀和代碼斷點調試的開發環境:linbojin/spark-notes

基於IDEA 2016.3 + Spark 2.0.2


我的環境是Spark 2.0, Mac10.11

下載源碼後先按照官網文檔用maven build一次, 然後直接在IDEA裡面導入源碼

導入之後, 把example/pom.xml裡面所有的&compile&都刪掉, 然後在maven裡面的"Spark Project External Flume Sink"上右擊, 選"Generate Sources and Update Folders", 再build一次就可以運行了


我來補充下連城的答案。maven用阿里雲的鏡像,不用掛VPN,我自己18分鐘就能build完。具體流程參考我博客:Spark 極速build與導入IDEA流程


先看 郭眾鑫 的解答

在 linux 下,先安裝 JDK,配好 JAVA_HOME

下載 Spark 的源碼包,注意是源碼的那個。

進那個目錄,然後運行 sbt/sbt assembly,這個編譯可能需要一個多小時,主要時間用在下載 jar 包。一般來說,用 SBT 做那種經常修改的編譯更加合適一些。

其他的都可以找到相關的資料,比如怎麼在兩個伺服器上啟動 Spark 並且建立 Master - Worker 體系。

如果你是本地實驗,用 bin/spark-shell 就可以了。


不知道這個有沒有用&>&>&>搭建大型源碼閱讀環境——使用 OpenGrok,https://zhuanlan.zhihu.com/p/24369747?refer=dreawer


這幾天剛有時間整理的答案

Spark源碼分析調試環境搭建


eclipse的話只是讀一讀的話也是可以的。先安裝Eclipse的scala插件,然後spark工程中有Eclipse的插件,進sbt輸入Eclipse生成Eclipse工程,然後導入就行了。你用Eclipse寫也行,那樣Eclipse就充當一個簡單的編輯器了。


以下是一些心得

1建議在Ubuntu里裝個Idea直接搞,相比遠程調試簡單省事,都在虛擬機里的話方便做快照以及回滾

2下載源代碼,導入工程之前用maven編譯一下比較靠譜


如果想快速用類似IDE的體驗在Web端閱讀Spark代碼,可以試試Codatlas:

https://www.codatlas.com/github.com/apache/spark/master/streaming/src/main/scala/org/apache/spark/streaming/receiver/BlockGenerator.scala?line=84


這個問題Spark官方wiki說的很詳細了: https://cwiki.apache.org/confluence/display/SPARK/Useful+Developer+Tools#UsefulDeveloperTools-IDESetup

我clone 的github上Spark的repo (as of 2015/10/13), 最新的代碼根據上述wiki的步驟,在intellij中編譯沒有問題。


idea吧


eclipse + scala 插件


idea VS eclipse, 建議初學的人用 eclipse, 好,方便,弄完後可以著手idea,這是教訓啊,別看他們用idea, idea 的名氣沒eclipse響亮是有原因的


推薦閱讀:

如何高效閱讀 Spark 和 Hadoop 這類大型開源項目源代碼?有什麼工具可以藉助?
第四範式的人工智慧平台 Prophet 有可能替代 Spark 么?
Spark SQL 和 Shark 在架構上有哪些區別?將來會合併嗎?
hadoop 和spark如何系統的學習?

TAG:Scala | Spark |