記一次spark中task卡頓引發的血案

記一次spark中task卡頓引發的血案

背景介紹:
由於spark-steaming中其中一個job中某個task卡頓,導致平均30s的平均處理時間的task,整整耗費了10個小時。
問題的排查差不多花費了一週的時間,可以說爲解決這個問題,同時摻雜其他工程化的事情,真的一週心情都不好了。
這裏特此記錄一下吧,給自己做個了斷!嘿嘿~

前言提要

(1)當前spark採用粗粒度的執行方式,資源申請都是一次性的完成;不存在後期申請不到資源的情況;

(2)數據量很小,每秒100條左右,基本不存在數據傾斜的問題,但是執行的業務流程很複雜;

(3)採用spark on mesos的組粒度模式運行

1.問題描述:

  • 2019年12月24日ML處理30個文件時間很異常超過10h;

  • xx中部分task處理時間超長,導致整個任務job失敗的問題;

1.1 spark ui 卡頓情況

查看spark ui的監控發現,如下圖:

在這裏插入圖片描述
圖 1 其中的spark中部分task已經卡頓超過10個小時

備註:spark中其中一個task已經卡頓超過10個小時,其他task很快就完成了;

1.2查看服務器日誌:

沒有發現明顯的異常日誌,

19/12/27 01:25:45 INFO ContextCleaner: Cleaned RDD 93
19/12/27 01:25:45 INFO BlockManagerInfo: Removed broadcast_49_piece0 on 172.19.32.131:37463 in memory (size: 8.5 KB, free: 3.6 GB)
19/12/27 01:25:45 INFO BlockManagerInfo: Removed broadcast_49_piece0 on 172.19.32.121:46267 in memory (size: 8.5 KB, free: 42.4 GB)
19/12/27 01:25:45 INFO BlockManagerInfo: Removed broadcast_49_piece0 on 172.19.32.68:33141 in memory (size: 8.5 KB, free: 42.3 GB)
19/12/27 01:25:45 INFO BlockManager: Removing RDD 95
19/12/27 01:25:45 INFO ContextCleaner: Cleaned RDD 95
19/12/27 01:25:45 INFO BlockManager: Removing RDD 121
19/12/27 01:25:45 INFO ContextCleaner: Cleaned RDD 121
19/12/27 01:25:45 INFO ContextCleaner: Cleaned shuffle 9
19/12/27 01:26:00 INFO JobScheduler: Added jobs for time 1577409960000 ms
19/12/27 01:27:00 INFO JobScheduler: Added jobs for time 1577410020000 ms
19/12/27 01:28:00 INFO JobScheduler: Added jobs for time 1577410080000 ms
19/12/27 01:29:00 INFO JobScheduler: Added jobs for time 1577410140000 ms
19/12/27 01:30:00 INFO JobScheduler: Added jobs for time 1577410200000 ms
19/12/27 01:31:00 INFO JobScheduler: Added jobs for time 1577410260000 ms
19/12/27 01:32:00 INFO JobScheduler: Added jobs for time 1577410320000 ms
19/12/27 01:33:00 INFO JobScheduler: Added jobs for time 1577410380000 ms
19/12/27 01:34:00 INFO JobScheduler: Added jobs for time 1577410440000 ms
19/12/27 01:35:00 INFO JobScheduler: Added jobs for time 1577410500000 ms
19/12/27 01:36:00 INFO JobScheduler: Added jobs for time 1577410560000 ms
19/12/27 01:37:00 INFO JobScheduler: Added jobs for time 1577410620000 ms
19/12/27 01:38:00 INFO JobScheduler: Added jobs for time 1577410680000 ms
19/12/27 01:39:00 INFO JobScheduler: Added jobs for time 1577410740000 ms

2.問題解決過程

1.懷疑1 :spark 中由於網絡不穩定

錯誤報異常:spark-submit 超時 Executor heartbeat timed out after 123574 ms
已經排除了內存原因,因爲內存很充足;

剛開始認爲是網絡原因導致一直沒有響應,於是增加執行超時時間。

spark-submit 
–conf spark.network.timeout=10000000 \

之後這錯誤不再報出。

2.懷疑2:某些原因導致task執行太慢

於是採用spark的”推斷執行“機制;–不管用

https://blog.csdn.net/baifanwudi/article/details/89377890

https://blog.csdn.net/hanxiaohei99/article/details/91981672

如何開啓推測執行
將參數spark.speculation設置爲TRUE即可。
spark.speculation=true

相關參數:
spark.speculation.interval 100:檢測週期,單位毫秒
spark.speculation.quantile 0.75:完成task的百分比
spark.speculation.multiplier 1.5:時間比例

spark.speculation.interval 參數的意思是設置檢測週期,默認100毫秒檢測一次是否執行推測執行。
spark.speculation.quantile 參數的意思是同一個stage裏面有task完成的百分比,默認爲75%。
spark.speculation.multiplier 這個參數是一個時間比例。意思是當task完成了75%的時候,取完成了的task的執行時間的中位數,再乘以這個時間比例,默認爲1.5。當未完成的task的執行時間超過了這個乘積值,就開啓推測執行。

缺點:推測執行有數據重複的問題,當心!

3.懷疑.查看cpu負載情況----[有效解決問題]

3.1參考到這個:

https://blog.csdn.net/weixin_42340179/article/details/82415085
在這裏插入圖片描述

於是查看cpu

前提是找到對應的executor耗時的task所在的機器

在這裏插入圖片描述

​ 圖 2-1 top命令查看進程消耗cpu
在這裏插入圖片描述

​ 圖 2-2 top 查看進程中的線程cpu

備註:可以看到進程中的線程cpu之一出現100%的高負載,基本確定是task出現複雜計算(近似死循環)

3.2技術路線:

(1)通過查看CPU參數發現:發現部分task的線程cpu使用100%;可能是複雜的邏輯導致task任務異常超時;(近乎死循環);
(2)在已經確定cpu高負載的情況下,需要排查業務邏輯部分的個別方法的耗時時間。
決定通過elk來查看各個方法的耗時時間;
(3)根據spark ui,確定了卡頓job的開始時間time和卡頓時刻的機器host名稱;最後在elk中添加過濾條件,在結果集中確定最終導致cpu打滿的方法method和數據記錄名稱;
(4)反過來,在去邏輯中測試、修改相應的業務邏輯;

======================================================

最終在elk中定位到該問題。確實是其中的某個方法導致高負載的cpu運算;

hod和數據記錄名稱;
(4)反過來,在去邏輯中測試、修改相應的業務邏輯;

======================================================

最終在elk中定位到該問題。確實是其中的某個方法導致高負載的cpu運算;

發佈了164 篇原創文章 · 獲贊 87 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章