圖一java
第一行(標記爲 [A])展現了Streaming應用程序當前的狀態;在這個例子中,應用已經以1秒的批處理間隔運行了將近40分鐘;在它下面是輸入速率(Input rate)的時間軸(標記爲 [B]),顯示了Streaming應用從它全部的源頭以大約49 events每秒的速度接收數據。在這個例子中,時間軸顯示了在中間位置(標記爲[C])平均速率有明顯的降低,在時間軸快結束的地方應用又恢復了。若是你想獲得更多詳細的信息,你能夠點擊 Input Rate旁邊(靠近[B])的下拉列表來顯示每一個源頭各自的時間軸,正以下面圖2所示:sql
圖二api
圖2顯示了這個應用有兩個來源,(SocketReceiver-0和 SocketReceiver-1),其中的一個致使了整個接收速率的降低,由於它在接收數據的過程當中中止了一段時間。緩存
這一頁再向下(在圖1中標記爲 [D] ),處理時間(Processing Time)的時間軸顯示,這些批次大約在平均20毫秒內被處理完成,和批處理間隔(在本例中是1s)相比花費的處理時間更少,意味着調度延遲(被定義爲:一個批次等待以前批次處理完成的時間,被標記爲 [E])幾乎是零,由於這些批次在建立的時候就已經被處理了。調度延遲是你的Streaming引用程序是否穩定的關鍵所在,UI的新功能使得對它的監控更加容易。分佈式
批次細節性能
再次參照圖1,你可能很好奇,爲何向右的一些批次花費更長的時間才能完成(注意圖1中的[F])。你能夠經過UI輕鬆的分析緣由。首先,你能夠點擊時間軸視圖中批處理時間比較長的點,這將會在頁面下方產生一個關於完成批次的詳細信息列表。測試
圖三優化
它將顯示這個批次的全部主要信息(在上圖3中以綠色高亮顯示)。正如你所看到的,這個批次較之其餘批次有更長的處理時間。另外一個很明顯的問題是:究竟是哪一個spark job引發了這個批次的處理時間過長。你能夠經過點擊Batch Time(第一列中的藍色連接),這將帶你看到對應批次的詳細信息,向你展現輸出操做和它們的spark job,正如圖4所示。ui
圖四spa
圖4顯示有一個輸出操做,它產生了3個spark job。你能夠點擊job ID連接繼續深刻到stages和tasks作更深刻的分析。此後跟spark sql的ui差很少,以下。
上面就是Spark的UI主頁,首先進來能看到的是Spark當前應用的job頁面,在上面的導航欄:
下面挨個介紹一下各個頁面的使用方法和實踐,爲了方便分析,我這裏直接使用了分佈式計算裏面最經典的helloworld程序——WordCount,這個程序用於統計某一段文本中一個單詞出現的次數。原始的文本以下:
for the shadow of lost knowledge at least protects you from many illusions
上面這句話是有一次逛知乎,一個標題爲 讀那麼多書,最後也沒記住多少,還爲何讀書?其中有一個回覆,引用了上面的話,也是我最喜歡的一句。意思是:「知識,哪怕是知識的幻影,也會成爲你的鎧甲,保護你不被愚昧反噬」(來自知乎——《爲何讀書?》)
程序代碼以下:
public static void main(String[] args) throws InterruptedException { SparkConf sparkConf = new SparkConf(); sparkConf.setMaster("local[2]"); sparkConf.setAppName("test-for-spark-ui"); JavaSparkContext sc = new JavaSparkContext(sparkConf); //知識,哪怕是知識的幻影,也會成爲你的鎧甲,保護你不被愚昧反噬。 JavaPairRDD<String,Integer> counts = sc.textFile( "C:\\Users\\xinghailong\\Desktop\\你爲何要讀書.txt" ) .flatMap(line -> Arrays.asList(line.split(" "))) .mapToPair(s -> new Tuple2<String,Integer>(s,1)) .reduceByKey((x,y) -> x+y); counts.cache(); List<Tuple2<String,Integer>> result = counts.collect(); for(Tuple2<String,Integer> t2 : result){ System.out.println(t2._1+" : "+t2._2); } sc.stop(); }
這個程序首先建立了SparkContext,而後讀取文件,先使用` `進行切分,再把每一個單詞轉換成二元組,再根據key進行累加,最後輸出打印。爲了測試storage的使用,我這對計算的結果添加了緩存。
主頁能夠分爲兩部分,一部分是event timeline
,另外一部分是進行中和完成的job任務。
第一部分event timeline
展開後,能夠看到executor建立的時間點,以及某個action觸發的算子任務,執行的時間。經過這個時間圖,能夠快速的發現應用的執行瓶頸,觸發了多少個action。
第二部分的圖表,顯示了觸發action的job名字,它一般是某個count,collect等操做。有spark基礎的人都應該知道,在spark中rdd的計算分爲兩類,一類是transform轉換操做,一類是action操做,只有action操做纔會觸發真正的rdd計算。具體的有哪些action能夠觸發計算,能夠參考api。collect at test2.java:27
描述了action的名字和所在的行號,這裏的行號是精準匹配到代碼的,因此經過它能夠直接定位到任務所屬的代碼,這在調試分析的時候是很是有幫助的。Duration
顯示了該action的耗時,經過它也能夠對代碼進行專門的優化。最後的進度條,顯示了該任務失敗和成功的次數,若是有失敗的就須要引發注意,由於這種狀況在生產環境可能會更廣泛更嚴重。點擊能進入該action具體的分析頁面,能夠看到DAG圖等詳細信息。
在Spark中job是根據action操做來區分的,另外任務還有一個級別是stage,它是根據寬窄依賴來區分的。
窄依賴是指前一個rdd計算能出一個惟一的rdd,好比map或者filter等;寬依賴則是指多個rdd生成一個或者多個rdd的操做,好比groupbykey reducebykey等,這種寬依賴一般會進行shuffle。
所以Spark會根據寬窄依賴區分stage,某個stage做爲專門的計算,計算完成後,會等待其餘的executor,而後再統一進行計算。
stage頁面的使用基本上跟job相似,不過多了一個DAG圖。這個DAG圖也叫做血統圖,標記了每一個rdd從建立到應用的一個流程圖,也是咱們進行分析和調優很重要的內容。好比上面的wordcount程序,就會觸發acton,而後生成一段DAG圖:
從這個圖能夠看出,wordcount會生成兩個dag,一個是從讀數據到切分到生成二元組,第二個進行了reducebykey,產生shuffle。
點擊進去還能夠看到詳細的DAG圖,鼠標移到上面,能夠看到一些簡要的信息。
storage頁面能看出目前使用的緩存,點擊進去能夠看到具體在每一個機器上,使用的block的狀況。
這個頁面通常不太用,由於環境基本上不會有太多差別的,不用時刻關注它。
這個頁面比較經常使用了,一方面經過它能夠看出來每一個excutor是否發生了數據傾斜,另外一方面能夠具體分析目前的應用是否產生了大量的shuffle,是否能夠經過數據的本地性或者減少數據的傳輸來減小shuffle的數據量。
在Spark應用裏面能夠直接使用System.out.println把信息輸出出來,系統會直接攔截out輸出到spark的日誌。像咱們使用的yarn做爲資源管理系統,在yarn的日誌中就能夠直接看到這些輸出信息了。這在數據量很大的時候,作一些show()(默認顯示20),count() 或者 take(10)的時候會很方便。
當任務失敗,收到sparkContext shutdown的信息時,基本都是執行者的內存不夠。這個時候,一方面能夠調大--excutor-memory參數,另外一方面仍是得回去看看程序。若是受限於系統的硬件條件,沒法加大內存,能夠採用局部調試法,檢查是在哪裏出現的內存問題。好比,你的程序分紅幾個步驟,一步一步的打包運行,最後檢查出現問題的點就能夠了。
線程池不夠,這個是由於--excutor-core給的太少了,出現線程池不夠用的狀況。這個時候就須要調整參數的配置了。
這種問題通常是driver memory不夠致使的,driver memory一般存儲了以一些調度方面的信息,這種狀況頗有多是你的調度過於複雜,或者是內部死循環致使。
在Spark的計算中,不太建議直接使用cache,萬一cache的量很大,可能致使內存溢出。能夠採用persist的方式,指定緩存的級別爲MEMORY_AND_DISK,這樣在內存不夠的時候,能夠把數據緩存到磁盤上。另外,要合理的設計代碼,恰當地使用廣播和緩存,廣播的數據量太大會對傳輸帶來壓力,緩存過多未及時釋放,也會致使內存佔用。通常來講,你的代碼在須要重複使用某一個rdd的時候,才須要考慮進行緩存,而且在不使用的時候,要及時unpersist釋放。
這個點,在優化的過程當中是很重要的。好比你須要把兩個rdd按照某個key進行groupby,而後在進行leftouterjoin,這個時候必定要考慮大小表的問題。若是把大表關聯到小表,那麼性能極可能會很慘。而只須要簡單的調換一下位置,性能就可能提高好幾倍。