外部表常見問題
本文為您介紹外部表的常見問題。
問題類別 | 常見問題 |
OSS外部表 | |
性能問題 |
自定義Extractor在讀取非結(jié)構(gòu)化數(shù)據(jù)時,如果數(shù)據(jù)字段存在DATETIME類型,報錯ODPS-0123131,如何解決?
問題現(xiàn)象
自定義Extractor在讀取非結(jié)構(gòu)化數(shù)據(jù)時,如果數(shù)據(jù)字段存在DATETIME類型(例如2019-11-11 06:43:36),會返回如下報錯。
FAILED: ODPS-0123131:User defined function exception - Traceback: java.lang.IllegalArgumentException at java.sql.Date.valueOf(Date.java:143) at com.aliyun.odps.udf.example.text.TextExtractor.textLineToRecord(TextExtractor.java:194) at com.aliyun.odps.udf.example.text.TextExtractor.extract(TextExtractor.java:153) at com.aliyun.odps.udf.ExtractorHandler.extract(ExtractorHandler.java:120)
產(chǎn)生原因
查看指定位置的代碼
Date.valueOf(parts[i])
,其中java.sql.Date.valueOf()
函數(shù)只支持形如"yyyy-[m]m-[d]d"
的STRING類型參數(shù),不支持DATETIME時間類型參數(shù)。解決措施
引入Joda-Time依賴并在代碼中增加導(dǎo)入信息。
--依賴。 <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>2.10</version> </dependency> --導(dǎo)入信息。 import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat;
引入
DateTimeFormat.forPattern()
函數(shù),將DATETIME類型的日期格式轉(zhuǎn)化為STRING類型進行讀取。record.setDate(index, new Date(DateTime.parse(parts[i], DateTimeFormat.forPattern("yyyy-MM-dd HH:mi:ss")).getMillis()));
使用示例如下。
通過MaxCompute客戶端上傳Extractor項目打包生成的JAR包。
add jar /Users/gary/big_data/odps/text_extractor/target/text_extractor-1.0-SNAPSHOT.jar
/Users/gary/big_data/odps/text_extractor/target/text_extractor-1.0-SNAPSHOT.jar
為生成JAR包的本地保存路徑。通過MaxCompute客戶端上傳Joda-Time第三方JAR包。
add jar /Users/gary/.m2/repository/joda-time/joda-time/2.10/joda-time-2.10.jar
/Users/gary/.m2/repository/joda-time/joda-time/2.10/joda-time-2.10.jar
為Joda-Time第三方JAR包本地存放路徑。上傳測試數(shù)據(jù)至OSS指定的目錄下。假設(shè)文件名為
video_play_log.txt
,示例數(shù)據(jù)如下。5c661071dba64d5080c91da085ff1073^音樂-點擊-快進^26.12.04.68^2019-11-11 06:43:36
通過外部表讀取數(shù)據(jù)。
select * from <project_name>.video_play_log;
讀取結(jié)果如下。
+------+-------+---+----------------+ | uuid | action | ip | time | +------+-------+---+----------------+ | 5c661071dba64d5080c91da085ff1073 | 音樂-點擊-快進 | 26.12.04.68 | 2019-11-11 06:43:36 | +------+-------+---+----------------+
在MaxCompute上訪問OSS外部表,編寫UDF本地測試通過,上傳后報錯內(nèi)存溢出,如何解決?
問題現(xiàn)象
在MaxCompute上訪問OSS外部表,編寫UDF本地測試通過,上傳后返回如下報錯。
FAILED: ODPS-0123131:User defined function exception - Traceback: java.lang.OutOfMemoryError: Java heap space
設(shè)置如下參數(shù)后運行時間增加但依然報錯。
set odps.stage.mapper.mem = 2048; set odps.stage.mapper.jvm.mem = 4096;
產(chǎn)生原因
外部表的對象文件太多,內(nèi)存占用過大且未設(shè)置分區(qū)。
解決措施
使用小數(shù)據(jù)量查詢。
將對象文件進行分區(qū),以減少內(nèi)存占用。
通過外部表處理OSS數(shù)據(jù)時,報錯Inline data exceeds the maximun allowed size,如何解決?
問題現(xiàn)象
處理OSS數(shù)據(jù)時,報錯
Inline data exceeds the maximum allowed size
。產(chǎn)生原因
OSS Store對于每一個小文件有一個大小限制,如果超過3 GB則報錯。
解決措施
針對該問題,您可以通過調(diào)整以下兩個屬性進行處理。其原理是通過屬性值調(diào)整執(zhí)行計劃,控制每個Reducer寫入外部表OSS的數(shù)據(jù)大小,使得OSS Store文件不超過3 GB的限制。
set odps.sql.mapper.split.size=256; #調(diào)整每個Mapper讀取數(shù)據(jù)的大小,單位是MB。 set odps.stage.reducer.num=100; #調(diào)整Reduce階段的Worker數(shù)量。
如何在MaxCompute中使用OSS外部表讀取JSON數(shù)據(jù)?
在MaxCompute中使用OSS外部表讀取JSON數(shù)據(jù)的操作,請參見在MaxCompute中使用OSS外部表讀取JSON數(shù)據(jù)。
如何通過OSS外部表將多個小文件輸出為一個文件?
通過Logview日志,查看SQL的執(zhí)行計劃中最后一個是Reducer還是Joiner。如果是Reducer,則執(zhí)行語句set odps.stage.reducer.num=1;
,如果是Joiner,則執(zhí)行語句set odps.stage.joiner.num=1;
。
基于外部表執(zhí)行SQL作業(yè)時,運行慢,如何解決?
基于外部表執(zhí)行SQL作業(yè)時,運行慢的常見情況如下:
OSS外部表中的GZ壓縮文件讀取慢
問題現(xiàn)象
用戶創(chuàng)建了一個OSS外部表,數(shù)據(jù)源為OSS中的GZ壓縮文件,大小為200 GB。在讀取數(shù)據(jù)過程中執(zhí)行緩慢。
產(chǎn)生原因
由于Map端執(zhí)行計算的Mapper數(shù)量過少,所以SQL處理慢。
解決措施
對于結(jié)構(gòu)化數(shù)據(jù),您可以設(shè)置以下參數(shù)調(diào)整單個Mapper讀取數(shù)據(jù)量的大小,加速SQL執(zhí)行。
set odps.sql.mapper.split.size=256; #調(diào)整每個Mapper讀取Table數(shù)據(jù)的大小,單位是MB。
對于非結(jié)構(gòu)化數(shù)據(jù),您需要查看OSS外部表路徑下的OSS文件是否只有1個。如果只有1個,由于壓縮方式下的非結(jié)構(gòu)化數(shù)據(jù)不支持拆分,所以只能生產(chǎn)1個Mapper,導(dǎo)致處理速度較慢。建議您在OSS對應(yīng)的外部表路徑下,將OSS大文件拆分為小文件,從而增加讀取外部表生成的Mapper數(shù)量,提升讀取速度。
使用SDK搜索MaxCompute外部表數(shù)據(jù)速度慢
問題現(xiàn)象
使用SDK搜索MaxCompute外部表數(shù)據(jù)速度慢。
解決措施
外部表僅支持全量搜索,所以較慢,建議您改用MaxCompute內(nèi)部表。
查詢外部表Tablestore數(shù)據(jù)慢
問題現(xiàn)象
查詢外部表Tablestore的數(shù)據(jù)慢,同樣的業(yè)務(wù)數(shù)據(jù),1個實時寫入Tablestore,1個定時寫入MaxCompute,兩個表結(jié)構(gòu)和數(shù)據(jù)量一樣。查詢MaxCompute內(nèi)部表耗時遠小于查詢Tablestore外部表。
解決措施
這種情況可能是對1份數(shù)據(jù)進行了多次計算,導(dǎo)致速度慢。相比每次從Tablestore遠程讀取數(shù)據(jù),更高效快速的方法是先一次性把需要的數(shù)據(jù)導(dǎo)入到MaxCompute內(nèi)部,轉(zhuǎn)為MaxCompute內(nèi)部表,再進行查詢。