Spark 超入門筆記

最近在使用 Spark 來處理較大量的資料,包含資料處理、資料轉換到建立模型與分析。對一個過去只曾經使用 R 的我來說,無非是個大挑戰。在經過近一到兩個禮拜的使用,想把一些經驗記錄起來。

若有錯誤,或是描述有問題的地方,再請指正。因為我只是花些時間去讓整個程式可以動,但對於其中更詳細的設定,仍然一隻半解。

希望能互相學習,更加精進。

相關環境

硬體部份是使用 mac book pro,編寫的 IDE 是 IntelliJ IDEA,並利用 sbt 來建立相關專案,而關於 IntelliJ IDEA 和 sbt 的介紹,在網路上可以找到非常多,再加上我還非常入門,無法提供太多個人的理解,因此這部分我會整理一些之前參考過的連結,包含如何設定 IntelliJ IDEA 以便來開發 spark,以及利用 sbt 來協助專案的建置。

怎麼執行一個 spark application

像在 R ,習慣的編程方式,就是寫一些程式碼,然後寫成像是 pipeline 的執行方式,把多個程式碼串接,透過 shell scripts 的方式,去讓整個分析流程動起來。
那在 spark application 的部分,則是會把它包裝成一個 jar 檔案,然後利用 spark-submit 這個 function ,去指定要啟動哪一個 object,讓整個分析流程跑起來。
簡單的程式碼大概如下,他有許多參數可以去設定,像是機器的規格,總共要幾個 cores…等,而這些參數也可以寫在 config 檔中。

spark-submit 
--class [Class] // 要執行哪一個 class
--master [master URL] // hadoop master 的 url
--executor-memory [8g] // 單台機器的 memory
--executor-cores [8] // 一台機器要用滿 8 個 cores,否則會用不滿。
--total-executor-cores [40] // 總共 40 個 cores
spark-project.jar // 辛苦包好的 jar 檔

而在上面最後一列看到的 spark-project.jar,就是將寫好的 spark application 包成這個 jar 檔案,然後透過 spark-submit 去執行。
而包成 jar 的方式,我並沒有使用 IntelliJ IDEA 來包,而是使用 sbt-assembly(連結有安裝和教學)。

用 sbt-assembly 的好處是,我們通常會在 build.sbt 中引入多個套件,但這些套件中,有些功能 (function) 可能是重複的,但是版本不同,這樣會導致引入多種不同版本的類似功能函數。而 sbt-assembly 便可以透過一些設定,來選擇假使要衝突的版本下,要使用哪個…等類似的設定。
使用的方法跟教學請見上面的 sbt-assembly 連結。

習慣的使用方式

對於像我這樣的超入門新手來說,我遇到的困難有以下幾點:

  • 像這樣要包成 jar 檔案的方式,要怎麼 debug?
    我習慣的方式,是先進到專案的資料夾,然後在 root 層,也就是 build.sbt 的那一層,輸入 sbt console,進到 scala 的 REPL 模式,也就是 scala 的互動模式,這個模式下可以直接互動式操作操作,就像 R 或是 python 的操作模式。
    進到這個模式下,有個好處,就是在 build.sbt 設定的套件,都會一併被載入,因此就可以專注在撰寫程式邏輯,而不用煩惱哪些套件該裝沒裝。
    因此編寫程式就在 IDE 內,好處是可以幫忙檢查拼字或是套件引入正確與否,而在 REPL 下,就可以先讀入小部分的資料,目的是驗證程式邏輯是否正確。
  • 能不能在同一個專案下,有多個 object,分別執行不同的內容?
    可以的,我舉 IntelliJ IDEA 為例,在新創一個 object 的方式是在 src/main/scala 資料夾按右鍵,點選 New 新增一個 scala class,這時候會跳出一個視窗,請記得在 Kind 的選項,預設是 Class,將其改為 Object,並取名稱。之後便在這個 Object 內,開始定義 main ,也就是程式進入點,然後開始撰寫程式。
    然後包成 jar 檔案,接著只要在 spark-submit 的步驟,在 class 的參數下指定該 Object 的名字,就會執行此 Object 底下的程式邏輯。
  • 在公司內,已經有同仁將 spark 等環境建置好,因此我只是將包好的 jar 檔上傳到 master 的機器,並使用 spark-submit 去執行。
    而一般在 local 的測試,只是利用取樣後的,或是極小部分的資料,去驗證程式的邏輯是正確的。而在 local 的設定,則是記得在 SparkSession 中,記得將 master(“local[*]”) 的參數帶入,然後若要丟到 master 機器上跑的時候,記得在包成 jar 前,要把 master(“local[*]”) 取消,詳細的設定可以再自行去搜尋。
val spark = SparkSession.builder().
master("local[*]").
appName("test").
getOrCreate().
...(other parameter)

有問題的部分,歡迎留言相互學習。

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.