全部產品
Search
文件中心

MaxCompute:MaxCompute UDF(Java)常見問題

更新時間:Jun 19, 2024

本文為您介紹使用Java語言編寫的MaxCompute UDF的常見問題。

類或依賴問題

調用MaxCompute UDF運行代碼時的常見類或依賴問題如下:

  • 問題現象一:運行報錯描述為ClassNotFoundExceptionSome dependencies are missing

    • 產生原因:

      • 原因一:建立MaxCompute UDF時指定的資源JAR包不正確。

      • 原因二:MaxCompute UDF依賴的資源JAR包未上傳至MaxCompute,例如依賴的第三方包沒有上傳。

      • 原因三:調用MaxCompute UDF運行代碼時,所處的專案不正確。即MaxCompute UDF不在MaxCompute專案中。例如MaxCompute UDF註冊到了開發專案,但卻在生產專案執行叫用作業。

      • 原因四:檔案資源不存在或資源類型不正確。例如PY檔案,資源類型是PY,但MaxCompute UDF代碼中get_cache_file需要的類型是FILE。

    • 解決措施:

      • 原因一的解決措施:檢查JAR包的正確性,並確認JAR包中已經包含需要的類,重新打包並上傳至MaxCompute專案。更多打包上傳操作,請參見打包、上傳及註冊

      • 原因二的解決措施:將MaxCompute UDF依賴的第三方包作為資源上傳至MaxCompute專案,然後在註冊函數時,依賴資源清單中添加此包。更多上傳資源及註冊函數操作,請參見添加資源註冊函數

      • 原因三的解決措施:在報錯的專案下通過MaxCompute用戶端執行list functions;命令,確保MaxCompute UDF是真實存在的,且MaxCompute UDF的類和依賴的資源正確。

      • 原因四的解決措施:通過MaxCompute用戶端執行desc function <function_name>;命令,確保Resources列表已覆蓋所有需要的檔案資源。如果資源類型不符,可執行add <file_type> <file_name>;重新添加資源。

  • 問題現象二:運行報錯描述為NoClassDefFoundErrorNoSuchMethodError或錯誤碼為ODPS-0123055

    • 產生原因:

      • 原因一:使用者上傳的JAR包中包含的第三方庫的版本與MaxCompute內建的第三方庫的版本不一致。

      • 原因二:Java沙箱限制。作業Instance的Stderr中出現java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "createClassLoader")詳細資料,表示是沙箱限制。MaxCompute UDF在分布式環境中運行時收到Java沙箱的限制。更多Java沙箱限制資訊,請參見Java沙箱

    • 解決措施:

      • 原因一的解決措施:使用maven-shade-plugin解決版本不一致問題並修改Import路徑,重新打包為JAR包並上傳至MaxCompute專案。更多打包上傳操作,請參見打包、上傳及註冊

      • 原因二的解決措施:請參見Java沙箱限制問題

Java沙箱限制問題

  • 問題現象:調用MaxCompute UDF訪問本地檔案、外網或Distributed File System,建立Java線程等時,代碼運行會報錯

  • 產生原因:網路限制問題 ,MaxCompute UDF預設不支援訪問網路。

  • 解決措施:請根據業務情況填寫並提交網路連接申請表單,MaxCompute支援人員團隊會及時聯絡您完成網路開通操作。表單填寫指導,請參見網路開通流程

效能問題

調用MaxCompute UDF運行代碼時的常見效能問題如下:

  • 問題現象一:運行報錯描述為 kInstanceMonitorTimeout

    • 產生原因:MaxCompute UDF處理時間過長導致逾時。預設情況下UDF處理資料的時間有限制,在處理一批(通常情況下為1024條)記錄時,必須在1800秒內處理完。這個時間限制並不是針對Worker的總已耗用時間,而是處理一小批記錄的時間。通常情況下SQL處理資料的速率超過了萬條/秒,該限制只是為了防止MaxCompute UDF中出現死迴圈,導致長時間佔用CPU資源的情況。

    • 解決措施:

      • 如果實際計算量很大,可以在MaxCompute UDF的實現Java類的方法中調用ExecutionContext.claimAlive來重設計時器。

      • 重點最佳化MaxCompute UDF代碼邏輯。後續調用MaxCompute UDF時,可同時在Session層級配置如下參數輔助調節MaxCompute UDF運行過程,提升處理速度。

        參數

        說明

        set odps.function.timeout=xxx;

        調整UDF運行逾時時間長度。預設值為1800s。可根據實際情況酌情調大。取值範圍為1s~3600s。

        set odps.stage.mapper.split.size=xxx;

        調整Map Worker的輸入資料量。預設值為256 MB。可根據實際情況酌情調小。

        set odps.sql.executionengine.batch.rowcount=xxx;

        調整MaxCompute一次處理的資料行數。預設值為1024行。可根據實際情況酌情調小。

  • 問題現象二:運行報錯描述為errMsg:SigKill(OOM)OutOfMemoryError

    • 產生原因:MaxCompute運行作業主要分為三個階段:Map、Reduce和Join。如果處理的資料量比較大,會導致各個階段的每個Instance處理的時間比較長。

    • 解決措施:

      • 如果是fuxiruntime相關代碼報錯,您可以通過設定如下資源參數提升處理速度。

        參數

        說明

        set odps.stage.mapper.mem=xxx;

        調整Map Worker的記憶體大小。預設值為1024 MB。可根據實際情況酌情調大。

        set odps.stage.reducer.mem=xxx;

        調整Reduce Worker的記憶體大小。預設值為1024 MB。可根據實際情況酌情調大。

        set odps.stage.joiner.mem=xxx;

        調整Join Worker的記憶體大小。預設值為1024 MB。可根據實際情況酌情調大。

        set odps.stage.mapper.split.size=xxx;

        調整Map Worker的輸入資料量。預設值為256 MB。可根據實際情況酌情調大。

        set odps.stage.reducer.num=xxx;

        調整Reduce階段的Worker數量。可根據實際情況酌情調大。

        set odps.stage.joiner.num=xxx;

        調整Join階段的Worker數量。可根據實際情況酌情調大。

      • 如果是Java代碼本身報錯,可以在調整上述參數的同時,通過set odps.sql.udf.jvm.memory=xxx;參數調大Jvm記憶體。

更多參數詳細資料,請參見SET操作

UDTF相關問題

調用Java UDTF運行代碼時的常見問題如下:

  • 問題現象一:運行報錯描述為Semantic analysis exception - only a single expression in the SELECT clause is supported with UDTF's

    • 產生原因:在SELECT語句中調用Java UDTF時,存在Java UDTF與其他列或運算式混用的問題,Java UDTF暫不支援該用法。錯誤樣本如下。

      select b.*, 'x', udtffunction_name(v) from table lateral view udtffunction_name(v) b as f1, f2;
    • 解決措施:您可以將Java UDTF與Lateral View配合使用。命令樣本如下。

      select b.*, 'x' from table lateral view udtffunction_name(v) b as f1, f2;
  • 問題現象二:運行報錯描述為Semantic analysis exception - expect 2 aliases but have 0

    • 產生原因:Java UDTF代碼中沒有指定輸出資料行名。

    • 解決措施:您可以在調用Java UDTF的SELECT語句中通過as子句給出列名。命令樣本如下。

      select udtffunction_name(paramname) as (col1, col2);