資源是影響 Spark 應用執行效率的一個重要因素。Spark 應用中真正執行 task 的元件是 Executor,可以通過spark.executor.instances 指定 Spark 應用的 Executor 的數量。在運作過程中,無論 Executor上是否有 task 在執行,都會被一直占有直到此 Spark 應用結束。
上篇我們從動态優化的角度講述了 Spark 3.0 版本中的自适應查詢特性,它主要是在一條 SQL 執行過程中不斷優化執行邏輯,選擇更好的執行政策,進而達到提升性能的目的。本篇我們将從整個 Spark 叢集資源的角度讨論一個常見痛點:資源不足。
在 Spark 叢集中的一個常見場景是,随着業務的不斷發展,需要運作的 Spark 應用數和資料量越來越大,靠資源堆砌的優化方式也越來越顯得捉襟見肘。當一個長期運作的 Spark 應用,若配置設定給它多個 Executor,可是卻沒有任何 task 配置設定到這些 Executor 上,而此時有其他的 Spark 應用卻資源緊張,這就造成了資源浪費和排程不合理。

要是每個 Spark 應用的 Executor 數也能動态調整那就太好了。
動态資源配置設定(Dynamic Resource Allocation)就是為了解決這種場景而産生。Spark 2.4 版本中 on Kubernetes 的動态資源并不完善,在 Spark 3.0 版本完善了 Spark on Kubernetes 的功能,其中就包括更靈敏的動态配置設定。我們 Erda 的 FDP 平台(Fast Data Platform)從 Spark 2.4 更新到 Spark 3.0,也嘗試了動态資源配置設定的相關優化。本文将針對介紹 Spark 3.0 中 Spark on Kubernetes 的動态資源使用。
一個 Spark 應用中如果有些 Stage 稍微資料傾斜,那就有大量的 Executor 是空閑狀态,造成叢集資源的極大浪費。通過動态資源配置設定政策,已經空閑的 Executor 如果超過了一定時間,就會被叢集回收,并在之後的 Stage 需要時可再次請求 Executor。
如下圖所示,固定 Executor 個數情況,Job1 End 和 Job2 Start 之間,Executor 處于空閑狀态,此時就造成叢集資源的浪費。
開啟動态資源配置設定後,在 Job1 結束後,Executor1 空閑一段時間便被回收;在 Job2 需要資源時再申Executor2,實作叢集資源的動态管理。
動态配置設定的原理很容易了解:“按需使用”。當然,一些細節還是需要考慮到:
何時新增/移除 Executor
Executor 數量的動态調整範圍
Executor 的增減頻率
Spark on Kubernetes 場景下,Executor 的 Pod 銷毀後,它存儲的中間計算資料如何通路
這些注意點在下面的參數清單中都有相應的說明。
無圖無真相,下面我們将動态資源配置設定進行簡單示範。
動态資源配置設定相關參數配置如下圖所示:
如下圖所示,Spark 應用啟動時的 Executor 個數為 2。因為配置了

運作一段時間後效果如下,executorNum 會遞增,因為空閑的 Executor 被不斷回收,新的 Executor 不斷申請。
使用 SparkThrfitServer 會遇到的問題是一個資料量很大的 SQL 把所有的資源全占了,導緻後面的 SQL 都等待,即使後面的 SQL 隻需要幾秒就能完成。我們開啟動态配置設定政策,再來看 SQL 執行順序。
先送出慢 SQL:
再送出快 SQL:
如下圖所示,開啟動态資源配置設定後,因為 SparkThrfitServer 可以申請新的 Executor,後面的 SQL 無需等待便可執行。Job7(慢 SQL)還在運作中,後送出的 Job8(快 SQL)已完成。這在一定程度上緩解了資源配置設定不合理的情況。
我們在 SparkWebUI 上可以看到動态配置設定的整個流程。
登陸 SparkWebUI 頁面,Jobs -> Event Timeline,可以看到 Driver 對整個應用的 Executor 排程。如下圖所示,顯示了每個 Executor 的建立和回收。
同時也能看到此 Executor 的具體建立和回收時間。
在 Executors 标簽頁,我們可以看到所有曆史 Executor 的目前狀态。如下圖所示,之前的 Executor 都已被回收,隻有 Executor-31 狀态為 Active。
動态資源配置設定政策在空閑時釋放 Executor,繁忙時申請 Executor,雖然邏輯比較簡單,但是和任務排程密切相關。它可以防止小資料申請大資源,Executor 空轉的情況。在叢集資源緊張,有多個 Spark 應用的場景下,可以開啟動态配置設定達到資源按需使用的效果。
以上是我們在 Spark 相關優化的一點經驗,希望能夠對大家有所幫助😄。
注:文中部分圖檔源自于網絡,侵删。
更多技術幹貨請關注【爾達 Erda】公衆号,與衆多開源愛好者共同成長~