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

问题类别 常见问题
OSS外部表
性能问题 基于外部表执行SQL作业时,运行慢,如何解决?

自定义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;       
  • 产生原因

    外部表的对象文件太多,内存占用过大且未设置分区。

  • 解决措施
    • 使用小数据量查询。
    • 将对象文件进行分区,以减少内存占用。

通过外部表处理OSS数据时,报错Inline data exceeds the maximun allowed size,如何解决?

  • 问题现象

    处理OSS数据时,报错Inline data exceeds the maximun allowed size

  • 产生原因

    OSS Store对于每一个小文件有一个大小限制,如果超过3 GB则报错。

  • 解决措施

    针对该问题,您可以通过调整以下两个属性进行处理。其原理是通过属性值调整执行计划,控制每个Reducer写入外部表OSS的数据大小,使得OSS Store文件不超过3 GB的限制。

    set odps.sql.mapper.split.size=256; #调整每个Mapper读取数据的大小,单位是MB。
    set odps.sql.reducer.instances=100; #调整执行计划的Reducer数量。

如何在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;

基于外部表执行SQL作业时,运行慢,如何解决?

基于外部表执行SQL作业时,运行慢的常见情况如下:

  • OSS外部表中的GZ压缩文件读取慢
    • 问题现象

      用户创建了一个OSS外部表,数据源为OSS中的GZ压缩文件,大小为200 GB。在读取数据过程中执行缓慢。

    • 产生原因

      由于Map端执行计算的Mapper数量过少,所以SQL处理慢。

    • 解决措施
      • 对于结构化数据,您可以设置以下参数调整单个Mapper读取数据量的大小,加速SQL执行。
        set odps.sql.mapper.split.size=256; #调整每个Mapper读取Table数据的大小,单位是MB。       
      • 对于非结构化数据,您需要查看OSS外部表路径下的OSS文件是否只有1个。如果只有1个,由于压缩方式下的非结构化数据不支持拆分,所以只能生产1个Mapper,导致处理速度较慢。建议您在OSS对应的外部表路径下,将OSS大文件拆分为小文件,从而增加读取外部表生成的Mapper数量,提升读取速度。
  • 使用SDK搜索MaxCompute外部表数据速度慢
    • 问题现象

      使用SDK搜索MaxCompute外部表数据速度慢。

    • 解决措施

      外部表仅支持全量搜索,所以较慢,建议您改用MaxCompute内部表。

  • 查询外部表Tablestore数据慢
    • 问题现象

      查询外部表Tablestore的数据慢,同样的业务数据,1个实时写入Tablestore,1个定时写入MaxCompute,两个表结构和数据量一样。查询MaxCompute内部表耗时远小于查询Tablestore外部表。

    • 解决措施

      这种情况可能是对1份数据进行了多次计算,导致速度慢。相比每次从Tablestore远程读取数据,更高效快速的方法是先一次性把需要的数据导入到MaxCompute内部,转为MaxCompute内部表,再进行查询。