1. 程式人生 > >使用MaxCompute Java SDK 執行任務卡住了,怎麽辦?

使用MaxCompute Java SDK 執行任務卡住了,怎麽辦?

ons 執行 原因 sys trac ram 程序 client 什麽

場景一
用戶A
A: “親,用 MaxCompute Java SDK 跑作業,為什麽卡住不動了?”
me: “有 Logview 嗎?發來看下”
A: “沒有,我用的是SDK,沒Logview”

場景二
用戶B
B :“親,用 MaxCompute Java SDK 訪問 Table,為什麽卡住半天沒反應?”
me:“卡在哪一行了?”
B:"就 RestClient retry 然後卡住了"

去繁就簡
用戶 A 的問題在於沒有 instance 的 logview,導致無法追蹤 instance 的運行過程。
通常用戶在創建 instance 後會調用 instance.waitForSuccess() 來等待作業運行完成,一旦作業耗時巨大,程序就卡在這一步了,此時如果有 logview ,就能查看追蹤查看作業等待的具體原因了。

用戶 B 的問題在於 sdk 的 Restclient 本身有重試機制,從表面來看就是卡住了,沒有任何輸出。
如果在每次重試的時候都輸出錯誤,就可以快速定位問題節約時間了。我已經遇到好幾個公共雲用戶因為缺包導致一直卡住幾分鐘才丟出異常,嚴重影響了工作效率。

那麽問題可以歸結為下面兩點:

1【 怎麽使用 MaxCompute Java SDK 生成 instance Logview 】
答案很簡單, MaxCompute Java SDK 提供了 logview 接口,詳情可查看 SDK Java Doc

String logview = odps.logview().generateLogView(instance, 7 * 24);

兩個參數: instance 對象,logview token 超時時間 (單位:小時)

再次提醒用戶,在使用 SDK 的時候,請為每個 instance 記錄 Logview,一旦遇到問題可快速追蹤。

當然如果改代碼很麻煩,那還有一個絕招。在 MaxCompute Console 中使用 wait <instance_id> 命令也可以得到Logview。

2【 能不能在每次重試的時候,都把錯誤輸出呢?】
當然可以。MaxCompute Java SDK 提供了抽象類 RetryLogger 詳情可查看 SDK Java Doc

public static abstract class RetryLogger {

/**
 * 當 RestClent 發生重試前的回調函數
 *
 * @param e
 *     錯誤異常
 * @param retryCount
 *     重試計數
 * @param retrySleepTime
 *     下次需要的重試時間
 */
public abstract void onRetryLog(Throwable e, long retryCount, long retrySleepTime);

}

用戶只需實現一個自己的 RetryLogger 子類,然後在初始化 odps 對象的時候使用 odps.getRestClient().setRetryLogger(new UserRetryLogger()); 就可以將日誌輸出。

一個典型的實現如下:

// init odps
odps.getRestClient().setRetryLogger(new UserRetryLogger());

// your retry logger
public class UserRetryLogger extends RetryLogger {

@Override
public void onRetryLog(Throwable e, long retryCount, long sleepTime) {
  if (e != null && e instanceof OdpsException) {
    String requestId = ((OdpsException) e).getRequestId();
    if (requestId != null) {
      System.err.println(String.format(
          "Warning: ODPS request failed, requestID:%s, retryCount:%d, will retry in %d seconds.",
          requestId, retryCount, sleepTime));
      return;
    }
  }
  System.err.println(String.format(
      "Warning: ODPS request failed:%s, retryCount:%d, will retry in %d seconds.", e.getMessage(),retryCount,
      sleepTime));
}

}

掌握上面兩種技巧,就可以快速定位問題。

使用MaxCompute Java SDK 執行任務卡住了,怎麽辦?