基本概念

  • Hologres与MaxCompute的对比。
    对比项MaxComputeHologres
    使用场景ETL(Extract-Transform-Load)加工,面向数据明细层(DWD,Data Warehouse Detail)和数据服务层(DWS,Data WareHouse Service)。交互式查询、在线数据服务,面向应用的数据服务(ADS)。
    用户使用异步的执行作业。同步的Query。
    集群资源共享大集群,SaaS模式。独享集群,PaaS模式。
    计算引擎基于Job Execution模型,将作业转化为Stage,每个Stage按需申请计算资源,执行过程中通过File持久化。基于MPP模型,精细化内存资源管理,执行引擎常驻内存,用户态细粒度SQL算子调度,计算不落盘。
    调度方式进程级别,运行时按需申请、分配。轻量级线程,资源启动时预留。
    扩展性几乎不受限制。复杂查询尽量避免跨多节点数据Shuffle。
    存储格式列式。行式、列式、行列共存。
    存储成本基于Pangu,成本低。基于Pangu,利用SSD做缓存加速,成本相对高。
    接口标准MaxCompute SQL,类Hive。PostgreSQL。
  • Hologres外部表和内部表的适用场景
    • 新建外部表直接加速查询

      外部表不存储数据,数据存储在MaxCompute中,且外部表没有索引,全靠CPU资源进行计算,因此外部表比较适用于小数据量,低QPS(Queries-per-second)的查询。

    • 导入数据至Hologres内部表进行加速查询

      内部表的数据存储在Hologres中,当有数据更新、复杂查询、高QPS的查询时,建议导入内部表,能充分发挥Hologres底层的性能优势。

常见报错

  • 报错:报错ERROR: not an ORC file
    查询外部表时报错:ERROR: status { code: SERVER_INTERNAL_ERROR message: "hos_exception: Invalid argument: ../../../src/OrcFileMetaHelper.cc(234)-<operator()>: not an ORC file
    • 报错原因:MaxCompute的表是Stream表,数据是通过Tunnel等流式写入,当前Hologres直读MaxCompute外部表时暂不支持查询该状态的表。
    • 解决方法:在查询数据SQL前添加如下GUC。
      set hg_experimental_enable_access_odps_with_table_api=on;
      set hg_experimental_enable_access_odps_orc_via_holo =off;
  • 报错: specified partitions count in MaxCompute table: exceeds the limitation of 512, please add stricter partition filter or set axf_MaxCompute_partition_limit. 或者Build desc failed: Exceeds the partition limitation of 512, current match xxx partitions.
    • 报错原因:

      当前Hologres支持查询最多分区数为512个,查询超过此限制。

    • 解决方法:
      • 请添加分区过滤条件,使一次查询不超过512个分区。
      • 请将数据导入Hologres内部表,则没有分区限制,详情请参见使用SQL导入MaxCompute的数据至Hologres
      • 使用如下命令调整每次Query命中的分区数,默认为512,最大为1024,不建议调整太大,否则会影响查询性能。
        -- V1.1及以上版本
        set hg_foreign_table_max_partition_limit = 128;
        -- V0.10版本
        set hg_experimental_foreign_table_max_partition_limit = xxx ;
        说明 如果MaxCompute配置了多级分区,会按照最细粒度分区单位进行分区命中计数。
  • 报错:Build desc failed: Exceeds the scan limitation of 200 GB, current scan xxx GB.
    • 报错原因:

      Hologres中默认最大的底层数据扫描量为200GB,此数据量是命中MaxCompute分区之后的扫描数据量,和MaxCompute自身存储数据量无关,查询超出此限制导致报错。

    • 解决方法:
      • 增加过滤条件,命中更少的分区,使一次Query的扫描数据量在200GB以内。
      • 请将MaxCompute表数据导入至Hologres中,再进行查询,详情请参见使用SQL导入MaxCompute的数据至Hologres
      • (不推荐)使用set hg_experimental_foreign_table_max_scan_size = xxx;命令设置参数调大数据量限制(其中xxx可以替换为业务的数据量,如400,单位为GB)。但是过分调大外部表数据量限制,可能无法得到预期的性能,也可能造成实例OOM(Out Of Memory),影响正常使用。
  • 报错:query next from foreign table executor failed, Not implemented
    • 报错原因:MaxCompute表数据写入时使用Streaming Tunnel的方式写入,写入命令为tunnel.createStreamUploadSession。Hologres读取数据时需要开启两个GUC。
    • 解决方法:添加如下两个配置项。
      set hg_experimental_enable_access_odps_with_table_api=on;
      set hg_experimental_enable_access_odps_orc_via_holo =off;
  • 报错:Build desc failed: failed to check permission: Currently not supported table type "view"

    报错原因:目前暂时不支持MaxCompute的View。

  • 报错:Build desc failed: failed to get foregin table split:MaxCompute-0010000: System internal error - get input pangu dir meta fai
    • 报错原因:

      Hologres读取MaxCompute的配置未及时更新。

    • 解决方法:

      请过几分钟重试,若是重试好几次都未成功,请联系技术支持处理。

  • 报错:ERROR: Query:[xxx] Build desc failed: failed to get foregin table split:ERPC_ERROR_CONNECTION_CLOSED
    • 报错原因:

      MaxCompute小文件过多,导致请求的META超过远程过程调用协议(RPC,Remote Procedure Call Protocol)1GB的最大限制。

    • 解决方法:
      • 请执行以下命令进行小文件合并。
        set MaxCompute.merge.task.mode=sql;
        set MaxCompute.merge.lock.expire.time=0;
        ALTER TABLE <tablename> [PARTITION] MERGE SMALLFILES;
      • HologresV0.10.21及以上版本已优化,请升级Hologres实例,详情请参见实例升级
      • 请联系MaxCompute技术支持从源头解决,如果数据量不大可直接将数据写入Hologres。
  • 报错:ERROR: status { code: SERVER_INTERNAL_ERROR message: "hos_exception: IO error: Failed to execute pangu open normal file ,err: PanguParameterInvalidException" }
    • 报错原因:

      Hologres V1.1版本外部表的执行引擎直读MaxCompute Pangu加密数据存在问题。

    • 解决方法:

      请执行set hg_experimental_enable_access_odps_orc_via_holo = off;命令或者升级Hologres实例至最新版本。

  • 报错:failed to import foreign schema:Failed to get MaxCompute table:Not enable schema evolution
    • 报错原因:

      对MaxCompute表的元数据做了修改。

    • 解决方法:
      • 请升级Hologres实例版本至V1.3及以上版本,通过加入实时数仓Hologres交流群(钉钉群号:32314975)申请升级实例或自助升级(Beta)
      • 更新了MaxCompute外部表Schema之后(例如增加列、删除列操作),请执行IMPORT FOREIGN SCHEMA来做刷新。
      • 如果执行了IMPORT FOREIGN SCHEMA还报错的话,请重新建一次MaxCompute的表,再建外部表,因为MaxCompute修改Schema之后进入到schema evolution状态,Hologres无法读取这种状态的表。
  • 报错:Open ORC file failed for schema mismatch. Reader schema:
    • 报错原因:

      MaxCompute的表为ORC格式,表的DECIMAL类型存储方式改变(一般是MaxCompute新加了DECIMAL字段或者MaxCompute做了灰度配置变更),导致Hologres读MaxCompute的DECIMAL类型出错。

    • 解决方法:
      • 请执行set MaxCompute.storage.orc.enable.binary.decimal=false命令,重新导下MaxCompute数据。
      • 请将MaxCompute的表的DECIMAL类型改为DOUBLE类型,再重新刷新一遍数据。
  • 报错:failed to import foreign schema:Failed to get MaxCompute table:Not enable acid table
    • 报错原因:

      MaxCompute表是事务(Transactional)表。

    • 解决方法:

      当前不支持MaxCompute的Transactional表,建议改为普通表。

  • 报错:Request denied, may caused by server busy.
    • 报错原因:

      外部表资源占满,CPU用量严重超出。

    • 解决方法:
      • 请优化SQL,使SQL更加充分合理的使用资源,详情请参见优化MaxCompute外部表的查询性能
      • 降低并发度。
        1. 使用show hg_foreign_table_executor_max_dop;命令查看当前配置。
        2. 使用如下命令降低并发度,推荐调整为当前配置的一半。
          -- 语法示例
          set hg_foreign_table_executor_max_dop = <并发数>; 
          -- 使用示例 
          set hg_foreign_table_executor_max_dop = 18;
          并发数:外部表单个执行节点读取外部表数据的并发度,默认值为256,取值范围为0-1024。修改后的风险: 并发度太大可能造成实例OOM,导致导入、查询失败,甚至实例重启,以至于服务不可用。并发度太小会导致外表查询、外表导入内表性能较差。
      • 请导入数据至Hologres内部表,内部表可以设置索引,使查询性能更好,详情请参见使用SQL导入MaxCompute的数据至Hologres
  • 导入数据报错:Query executor exceeded total memory limitation xxxxx: yyyy bytes used
    • 报错原因:

      数据量太大或者导入逻辑太复杂,导致超出了内存限制。(实例由多个节点组成,一个节点标准的内存上限是64GB,节点内存会分为三部分,三分之一用于计算,三分之一用于缓存,三分之一用于元数据。这里的报错是计算内存超出了限制。)

    • 解决方法:
      1. 查看执行计划

        可以执行explain analyze sql;命令查看执行计划中具体的数据行数。当导入Query包含查询,但部分表没有analyze,或者analyze过,但数据又有更新导致不准确,导致查询优化器决策连接顺序有误,会引起内存开销过高。

        对所有参与的内表、外表执行analyze tablename;命令,更新表的统计元信息,可以帮助查询优化器生成更优的执行计划。

      2. 设置单行导入条数
        当表的列数较多,单行数据量较大时,单次读取的数据量会更大,通过在SQL前加以下参数来控制单次读取数据的行数,可以有效减少OOM情况。
        set hg_experimental_query_batch_size = 1024;  -- 默认值为8192
        insert into holo_table select * from mc_table;
      3. 降低导入的并发度。
        降低导入并发度,也会有效减少导入过程中的内存开销,并发度通过参数hg_foreign_table_executor_max_dop控制,默认为实例的Core数,可以在导入时设置更小的参数,降低导入的内存使用。
        set hg_foreign_table_executor_max_dop = 8;
        insert into holo_table select * from mc_table;
      4. 排查外表重复数据是否过多。

        如果以上操作都做完了,还是导入不了,如果使用的是insert on conflict命令,请排查是否外表重复数据太多,重复数据太多也会导致导入性能不好,可以在MaxCompute做重复数据去重,再进行导入,详情请参见多行数据合并为一行数据

      5. 升级新版本动态调整内存。

        Hologres从V1.1.24版本开始,会对内存进行动态调整,后台会实时刷新当前内存水位,若是有空闲,则会分配更多内存给计算使用,请升级Hologres至最新版本,具体操作请参见实例升级

      6. 扩容。

        如果以上操作都做完了,导入数据还是不成功,请对Hologres扩容,详情请参见升配

  • 报错:Timestamp overflow detected while converting timestampfrom orc VectorBatch to arrow
    • 报错原因:

      在MaxCompute表中有TIMESTAMP类型,使用Tunnel写入后TIMESTAMP精度会变成纳秒,目前Hologres暂不支持精度为纳秒的TIMESTAMP。

    • 解决方法:
      • 在MaxCompute中将TIMESTAMP类型转换为DateTime类型。
      • Hologres实例升级版本到 V1.1.70及以上版本。
  • 报错:query next from foreign table executor failed,userinfao fail
    • 报错原因:

      当前MaxCompute表是存储加密的表,在HologresV1.1以下版本还不支持读取。

    • 解决方法:

      请将Hologres实例升级至V1.1以上版本,详情请参见实例升级

  • 报错:You have NO privilege 'MaxCompute:Select' on xxx
    • 报错原因:

      当前账号不具备MaxCompute表的查询(Select)权限。

    • 解决方法:

      请联系MaxCompute管理员在MaxCompute中授予当前账号查询表(Select)的权限,具体操作请参见MaxCompute权限

  • 报错:The sensitive label of column 'xxx' is 2, but your effective label is 0
    • 报错原因:

      当前账号只有MaxCompute表的部分字段权限。

    • 解决方法:
      • 核对有权限的账号和报错的账号是否为同一个账号,若是真的没有权限,可以去申请MaxCompute的权限,或者只过滤有权限的字段查询。
      • 若是有权限,并且也只查询了有权限的字段,在实例比较老的版本可能存在缺陷,您可以在执行的Query前增加如下命令解决报错问题。
        set hg_experimental_enable_MaxCompute_executor=on;  
        set hg_experimental_enable_query_master=on;
        更多关于MaxCompute的权限问题,请参见MaxCompute权限相关

查询外部表速度慢如何解决?

建议优化SQL,详情请参见优化MaxCompute外部表的查询性能