一、MaxCompute作業基本概念
MaxCompute有很多專業術語,logview 中內容直接沿用了這些術語,為了便於理解logview ,首先需要理解相關概念。

控制集群:
- Job/Instance/MaxCompute Instance:代表用戶提交的作業,每個作業具有instanceId 進行唯一標示。
- Task/MaxCompute Task:作業在運行時所屬的類型,例如SQL task, LOT Task,Graph Task 等,一般一個Instance 只有一個Task,所以logview 2.0 隱藏了該信息。(1.0 是有的)
計算集群:
- Fuxi:作業實際計算層,以fuxi job -》 fuxi task -》 fuxi instance 層級遞進。
- DAG 圖:fuxi task 具有依賴關係,連接所有 fuxi task 構成了有向無環圖。
- Operator:fuxi task 內部的算子,例如TableScan,TableSink,是數據處理的邏輯。

二、Logview 的生成過程
Logview 是用於查看MaxCompute作業的工具,可以展示作業實際執行的每一處細節。當作業運行出錯,運行變慢等都需要通過logview進行定位。

LogviewURL結構:logview域名 + MaxCompute endpoint + project + instanceId + token + other parameters,例如:https://logview.aliyun.com/logview/?h=http://service.cn.maxcompute.aliyun.com/api&p=huadong_1_test&i=20201103031620528g3e7n4pr2&token=eEdUUEI0SWh3ZUFVS043SitFT21PUm5mQ3RvPSxPRFBTX09CTzoxNzY3OTc2MDA5NDY4MDcxLDE2MDY5NjUzODAseyJTdGF0ZW1lbnQiOlt7IkFjdGlvbiI6WyJvZHBzOlJlYWQiXSwiRWZmZWN0IjoiQWxsb3ciLCJSZXNvdXJjZSI6WyJhY3M6b2RwczoqOnByb2plY3RzL2h1YWRvbmdfMV90ZXN0L2luc3RhbmNlcy8yMDIwMTEwMzAzMTYyMDUyOGczZTduNHByMiJdfV0sIlZlcnNpb24iOiIxIn0=
有效期:和logview 1.0 一樣,2.0 也有有效期,一般是30天。
三、Logview 原理
Logview 跟常規web應用一樣,由前後端組成,前端渲染頁面,後端彙總MaxCompute 各種運行信息。
Logview 1.0 原理非常簡單,就是一個頁面展示+代理,所有頁面展示的內容都是調用MaxCompute 的restful api 實現,2.0 實現稍微複雜些,數據源更加豐富,支持一些定製化任務展示。

四、Logview 1.0 VS 2.0
logview 2.0 相比於1.0 重新升級頁面風格,簡化作業查看流程,提供1.0 原有數據前提下,增強了DAG 展示、作業回放等功能。

1.0 vs 2.0

相比於logview1.0 ,2.0 隱藏了MaxCompute task 信息,因為MaxCompute 作業默認只有一個MaxCompute task,直接展示fuxi job/fuxi task 信息。
4.1 上部為功能區
包含三個按鈕,打開本地離線logview文件,返回1.0,保存離線logview文件。注意2.0和1.0 的離線文件不兼容。
4.2 左側為基本信息
重點可以看Queue字段,如果發生排隊,該字段顯示排隊位置。
4.3 右側為多Tab 頁面結構
新增了SubStatusHistory 和OperationHistory Tab, subStatusHistory跟1.0 subStatus相同。OperationHistory 可以顯示哪些人對該作業進行過操作,例如看被誰kill了。
4.3.1 JobDetail Tab
上部分為DAG圖,下部分為Fuxi Job-》Fuxi Task -》 Fuxi Instance。
這裡重點關注DAG圖,默認為Fuxi Task 層圖,雙擊進入Operator層,支持進度圖/熱度圖,作業回放。作業回放原理是將作業運行時間劃分成120幀,每一幀計算出對應的進度/熱度等,連續播放120幀。可以快速查看出關鍵fuxi task。注意running 時不支持回放功能。
4.3.2 Result Tab
Result tab 有多種模式,select 語句的結果, 作業運行失敗原因展示。
result 結果支持以文本和表格兩種方式展示,可通過設置以下flag 修改,默認為表格展示方式。
set odps.sql.select.output.format=HumanReadable;

4.3.3 substatusHistory Tab

| Waiting for scheduling | 作業已提交,等待MaxCompute 框架調度,一般很短 |
|---|---|
| Waiting for cluster resource | 框架發現fuxi 計算集群沒資源,直接等 |
| Waiting for concurrent task slot | project 級別流控,project 可以設置並行提交sql個數,彈內不限制,公共雲限制,有限制後這個就是流控。 |
| Waiting for data replication | 等待數據複製 |
| Waiting for execution slot | 這個是系統級別流控 |
| Waiting for cleaning up of previous task attempt | 等待清理執行歷史完成 |
| Waiting for execution | 從父進程隊列拿出來分發給子進程執行過程,一般很快。 |
| Waiting lazy package launching | |
| Updating package version | |
| Preparing for execution | 明確知道交給子進程,如果子進程出問題才會時間長。 |
| Task is executing | 作業在框架處理中 |
| SQLTask is initializing | sql 作業初始化中 |
| SQLTask is compiling query | sql 作業編譯中 |
| SQLTask is optimizing query | sql 作業優化query,如果執行計劃複雜,優化時間會稍長,但過長可能就是bug |
| SQLTask is splitting data sources | sql 作業優化中,切分data sources |
| SQLTask is generating execution plan | sql 作業生成執行計劃中,時間長可能是讀取分區太多,或者小文件太多 |
| SQLTask is submitting execution plan | sql 作業提交執行計劃 |
| Job has been submitted | 作業提交計算集群 |
| Offline Job Waiting for running | 提交後發現fuxi 集群quota組沒資源,是等第一份資源,本來以為有,實際提交後發現沒了,就會等待。只會出現一次,後面就算沒資源也不會顯示了。 |
| Offline Job is running | fuxi 作業執行中, 如果運行中沒資源,會一直是該狀態,比如高優先級作業搶佔資源,導致部分fuxi instance 起不來,狀態是ready |
| Offline Job is failed | fuxi 作業執行失敗 |
| Offline Job is succeed | fuxi 作業執行成功 |
| SQLTask is updating meta information | SQL作業更新元數據信息,生成動態分區時,可能會稍長 |
| SQLTask is finishing | SQl 作業執行結束 |
| Online Job is cancelled by fuxi | service mode 模式被取消 |
| Task rerun | 作業重跑,可能是service mode 失敗,採用offline job,也可能是數據跨集群複製 |
| Online Job Waiting for running | service mode 等待運行 |
| Online Job is running | service mode 模式運行中 |
| Online Job is failed | service mode 模式執行失敗 |
| Online Job is succeed | service mode 模式運行成功 |
| Online Job is cancelled by fuxi | service mode 模式作業被取消 |
| Task key-path executing finished | 作業關鍵路徑完成,但是detailstatus 等尚未完成 |
| Task key-path is finished | Task關鍵路徑完成 |
| Instance key-path is finished | Instance 關鍵路徑完成 |
| Task execution is finished | task處理完成,生成detailStatus |
| Instance execution is finished | 作業處理完成 |
| Execution failed | 作業執行失敗 |
五、使用logview分析作業
5.1 分析運行出錯作業
作業運行失敗時,通過logview 查看result 可以查看出錯信息,對於失敗的作業,打開logview 默認會跳轉到result tab。常見失敗包括:
(1) sql 語法錯誤,此時不會有DAG 和fuxi jobs,因為還沒有提交到計算集群執行
(2) 用戶udf 出錯,調查步驟result -》 DAG 確定出問題的udf -》 查看stdout/stderror等
(3) 除明確提示的錯誤,其他問題多數需要找MaxCompute 值班同學排查。
5.2 分析運行慢作業
5.2.1 編譯階段
首先,查看作業排隊情況, 如果queue > 0 ,說明等待資源,排隊中,一般除了增加計算資源,只能找出佔用大戶,評估是否可以kill 掉,讓出資源。
其次,就算作業運行起來了, queue = 0, 可能還會存在等計算資源情況, 比如高優先級作業搶佔, 此時表現是subStatus 為OfflineJob is Running 或OfflineJob waiting for run,查看fuxi instance 狀態,有大量waiting 或ready 狀態。
對於結束後的作業如何分析當時是否等資源可以通過latency chart ,理想的latency chart, 底部應該是一條直線,說明作業同時啟動了,如果是條斜線說明存在等資源情況。
5.2.2 運行階段
後面就是運行中慢了,可能有幾種情況數據傾斜,數據膨脹,UDF執行效率低,作業發生重跑。
數據傾斜
【特徵】task 中大多數 instance 都已經結束了,但是有某幾個 instance 卻遲遲不結束(長尾)。如下圖中大多數(358個)instance 都結束了,但是還有 18 個的狀態是 Running,這些 instance 運行的慢,可能是因為處理的數據多,也可能是這些instance 處理特定數據慢。

解決方法:根據業務數據實際情況打散熱點key,具體參見 https://help.aliyun.com/document_detail/102614.html?spm=a2c4g.11186623.3.3.462c66604eqnSi
數據膨脹
【特徵】task 的輸出數據量比輸入數據量大很多。
比如 1G 的數據經過處理,變成了 1T,在一個 instance 下處理 1T 的數據,運行效率肯定會大大降低。輸入輸出數據量體現在 Task 的 I/O Record 和 I/O Bytes 這兩項:
解決思路:
(1) 檢查代碼是否有 bug:
JOIN 條件是不是寫錯了,變成笛卡爾積了;
UDTF 是不是有問題,輸出了太多數據。
(2) 避免join引起的數據膨脹。
比如:兩個表 join,左表是人口數據,數據量很大,但是由於並行度足夠,效率可觀。右表是個維表,記錄每種性別對應的一些信息(比如每種性別可能的壞毛病),雖然只有兩種性別,但是每種都包含數百行。那麼如果直接按照性別來 join,可能會讓左表膨脹數百倍。要解決這個問題,可以考慮先將右表的行做聚合,變成兩行數據,這樣 join 的結果就不會膨脹了
UDF執行效率低
【特徵】某個 task 執行效率低,且該 task 中有用戶自定義的擴展。甚至是 UDF 的執行超時報錯:“Fuxi job failed - WorkerRestart errCode:252,errMsg:kInstanceMonitorTimeout, usually caused by bad udf performance”。
首先確定udf位置,點看慢的fuxi task, 可以看到operator graph 中是否包含udf,例如下圖說明有java 的udf

通過查看logview 中fuxi instance 的stdout 可以查看該operator 運行速度,正常情況 Speed(records/s) 在百萬或者十萬級別。
解決方法:
(1) 檢查 UDF 是否有 bug。
(2) 使用內置函數替換自定義udf,內置函數一般效率更高。
(3) 將 UDF 函數進行功能拆分,部分用內置函數替換。函數無法實現的再用 UDF。
(4) 優化 UDF 的 evaluate 方法,將重複計算提取到初始化中。
作業重跑
有的MaxCompute 作業打開了service mode 功能,默認會優先使用service mode 模式,可以在project 級別設置
("odps.service.mode.enable.odps2": "true"),如果service mode 失敗,比如instance 個數超過1000,或者運行超過10分鐘,就會退回以Offline模式重跑。

5.2.3 結束階段
有時會發現fuxi task 都已經運行結束但是作業依然沒有結束情況,此時可能是合併小文件或動態分區元數據更新。
大小低於64MB的文件被認為是小文件,過多的小文件既會影響存儲效率,也會降低計算速度,為了避免系統產生過多小文件,SQL 作業在結束時會針對一定條件自動觸發合併小文件的操作,及Merge job。
解決方法:https://help.aliyun.com/document_detail/117430.html?spm=5176.11065259.1996646101.searchclickresult.67a35a8fsLWgmr
六、常見問題
1. 為什麼我的作業沒有顯示DAG圖?
a.例如grant,drop table 等語句不需要啟動fuxi job ,因此就沒有DAG圖。
b.algoTask 類型作業默認不展示DAG圖。
c.語法錯誤情況,由於尚未啟動fuxi job ,也沒有DAG圖。
2. 為什麼DAG 圖雙擊不能看operator 圖?
a.只有SQL,SQLRT 類型作業支持查看Operator 圖。
b.logview 依賴執行計劃畫圖,如果獲取執行計劃失敗,logview 依然可以用fuxi task 名字畫DAG圖,此時需要聯繫MaxCompute 值班同學調查。
3. DataWorks,MaxCompute 優先級問題?
MaxCompute 作業優先級與DataWorks 優先級相反, 9 - DataWorks = MaxCompute instance 優先級,logview 顯示的是MaxCompute 優先級(1~8), 數字越低優先級越高。
4. fuxi task instance 個數變來變去怎麼回事?
fuxi instance 個數默認不需要配置,可以通過輸入數據多少自動設置。HBO 可以動態修改instance個數,如果sql 有改動會導致hbo失效,此時instance個數就會發生變化,等運行一段時間hbo重新生效就會正常。
Map數根據splitsize 默認256M
Reduce 跟表的bucket ,上游的map數共同決定。
hbo 會動態調整worker 個數,可以運行中調整,比如發現多了,可以自動調小。
5.fuxi instance 的時間為啥不是fuxi task 的開始時間,主要是花費什麼時間?

如果計算資源不夠,fuxi instance 就會等待,此時就會發上fuxi instance 的開始時間晚於task 開始時間
6.查看stdout /stderror 報錯文件找不到,提示被回收
由於stdout /stderror 是保存在MaxCompute 運行作業的臨時目錄中,時間一長就會被回收,回收快慢取決於所在集群繁忙程度,一般一天內是能看到,如果回收過快可以找MaxCompute 值班同學協調排查。
7.Fuxi task 種類?
fuxi task 包括M,R, J, C,C是condition map join ,會在運行時動態決定使用哪種join算法。
七、參考文檔
1.SQL 調優 https://help.aliyun.com/document_detail/102614.html?spm=a2c4g.11186623.3.3.462c66604eqnSi
2.Join 長尾優化 https://help.aliyun.com/document_detail/143996.html?spm=a2c4g.11186623.6.1089.60f23de8zeVxHA
3.其他計算長尾優化 https://help.aliyun.com/document_detail/51020.html?spm=a2c4g.11186623.6.1090.48c61a61RDoLNZ
八、掃碼加入MaxCompute 開發者社區
