天天看點

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查

摘要:

Logview是MaxCompute Job送出後檢視和Debug任務的工具。通過Logview可看到一個Job的運作狀态、運作結果以及運作細節和每個步驟的進度。當Job送出到MaxCompute後,會生成Logview的連結,使用者可以直接在浏覽器上打開Logview連結,進入檢視Job的資訊,而對于Logview上的諸多參數資訊,究竟應該怎麼“撥開雲霧”,發現問題所在呢?又如何通過Logview了解每個instance、task運作狀态及資源占用情況,如何分析執行計劃,分析query存在問題,找到Long-Tails task,讓資料分析業務高效又省錢呢?本文中,阿裡巴巴計算平台産品專家雲花将為大家揭曉答案。

直播視訊回看,戳這裡!

https://yq.aliyun.com/webinar/play/484

分享資料下載下傳,戳這裡!

https://yq.aliyun.com/download/2953

更多精彩内容傳送門:

大資料計算技術共享計劃 — MaxCompute技術公開課第二季 以下内容根據演講視訊及PPT整理而成。

本文将主要圍繞以下4個方面進行分享:

  1. 什麼是Logview
  2. 相關概念和原理
  3. Logview參數詳解
  4. 使用Logview排查問題

很多使用者在使用MaxCompute的時候會遇到一些問題,但是卻苦于不知道如何去定位這些問題,也不知道應該如何進行優化。是以,本文整理了一些Logview參數以及問題定位的相關知識與大家分享。

一、什麼是Logview?

Logview是一個在MaxCompute上送出任務之後用來檢視和Debug任務的工具,大家可以通過Logview看到任務的運作狀态,包括任務的排隊情況以及資源的使用情況,甚至在每個節點上Instance運作的細節及其進度。當送出的任務出錯了或者運作時間過長,就可以借助Logview分析具體的原因,進而對任務進行精準優化。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查
二、相關概念和原理

在使用Logview的時候可能會遇到很多名詞,這些名詞都是MaxCompute特有的,是以在本部分中也進行簡單介紹,幫助大家更好地了解Logview的運作原理。

MaxCompute系統架構

如下圖所示的是MaxCompute的系統架構。從上往下看,首先最上層就是資料源和用戶端接入的部分,各種外部資料源都可以通過外部傳輸的工具如Tunnel以及DataHub将資料同步到分布式檔案存儲系統盤古中。在用戶端,使用者可以使用指令行工具、MaxCompute Studio以及DataWorks等開發完任務送出之後,以Restful API形式送出到HTTP服務,當HTTP服務接收到請求之後,先向使用者中心做身份鑒權,是以整個接入層其實承載了資料上傳下載下傳、使用者鑒權以及負載均衡等工作。接入層之下就是管理層,這也是MaxCompute最為核心的部分,這部分負責對使用者空間和對象的管理、指令的解析與執行、對象的通路控制以及授權等功能,其主要有三種角色,即Workers、Scheduler以及Executor。MaxCompute的中繼資料其實是存儲在阿裡雲開放服務——分布式中繼資料服務上。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查

MaxCompute的計算叢集就是架構在飛天系統之上的,而飛天系統的核心子產品包括了分布式檔案存儲系統盤古、分布式資源排程系統伏羲、分布式協同服務女娲以及分布式監控系統神農、遠端過程調用系統誇父、以及安全管理系統鐘馗等。以上就是MaxCompute的基礎架構,其最核心和複雜的邏輯就在管理層與伏羲之間的任務排程和管理。

MaxCompute中繼資料模型

其實MaxCompute以前還有個名字叫做ODPS,從2016年開始ODPS正式改名為MaxCompute,是以其實在Logview中出現的ODPS字樣其實就是指MaxCompute。MaxCompute最常見的兩種對象就是Job,也就是Instance,另外一個就是ODPS Task。比如當送出一個SQL Query的請求,系統就會建立一個Instance,而當這個Instance在MaxCompute上執行的時候就會被分解成多個Task,但是多數情況下Instance與Task是一一對應的。這個Task有SQL類型的、有MR類型的,還有機器學習的。而在底層的分布式系統Fuxi上面也有Job和Task和Instance的概念,而這些需要和MaxCompute上的Task以及Instance的概念區厘清楚。當ODPS Task送出到伺服器上之後,每個Task會被分解成為多個Fuxi Job,而每個Fuxi Job會根據執行計劃分解成不同的執行階段,比如Map、Reduce以及Join等。而每個Task又會啟動多個Instance來執行,相當于啟動多個節點。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查
MaxCompute作業處理流程

首先,使用者會在用戶端送出一個SQL語句,用戶端會通過Restful API形式送出到HTTP服務,HTTP服務的前端接收到這個請求之後會先去使用者中心做鑒權,通過鑒權之後會根據所在叢集資訊轉交給MaxCompute相應的Worker去執行。Worker則會解析這個請求,首先做API的鑒權,有了權限之後才會響應請求。Worker會判斷作業類型,一種是同步任務,也就是說當Worker自己執行完就可以傳回,比如SQL DDL以及Job的查詢狀态等,Worker會通路OTS擷取中繼資料資訊,然後交給Executor執行,執行完成之後就直接傳回給用戶端。另外一種是異步任務,所謂異步任務就是對後續節點進行處理,需要送出到Fuxi去處理的任務,比如SQL的DML或者MR這類的任務請求。Worker會建立一個Instance然後交給Scheduler去執行,Scheduler負責對所有異步任務的排程,它會把Instance分解為Task并做全局的計算排程。當所有資源以及條件都滿足Scheduler就會将Task交給Executor進行執行,Executor上其實封裝了各種業務邏輯,比如SQL以及算法子產品,Executor會根據不同的作業類型拉取不同的作業子產品。當Executor空閑的時候會向Scheduler進行心跳上報并請求任務,當其拿到任務之後會根據任務類型啟動一個相應的業務子產品來執行。Executor會生成一個任務的執行計劃,并将任務以及執行計劃一起交給Fuxi進行執行。有時候送出到Fuxi的任務會出現回退的情況,比如第一次是按照Online Job的作業類型來送出的,到Fuxi之後可能會送出失敗并回退到Scheduler,然後按照Offline的方式再送出一次,這樣就會在Logview看到對應的情況。當Executor将Task送出給Fuxi之後,還會去監控Task的執行狀态,當執行完成之後則會更新OTS裡面的Task資訊并彙報給Scheduler,Scheduler則會判斷整個Instance是否執行完畢,如果執行完畢也會去更新OTS中的Instance資訊,将其設定為Terminated,以上這些就是完整的作業處理流程。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查
三、Logview參數詳解

分享完基本概念和理論之後就可以介紹Logview的參數了。主要的資訊包括ODPS Instance,其涵蓋了隊列資訊以及子狀态資訊,另外一部分包括Fuxi Job,這可以進一步拆解成Task資訊和Fuxi Instance資訊。在整個任務結束之後可以看到其Summary以及Diagnosis診斷資訊,此外還有上傳下載下傳的小功能。

ODPS Instance資訊

下圖中最上面的表中有這樣的幾個字段:URL、Project、InstanceID、Owner、StartTime、EndTime、Latency、Status以及Process等。URL是Endpoint的位址,Project存放項目的名稱,InstanceID其實是時間戳跟着随機字元串,這個時間戳是精确到毫秒的,而這個時間是UTC時間,與電腦送出任務的時間是不一緻的。StartTime和EndTime分别是任務開始和結束的時間,Latency則是任務運作所消耗的時間。而對于Status而言,則有四種狀态:Waiting狀态代表任務正在ODPS中處理,還沒送出到Fuxi中運作;Waiting List代表任務已經到了Fuxi,并且在Fuxi中排隊,N代表排隊的位置;Running代表在Fuxi中運作;Terminated代表運作已經結束了。在表格裡面,隻要Status不是Terminated的狀态,隻要輕按兩下就能打開Queue Detail和SubStatus History詳細資訊。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查
Queue Detail&SubStatus History資訊

如下圖所示最上面的Table是關于隊列的資訊,首先是Fuxi Job的name,SubStatus則是目前Job的運作狀态,Progress是目前的執行進度。紅框裡面有兩個字段,分别是WaitPOS和QueueLength,前者是目前排隊的位置,後者是隊列長度,根據這兩個字段就能看到整個隊列裡面有多少任務在排隊,這個任務排在第幾位。Total Priority是其優先級,點選SubStatus History的圖示可以打開下圖中下側的Table。對于SubStatus History而言着重介紹一下SubStatus Code以及其含義,在下圖中列出了一些常見的SubStatus Code以及其對應含義。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查
Fuxi Job的兩種作業類型

前面也提到了Fuxi Job有兩種作業類型,分别是Online Job和Offline Job,這兩種Job到底有什麼差別呢?首先,對于Offline的作業而言,當每次送出作業時在Fuxi上都會有一個環境準備的時間,對于大資料量并且不需要傳回查詢結果的作業比較合适。而對于小資料量并且實時作業要求比較高的作業是不合适的。是以Fuxi提供了Service Mode這種準實時的作業形式,首先會有一個服務去預先申請計算一些資源并加載出來,比如會預先配置設定一萬個Instance,當有作業送出過來的時候會根據作業規模配置設定一些Instance進行執行,這樣就省去環境準備的時間,是以就會比較快,這就是兩種類型作業的主要差異。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查

對于FuxiJob的命名規則而言,如上圖所示“odps/”後面的部分就是<project_name>_<instanceId>_<task_type>_<odps_task_index>_<task_history>_<fuxi_job_index>_<jobtail>。

ODPS Task資訊

如下圖所示的是ODPS Task資訊,上面的表格的第一個字段是TaskName,Type指的是作業類型,Status指的是運作狀态,輕按兩下Rusult會輸出作業的整個結果集,輕按兩下Detail資訊則會打開整個Fuxi Job的詳細Table。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查
Fuxi Job Detail資訊

Fuxi Job詳細資訊主要分為三個部分,最左側是任務的執行計劃,這個執行計劃是在Executor裡面生成的,執行計劃就是将一個任務分成不同的Stage來執行,每個Stage的都可以看做一個圖上的點,而Stage之間的依賴關系就可以看做圖的邊,這樣就構成一個有向無環圖。在下圖例子中,将Fuxi Job分解成了四個Map的Task,兩個Join的Task,還有3個Reduce的Task。舉例而言,對于J3_1_2這個Task而言,需要在M1和M2執行完成之後才會執行,也就是說M1和M2的輸出就是J3_1_2的輸入,并且在名字上也可以展現其依賴關系,也就是說命名其實是和執行計劃相關的。下圖中右上方這部分就是每個Task的詳細資訊,也是每個Stage的詳細資訊。圖中下面部分則是每個Instance的詳細資訊。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查
Fuxi Task Detail資訊

對于Fuxi Job Detail資訊而言,又有哪些需要關注呢?第一個字段就是TaskName,其和執行計劃的生成是相關的。後面的字段Fatal/Finished/TotalInstCount,在表格裡面Fatal表示嚴重錯誤個數,是以被标紅了;Finished表示已經結束的Instance的個數,後面的TotalInstCount指的是為每個Task啟動的總Task數量。下一個字段I/O Records指的是輸入和輸出的記錄的個數,I/O Bytes指的是輸入和輸出的位元組數。FinishedPercentage指的是進度條,Status則指的是每個Task的運作狀态。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查
Fuxi Instance Detail資訊

Fuxi Instance是整個作業流中最小的顆粒,在如下圖所示的Demo中是一個Map的作業詳細資訊。首先看All字段,這個字段後面有一個數字415,這說明為M3_2這個Task啟動了415個Instance,其左側的Terminated、Running、Ready以及Failed分别是相應狀态的執行個體個數。而SmartFilter則會給出最早結束、最晚結束、運作時間最短和運作時間最長的四個Instance,将其篩選處理友善觀察。Latency Chart則是以圖表的形式展示所有的Instance的運作時長分布,而在Latency裡面則是最長運作時間和最短運作時間以及平均運作時長,其實這三個時間對于分析長尾任務是非常有用的。在每個Instance的表格裡面詳細資訊裡面有一個StdOut,這是每個Instance在執行過程中列印的資訊,而StuErr則是當Instance失敗的時候可以用來檢視出錯原因的。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查
Fuxi Job Detail資訊 之 Summary資訊

FuxiJob的Summary是在整個Job運作完之後才能檢視的資訊,主要包括Job消耗的CPU、記憶體、Job輸入的表名以及記錄數和位元組數。此外,Job的運作時間機關是秒。Fuxi Task的Summary資訊則主要包括Instance數量、Task運作時間、所有Instance裡面的最大、最小和平均運作時間。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查
Tips:用Summary資訊做計量計費參考

這裡與大家分享一個Tips,就是如何用Summary資訊做計量計費參考,比如在這裡執行的是一個MapReduce作業,其計費方法是MR任務當日計算費用=當日總計算時*0.46元(RMB),則任務的計算時=任務運作時間(小時)*任務調用的核數量。而在Summary資訊裡面就能夠直接拿到CPU的計算時,而不需要用公式計算了。而對于SQL計算而言,計算公式為:一次SQL計算費用 = 計算輸入資料量 * SQL複雜度 * SQL價格。而輸入資料量與SQL複雜度都能夠通過cost sql <SQL Sentence>這個指令來計算。對于計量計算而言,更多的内容請參考官網上的資訊。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查
Diagnosis資訊

Diagnosis是診斷資訊,其是在作業執行完成之後可以點選小紅點進而打開如下圖所示的表格。Diagnosis主要會診斷三類資訊,分别是對資源的診斷、對資料傾斜的診斷以及對重新運作的診斷,每類資訊會給出對于問題的說明和問題嚴重等級,并且會給出改進意見。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查
Logview資訊的導入導出

Logview的資訊可以導入和導出,因為其資訊隻能在系統中保留7天,如果想要長期儲存就需要導出資訊。大家可以點選Logview右上角的小圖示将Logview資訊儲存到本地,當需要分析的時候再點選“望遠鏡”小圖示,從本地将Logview資訊上傳上去就可以還原出Logview的資訊。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查
四、使用Logview排查問題

常見的問題有這樣幾種,首先就是任務一直在排隊等待或者任務直接運作失敗了,而最常見的情況就是任務執行時間太長了,一直跑不完。其實大多數慢任務的原因都是因為長尾,而大多數長尾都是因為資料傾斜帶來的。這不僅将會影響資料分析結果的産出,還會拉高資料資源的消費,是以對于這種情況必須要進行優化。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查
1. 任務出錯了

對于出錯任務而言,從控制台輸出就可以看到出錯的原因,如果想要檢視更加詳細的資訊,則可以打開Logview去檢視ODPS的Result資訊,如果失敗了可以看到Status變成紅色了。當輕按兩下Result之後就可以看到報錯輸出的整體資訊。在出錯資訊裡面會有錯誤碼,而錯誤碼與詳細錯誤的對照表可以在官網找到。是以檢視出錯任務的方式有兩種,一種是在作業結束之後檢視其Result資訊,另外一種方式則是去檢視Instance的StdErr資訊。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查
2. 慢任務診斷

(1) 作業排隊

對于慢任務診斷而言,可能看到一種現象就是作業一直在排隊或者在控制台看到Fuxi Job一直在Waiting。進一步在Logview裡面檢視,發現Status到底是Waiting還是Waiting List,這樣就可以發現其到底在哪裡排隊,如果狀态是Waiting List則可以進一步地看其詳細隊列長度到底是多少,排到了第幾位。還可以在SubStatus裡面看到其子狀态的資訊。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查

對于慢任務而言,很多使用者反映不能夠知道到底是哪一個作業是慢任務,是以在這裡為大家介紹兩種檢視慢任務的方法:一種是“show p”,可以檢視所有示例資訊;而“top instance”可以檢視目前正在執行的作業,而運作時間最長的作業可能就是阻塞隊列導緻其他任務排隊的任務。對于由于資源搶占所導緻的問題,可以做如下的優化:

  • 對于後付費使用者而言,可以根據作業特性把相對穩定的周期性正常任務放到預付費資源組去執行,可以保證資源不被搶占。
  • 對于預付費使用者而言,如果并行執行多個作業,最好合理安排作業執行時間,讓作業錯峰執行,臨時任務則建議在後付費資源組執行。而關于作業排隊的原因分析,可以參照雲栖社群的一些相關資源文檔。
帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查

(2) 大量小檔案問題

大量小檔案的存在也會導緻任務執行很慢,比如在作業開始執行的時候,執行計劃可能如下圖中第一張所示,有兩個Map以及一個Join還有一個Reduce,當Reduce的Task執行之後,發現系統自動增加一個MergeTask,這就是因為系統在做合并小檔案的操作。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查

其實,分布式檔案系統的資料檔案是按照塊來存儲的,盤古的塊大小就是64M,是以如果檔案小于64M就可以稱為小檔案。小檔案的産生主要有這樣的3種原因:(1)當Reduce計算過程中會産生大量小檔案;(2)Tunnel資料采集過程中會生成小檔案;(2)Job執行過程中生成的各種臨時檔案、資源回收筒保留的過期檔案等。而因為小檔案過多,就會導緻在Map階段讀取的資料出現分布不均勻的情況,進而引起長尾。如果存在大量的小檔案,除了會浪費資源并降低磁盤空間使用率之外,還會影響整體的執行性能,是以從存儲和性能兩方面考慮都需要将計算過程中的小檔案都合并。其實MaxCompute系統已經做了很多的優化,系統會自動配置設定一個Fuxi的MergeTask來做小檔案的合并,但是其實還有很多情況下産生的小檔案沒有被合并。是以,MaxCompute提供了一些參數幫助使用者進行小檔案的合并。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查

首先可以檢視小檔案的數量,也就是判斷自己的表裡面是否存在很多小檔案。可以用“desc extended TableName”指令就可以輸出小檔案數量。如果小檔案數量很多就可以通過如圖中下面的SQL來整合小檔案。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查

為了避免小檔案的操作,可以給出一些相關建議。比如在Reduce過程中産生的小檔案建議可以使用insert overwrite向原表寫入資料,或者把資料寫入新表之後,将原表删除。其次,為了避免在Tunnel的資料采集過程中産生小檔案,可以調用Tunnel SDK。也就是在上傳資料的時候最好等到Buffer達到64M的時候再進行送出,不要過于頻繁地進行送出。在導入分區表的時候建議為表設定生命周期,對于過期的資料可以進行自動清理。而針對大量臨時表的情況,也可以加上生命周期,到期之後進行自動回收。對于小檔案的優化,在官網文檔中也有更加詳細的介紹。

(3)資料傾斜導緻長尾任務

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查

資料傾斜導緻長尾任務也會導緻慢作業。其實資料傾斜就是因為資料分布不均勻,少數的Fuxi Instance處理的資料量遠遠超過其他的Instance,是以導緻長尾任務。在MaxCompute的Logview裡面,将滑鼠放在Longtails标簽上面就可以看到提示“Latency is more than twice average”,也就是說運作時間超過平均的兩倍,就将其定義為長尾任務。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查

通過Logview有兩種方式檢視其是否屬于長尾任務,第一種方法就是檢視Long-Tails的Fuxi Instances的Max Lantency。如果括号裡面的數量大于0,那就說明已經出現了長尾,點選标簽之後就會将所有長尾Instance列出來,并且可以檢視其各種資訊。另外一種檢視長尾任務的方法就是檢視Fuxi Job的Summary資訊以及Diagnosis資訊,通過分析Summary可以檢視長尾分布在哪個階段。如果instance time的max和avg兩個值相差很大就說明出現了長尾;而對于input records而言,如果輸入資料量的max和avg相差也很大就說明發生了資料傾斜。在Diagnosis資訊裡面專門有一項是檢查資料傾斜和長尾的,是以通過系統所給出的資訊就能夠檢視出是否出現了長尾還是資料傾斜,也同時給出了一些改進意見。

最後與大家分享對于不同種類的資料傾斜分别可以做哪些優化。在Join階段出現的資料傾斜是因為Join Key分布不均勻,導緻某一個Key的值資料量特别大,會被配置設定到同一個Instance上進行處理,這個Instance處理時間就會比較長,是以造成長尾。比如用一個大表來join一個小表或者在key中有大量的空值都會造成Join階段的資料傾斜,對于這種情況可以使用Map Join進行優化,其原理是将Join操作提前到Join階段進行,其實就是将小表裡的資料加載到執行Join操作的程式記憶體中,是以就加速了Join的執行,而Map Join比普通Join性能要好很多,對于有空值的情況,建議先過濾掉空值然後補上随機數,相當于對Key做重新配置設定,然後再進行Join。第二種則是由于Group By導緻的資料傾斜,其産生原因也是由于Group By後面的Key分布不均勻導緻的,這裡有兩種優化方法,一種是設定方傾斜的參數,另外一種則是對Key加上随機數進行重新配置設定。第三種是由于使用Distinct造成的資料傾斜,由于Distinct是對于字段做去重的操作,那麼這樣就沒辦法在Map的Shuffle階段就根據GroupBy做一次聚合操作來減少資料傳輸,它隻能将所有的資料全都傳入到Reduce端來處理,是以當Key的資料發生了不均勻的時候就會導緻Reduce端出現長尾,針對這種情況可以用Count + GroupBy代替Distinct。最後一種就是由于動态分區帶來的長尾,如果動态分區過多的時候就可能造成小檔案過多,而為了整理小檔案,系統會在啟動一個Reduce的Task對資料進行整理,如果動态分區寫入資料有傾斜就會産生長尾,在這種情況下就盡量不要使用動态分區,在insert的時候最好指定相應的分區。對于優化這部分,大家也可以在官網上找到更加詳細的連結。

帶你玩轉Logview: MaxCompute Logview參數詳解和問題排查