Driver:
①、driver進程就是應用的main()函數並且構建sparkContext對象,當我們提交了應用之后,便會啟動一個對應的driver進程,driver本身會根據我們設置的參數占有一定的資源(主要指cpu core和memory)。
②、driver可以運行在master上,也可以運行worker上(根據部署模式的不同)。
③、driver首先會向集群管理者(standalone、yarn,mesos)申請spark應用所需的資源,也就是executor,然后集群管理者會根據spark應用所設置的參數在各個worker上分配一定數量的executor,每個executor都占用一定數量的cpu和memory。在申請到應用所需的資源以后,driver就開始調度和執行我們編寫的應用代碼了。
④、driver進程會將我們編寫的spark應用代碼拆分成多個stage,每個stage執行一部分代碼片段,並為每個stage創建一批tasks,然后將這些tasks分配到各個executor中執行。
Executor:
executor進程宿主在worker節點上,一個worker可以有多個executor。每個executor持有一個線程池,每個線程可以執行一個task,executor執行完task以后將結果返回給driver,
每個executor執行的task都屬於同一個應用。此外executor還有一個功能就是為應用程序中要求緩存的RDD提供內存式存儲,RDD是直接緩存在executor進程內的,
因此任務可以在運行時充分利用緩存數據加速運算。
理解了上面兩個進程的基本概念后,我們可以基於Executor的個數以及每個Executor的cpu core個數進行spark優化:
資源的分配在使用腳本提交Spark任務時進行指定,標准的Spark任務提交腳本如代碼清單所示:
代碼清單標准Spark提交腳本:
/usr/opt/modules/spark/bin/spark-submit \ --class com.atguigu.spark.Analysis \ --num-executors 80 \ --driver-memory 6g \ --executor-memory 6g \ --executor-cores 3 \ /usr/opt/modules/spark/jar/spark.jar \
名稱 | 說明 |
---|---|
--num-executors | 配置Executor的數量 |
--driver-memory | 配置Driver內存(影響不大) |
--executor-memory | 配置每個Executor的內存大小 |
--executor-cores | 配置每個Executor的CPU core數量 |
第一種是Spark Standalone模式,你在提交任務前,一定知道或者可以從運維部門獲取到你可以使用的資源情況,在編寫submit腳本的時候,就根據可用的資源情況進行資源的分配,比如說集群有15台機器,每台機器為8G內存,2個CPU core,那么就指定15個Executor,每個Executor分配8G內存,2個CPU core。
第二種是Spark Yarn模式,由於Yarn使用資源隊列進行資源的分配和調度,在表寫submit腳本的時候,就根據Spark作業要提交到的資源隊列,進行資源的分配,比如資源隊列有400G內存,100個CPU core,那么指定50個Executor,每個Executor分配8G內存,2個CPU core。
名稱 | 解析 |
---|---|
增加Executor·個數 | |
增加每個Executor的CPU core個數 | 在資源允許的情況下,增加每個Executor的Cpu core個數,可以提高執行task的並行度。比如有4個Executor,每個Executor有2個CPU core,那么可以並行執行8個task,如果將每個Executor的CPU core個數增加到4個(資源允許的情況下),那么可以並行執行16個task,此時的並行能力提升了一倍。 |
增加每個Executor的內存量 | 在資源允許的情況下,增加每個Executor的內存量以后,對性能的提升有三點: 1. 可以緩存更多的數據(即對RDD進行cache),寫入磁盤的數據相應減少,甚至可以不寫入磁盤,減少了可能的磁盤IO; 2. 可以為shuffle操作提供更多內存,即有更多空間來存放reduce端拉取的數據,寫入磁盤的數據相應減少,甚至可以不寫入磁盤,減少了可能的磁盤IO; 3. 可以為task的執行提供更多內存,在task的執行過程中可能創建很多對象,內存較小時會引發頻繁的GC,增加內存后,可以避免頻繁的GC,提升整體性能。 |