本文为您介绍外部表的常见问题。

自定义Extractor在读取非结构化数据时,如果数据字段存在DATETIME类型,则出现ODPS-0123131报错信息,如何处理?

  • 问题现象:自定义Extractor在读取非结构化数据时,如果数据字段存在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)       
  • 问题原因:查看指定位置的代码Date.valueOf(parts[i]),其中java.sql.Date.valueOf()函数只支持形如"yyyy-[m]m-[d]d"的STRING类型参数,不支持DATETIME时间类型参数。
  • 解决方法:
    1. 引入Joda-Time依赖。
      <dependency>
        <groupId>joda-time</groupId>
        <artifactId>joda-time</artifactId>
        <version>2.10</version>
      </dependency>
      import org.joda.time.DateTime;
      import org.joda.time.format.DateTimeFormat;                            
    2. 引入DateTimeFormat.forPattern()函数,将DATETIME类型的日期格式转化为STRING类型进行读取。
      record.setDate(index, new Date(DateTime.parse(parts[i], DateTimeFormat.forPattern("yyyy-MM-dd HH:mi:ss")).getMillis()));                           
  • 结果验证:
    1. 通过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包的本地保存路径。

    2. 通过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包本地存放路径。

    3. 上传测试数据至OSS指定的目录下。假设文件名为video_play_log.txt,示例数据如下。
      5c661071dba64d5080c91da085ff1073^音乐-点击-快进^26.12.04.68^2019-11-11 06:43:36                           
    4. 通过外部表读取数据。
      select * from <project_name>.video_play_log;
      读取结果如下。
      +------+-------+---+----------------+
      | uuid  | action  | ip  | time      |
      +------+-------+---+----------------+
      | 5c661071dba64d5080c91da085ff1073 | 音乐-点击-快进 | 26.12.04.68 | 2019-11-11 06:43:36 |
      +------+-------+---+----------------+     

在MaxCompute上访问OSS外部表,编写UDF本地测试通过,上传后报错内存溢出,如何处理?

  • 问题现象:在MaxCompute上访问OSS外部表,编写UDF本地测试通过,上传后报错内存溢出。
    FAILED: ODPS-0123131:User defined function exception - Traceback:
    java.lang.OutOfMemoryError: Java heap space        
    设置如下参数后运行时间增加但依然报错内存溢出。
    set odps.stage.mapper.mem = 2048 
    set odps.stage.mapper.jvm.mem = 4096       
  • 问题原因:外部表的对象文件太多,内存占用过大且未设置分区。
  • 解决方法:
    • 使用小数据量查询。
    • 将对象文件进行分区,以减少内存占用。

如何在MaxCompute中使用OSS外部表读取JSON数据?

在MaxCompute中使用OSS外部表读取JSON数据的操作详情请参见在MaxCompute中使用OSS外部表读取JSON数据

如何通过OSS外部表将多个小文件输出为一个文件?

通过Logview日志,查看SQL的执行计划中最后一个是Reducer还是Joiner。如果是Reducer,则执行语句set odps.stage.reducer.num=1,如果是Joiner,则执行语句set odps.stage.joiner.num=1