2025年2月22日 星期六

Spark 新手筆記(二):在本機打開 Spark History Server 查看 event logs

這篇要紀錄如何使用 Spark History Server。因為我們專案在使用 AWS EMR 時,是可以在 AWS 上打開 Spark History Server,但一方面打開要開很久,而且一段時間沒去存取的話,Server 又會自動被關掉,另一方面在 AWS 開的 History Server 常遇到一些奇怪的問題,但好像又沒辦法對它做什麼調整,所以就在想說有沒有辦法把資料下載到本機,在本機開 Spark History Server 呢?結論來說,是可以的,這篇就會紀錄在本機要如何使用 Spark History Server。

選擇合適的 Spark 版本

首先在開始之前,先提一下我試了一個下午的結果,目前 Spark 最新版的 3.5.x 因為底下會用到 Jackson 2.15.x,這個版本的 Jackson 引入了 JSON 長度的限制,而且現在這個限制似乎是無法調整的。Github 上有對應的 issuePR 想要改成沒有限制長度,但寫這篇文章的現在,這個 PR 還沒有被 merge。回到問題本身,具體來說,這個問題會導致長度超過 20M 的 Spark event logs 沒辦法被 History Server 讀取,會拋出類似以下的錯誤訊息:

URI:    /history/application_1739961940470_0001/1/jobs/
STATUS:    500
MESSAGE:    com.fasterxml.jackson.core.exc.StreamConstraintsException: String length (20054016) exceeds the maximum length (20000000)
SERVLET:    org.apache.spark.deploy.history.HistoryServer$$anon$1-2787de58
CAUSED BY:    com.fasterxml.jackson.core.exc.StreamConstraintsException: String length (20054016) exceeds the maximum length (20000000)

而以本機來說,最簡單又快速的解法,就是去下載 Spark 3.4.x 或更早以前的版本,3.4.x 版的 Spark 使用的 Jackson 版本是 2.14.x,就可以避開這個問題了。

設定相關的 History Server 參數

這個步驟可能不一定是必要的,只是因為 History Server 都有預設設定,但預設設定不見得符合需求,所以適度調整一下會比較方便。

首先,History Server 預設會去 file://tmp/event-logs 資料夾尋找 event logs,但如果不想把 event logs 放在暫存資料夾,可以指定一個別的資料夾讓 History Server 去讀取。作法是把 Spark 資料夾中的 conf/spark-defaults.conf.template 更名成 conf/spark-defaults.conf,然後寫上以下的設定:

spark.history.fs.logDirectory=/YOUR/PREFERRED/PATH

另外 Spark History Server 預設使用的記憶體是 1GB,但如果你會讀非常龐大的 event logs 的話,1GB 很有可能會不夠用,這時打開 History Server 後,可能會在 job 頁面看到類似以下的錯誤訊息:

URI:    /history/application_1739961940470_0001/1/jobs/
STATUS:    500
MESSAGE:    org.sparkproject.guava.util.concurrent.ExecutionError: java.lang.OutOfMemoryError: Java heap space
SERVLET:    org.apache.spark.deploy.history.HistoryServer$$anon$1-27b71f50
CAUSED BY:    org.sparkproject.guava.util.concurrent.ExecutionError: java.lang.OutOfMemoryError: Java heap space
CAUSED BY:    java.lang.OutOfMemoryError: Java heap space

這時要增加可用的記憶體,可以去修改 daemon memory 設定,這個設定是放在另一個檔案,所以要先把 conf/spark-env.sh.template 改名成 conf/spark-env.sh,然後在裡面加上以下的設定,把記憶體改成你想要的用量,這邊的例子是改成 4GB。

SPARK_DAEMON_MEMORY="4g"

啟動與關閉 Spark History Server

在本機啟動 History Server,只要去 Spark 資料夾內的 sbin 資料夾裡執行 start-history-server 即可。執行後如果想看 History Server 有沒有預期的反應,可以去查看 /logs 資料夾裡的 log。

以下是執行的範例:

$ cd spark-3.4.4-bin-hadoop3-scala2.13/sbin/
$ ./start-history-server
starting org.apache.spark.deploy.history.HistoryServer, logging to /mnt/d/spark-3.4.4-bin-hadoop3-scala2.13/logs/spark-jimwayne-org.apache.spark.deploy.history.HistoryServer-1-JW-HOMEPC-12700.out
$ tail -f ../logs/spark-jimwayne-org.apache.spark.deploy.history.HistoryServer-1-JW-HOMEPC-12700.out
25/02/22 22:12:56 INFO SecurityManager: Changing view acls groups to:
25/02/22 22:12:56 INFO SecurityManager: Changing modify acls groups to:
25/02/22 22:12:56 INFO SecurityManager: SecurityManager: authentication disabled; ui acls disabled; users with view permissions: jimwayne; groups with view permissions: EMPTY; users with modify permissions: jimwayne; groups with modify permissions: EMPTY
25/02/22 22:12:56 INFO FsHistoryProvider: History server ui acls disabled; users with admin permissions: ; groups with admin permissions:
25/02/22 22:12:56 INFO JettyUtils: Start Jetty 0.0.0.0:18080 for HistoryServerUI
25/02/22 22:12:56 INFO Utils: Successfully started service 'HistoryServerUI' on port 18080.
25/02/22 22:12:56 INFO HistoryServer: Bound HistoryServer to 0.0.0.0, and started at http://10.255.255.254:18080
25/02/22 22:12:56 INFO FsHistoryProvider: Parsing file:/mnt/d/spark-events/application_1739961940470_0001_1 for listing data...
25/02/22 22:12:57 INFO FsHistoryProvider: Looking for end event; skipping 1919341552 bytes from file:/mnt/d/spark-events/application_1739961940470_0001_1...
25/02/22 22:12:57 INFO FsHistoryProvider: Finished parsing file:/mnt/d/spark-events/application_1739961940470_0001_1

上面可以從 log 看出,啟動成功後,Spark History Server 會開在 http://localhost:18080,並且會自動開始讀取 spark.history.fs.logDirectory 設定的資料夾裡面的 event logs 檔案。因為我已經在裡面放了一個從 EMR 下載下來並解壓縮的檔案,所以它可以掃到並開始解析這個檔案。

最後,用瀏覽器打開 http://localhost:18080 就可以進入 Spark History Server 查看了。要看在雲端或其他環境執行的狀況,就去把那邊的 Spark event logs 下載回來,放在 spark.history.fs.logDirectory 指定的目錄即可。

PS. 目前測試 History Server 好像無法接受 ZIP,雖然 ChatGPT 跟我說 Spark History Server 可以支援壓縮檔…。

到這裡,就可以避開文章最開始提到 AWS EMR 的 Spark History Server 常常打不開的各種奇怪問題了!雖然說第一步還是得先打開 EMR 上的 Spark History Server,並且上去下載 event logs 啦 😆

沒有留言: