MaxCompute UDF(Java)常見問題
本文為您介紹使用Java語言編寫的MaxCompute UDF的常見問題。
類或依賴問題
調(diào)用MaxCompute UDF運(yùn)行代碼時(shí)的常見類或依賴問題如下:
問題現(xiàn)象一:運(yùn)行報(bào)錯(cuò)描述為
ClassNotFoundException
或Some dependencies are missing
。產(chǎn)生原因:
原因一:創(chuàng)建MaxCompute UDF時(shí)指定的資源JAR包不正確。
原因二:MaxCompute UDF依賴的資源JAR包未上傳至MaxCompute,例如依賴的第三方包沒有上傳。
原因三:調(diào)用MaxCompute UDF運(yùn)行代碼時(shí),所處的項(xiàng)目不正確。即MaxCompute UDF不在MaxCompute項(xiàng)目中。例如MaxCompute UDF注冊(cè)到了開發(fā)項(xiàng)目,但卻在生產(chǎn)項(xiàng)目執(zhí)行調(diào)用操作。
原因四:文件資源不存在或資源類型不正確。例如PY文件,資源類型是PY,但MaxCompute UDF代碼中
get_cache_file
需要的類型是FILE。
解決措施:
原因一的解決措施:檢查JAR包的正確性,并確認(rèn)JAR包中已經(jīng)包含需要的類,重新打包并上傳至MaxCompute項(xiàng)目。更多打包上傳操作,請(qǐng)參見打包、上傳及注冊(cè)。
原因二的解決措施:將MaxCompute UDF依賴的第三方包作為資源上傳至MaxCompute項(xiàng)目,然后在注冊(cè)函數(shù)時(shí),依賴資源列表中添加此包。更多上傳資源及注冊(cè)函數(shù)操作,請(qǐng)參見添加資源和注冊(cè)函數(shù)。
原因三的解決措施:在報(bào)錯(cuò)的項(xiàng)目下通過MaxCompute客戶端執(zhí)行
list functions;
命令,確保MaxCompute UDF是真實(shí)存在的,且MaxCompute UDF的類和依賴的資源正確。原因四的解決措施:通過MaxCompute客戶端執(zhí)行
desc function <function_name>;
命令,確保Resources列表已覆蓋所有需要的文件資源。如果資源類型不匹配,可執(zhí)行add <file_type> <file_name>;
重新添加資源。
問題現(xiàn)象二:運(yùn)行報(bào)錯(cuò)描述為
NoClassDefFoundError
、NoSuchMethodError
或錯(cuò)誤碼為ODPS-0123055
。產(chǎn)生原因:
原因一:用戶上傳的JAR包中包含的第三方庫的版本與MaxCompute內(nèi)置的第三方庫的版本不一致。
原因二:Java沙箱限制。作業(yè)Instance的Stderr中出現(xiàn)
java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "createClassLoader")
詳細(xì)信息,表示是沙箱限制。MaxCompute UDF在分布式環(huán)境中運(yùn)行時(shí)收到Java沙箱的限制。更多Java沙箱限制信息,請(qǐng)參見Java沙箱。
解決措施:
原因一的解決措施:使用
maven-shade-plugin
解決版本不一致問題并修改Import路徑,重新打包為JAR包并上傳至MaxCompute項(xiàng)目。更多打包上傳操作,請(qǐng)參見打包、上傳及注冊(cè)。原因二的解決措施:請(qǐng)參見Java沙箱限制問題。
Java沙箱限制問題
問題現(xiàn)象:調(diào)用MaxCompute UDF訪問本地文件、外網(wǎng)或分布式文件系統(tǒng),創(chuàng)建Java線程等時(shí),代碼運(yùn)行會(huì)報(bào)錯(cuò)。
產(chǎn)生原因:網(wǎng)絡(luò)限制問題 ,MaxCompute UDF默認(rèn)不支持訪問網(wǎng)絡(luò)。
解決措施:請(qǐng)根據(jù)業(yè)務(wù)情況填寫并提交網(wǎng)絡(luò)連接申請(qǐng)表單,MaxCompute技術(shù)支持團(tuán)隊(duì)會(huì)及時(shí)聯(lián)系您完成網(wǎng)絡(luò)開通操作。表單填寫指導(dǎo),請(qǐng)參見網(wǎng)絡(luò)開通流程。
性能問題
調(diào)用MaxCompute UDF運(yùn)行代碼時(shí)的常見性能問題如下:
問題現(xiàn)象一:運(yùn)行報(bào)錯(cuò)描述為
kInstanceMonitorTimeout
。產(chǎn)生原因:MaxCompute UDF處理時(shí)間過長(zhǎng)導(dǎo)致超時(shí)。默認(rèn)情況下UDF處理數(shù)據(jù)的時(shí)間有限制,在處理一批(通常情況下為1024條)記錄時(shí),必須在1800秒內(nèi)處理完。這個(gè)時(shí)間限制并不是針對(duì)Worker的總運(yùn)行時(shí)間,而是處理一小批記錄的時(shí)間。通常情況下SQL處理數(shù)據(jù)的速率超過了萬條/秒,該限制只是為了防止MaxCompute UDF中出現(xiàn)死循環(huán),導(dǎo)致長(zhǎng)時(shí)間占用CPU資源的情況。
解決措施:
如果實(shí)際計(jì)算量很大,可以在MaxCompute UDF的實(shí)現(xiàn)Java類的方法中調(diào)用
ExecutionContext.claimAlive
來重置計(jì)時(shí)器。重點(diǎn)優(yōu)化MaxCompute UDF代碼邏輯。后續(xù)調(diào)用MaxCompute UDF時(shí),可同時(shí)在Session級(jí)別配置如下參數(shù)輔助調(diào)節(jié)MaxCompute UDF運(yùn)行過程,提升處理速度。
參數(shù)
說明
set odps.function.timeout=xxx;
調(diào)整UDF運(yùn)行超時(shí)時(shí)長(zhǎng)。默認(rèn)值為1800s。可根據(jù)實(shí)際情況酌情調(diào)大。取值范圍為1s~3600s。
set odps.stage.mapper.split.size=xxx;
調(diào)整Map Worker的輸入數(shù)據(jù)量。默認(rèn)值為256 MB。可根據(jù)實(shí)際情況酌情調(diào)小。
set odps.sql.executionengine.batch.rowcount=xxx;
調(diào)整MaxCompute一次處理的數(shù)據(jù)行數(shù)。默認(rèn)值為1024行。可根據(jù)實(shí)際情況酌情調(diào)小。
問題現(xiàn)象二:運(yùn)行報(bào)錯(cuò)描述為
errMsg:SigKill(OOM)
或OutOfMemoryError
。產(chǎn)生原因:MaxCompute運(yùn)行作業(yè)主要分為三個(gè)階段:Map、Reduce和Join。如果處理的數(shù)據(jù)量比較大,會(huì)導(dǎo)致各個(gè)階段的每個(gè)Instance處理的時(shí)間比較長(zhǎng)。
解決措施:
如果是
fuxi
或runtime
相關(guān)代碼報(bào)錯(cuò),您可以通過設(shè)置如下資源參數(shù)提升處理速度。參數(shù)
說明
set odps.stage.mapper.mem=xxx;
調(diào)整Map Worker的內(nèi)存大小。默認(rèn)值為1024 MB。可根據(jù)實(shí)際情況酌情調(diào)大。
set odps.stage.reducer.mem=xxx;
調(diào)整Reduce Worker的內(nèi)存大小。默認(rèn)值為1024 MB。可根據(jù)實(shí)際情況酌情調(diào)大。
set odps.stage.joiner.mem=xxx;
調(diào)整Join Worker的內(nèi)存大小。默認(rèn)值為1024 MB。可根據(jù)實(shí)際情況酌情調(diào)大。
set odps.stage.mapper.split.size=xxx;
調(diào)整Map Worker的輸入數(shù)據(jù)量。默認(rèn)值為256 MB。可根據(jù)實(shí)際情況酌情調(diào)大。
set odps.stage.reducer.num=xxx;
調(diào)整Reduce階段的Worker數(shù)量。可根據(jù)實(shí)際情況酌情調(diào)大。
set odps.stage.joiner.num=xxx;
調(diào)整Join階段的Worker數(shù)量。可根據(jù)實(shí)際情況酌情調(diào)大。
如果是Java代碼本身報(bào)錯(cuò),可以在調(diào)整上述參數(shù)的同時(shí),通過
set odps.sql.udf.jvm.memory=xxx;
參數(shù)調(diào)大Jvm內(nèi)存。
更多參數(shù)詳細(xì)信息,請(qǐng)參見SET操作。
UDTF相關(guān)問題
調(diào)用Java UDTF運(yùn)行代碼時(shí)的常見問題如下:
問題現(xiàn)象一:運(yùn)行報(bào)錯(cuò)描述為
Semantic analysis exception - only a single expression in the SELECT clause is supported with UDTF's
。產(chǎn)生原因:在SELECT語句中調(diào)用Java UDTF時(shí),存在Java UDTF與其他列或表達(dá)式混用的問題,Java UDTF暫不支持該用法。錯(cuò)誤示例如下。
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;
問題現(xiàn)象二:運(yùn)行報(bào)錯(cuò)描述為
Semantic analysis exception - expect 2 aliases but have 0
。產(chǎn)生原因:Java UDTF代碼中沒有指定輸出列名。
解決措施:您可以在調(diào)用Java UDTF的SELECT語句中通過
as
子句給出列名。命令示例如下。select udtffunction_name(paramname) as (col1, col2);