文档

基于Hive Metastore访问OSS数据湖数据(Beta)

更新时间:

Hologres从V2.2版本开始,支持通过Hive Metastore访问存储于OSS上的数据湖数据,如您使用EMR集群构建了基于OSS的数据湖环境,可通过简单配置实现Hologres加速读写OSS和OSS-HDFS数据。

前提条件

  • 已开通OSS服务。具体操作,请参见控制台快速入门

  • 已创建EMR数据湖集群构建测试数据。具体操作,请参见创建集群。Hologres支持的EMR集群需满足以下条件:

    • Hive为3.1.3及以上版本。

    • 未开启Kerberos身份认证。

    • 元数据选择自建RDS或者内置MySQL

  • 已购买Hologres实例并开启数据湖加速,然后登录Hologres实例并创建数据库。具体操作,请参见购买Hologres创建数据库

    说明

    开启数据湖加速方式:访问Hologres实例列表,单击目标实例操作列中的数据湖加速并确认,开启数据湖加速功能。

  • 已提交网络打通申请,阿里云Hologres技术支持人员会协助您创建反向终端节点,打通网络。网络打通申请链接,请参见网络打通申请

    说明

    当前网络配置是通过IP来进行连接,当EMR集群IP发生变化后,需要重新配置。

限制条件

  • Hologres只读从实例暂不支持开启数据湖加速功能。

  • 不支持对外部表执行UPDATEDELETETRUNCATE等操作。

  • 暂不支持通过Auto Load方式映射来自HMS的外部表。

  • 暂不支持开启了Kerberos身份认证的Hive集群。

操作步骤

  1. 执行SQL命令,创建EXTENSION。

    创建EXTENSION需要Superuser权限,该操作针对整个DB生效,一个DB只需执行一次。

    CREATE EXTENSION IF NOT EXISTS hive_fdw;
  2. 基于hive_fdw创建Foreign Server(外部服务器)并配置Endpoint信息。

    CREATE SERVER IF NOT EXISTS <server_name> FOREIGN DATA WRAPPER hive_fdw 
    OPTIONS (
       hive_metastore_uris 'thrift://<Hive metastore的IP地址>:<端口号>',
       oss_endpoint 'oss-<nation>-<region>-internal.aliyuncs.com | <bucket>.oss-<nation>-<region>.oss-dls.aliyuncs.com' 
    );

    参数

    是否必填

    说明

    示例值

    server_name

    自定义Foreign Server名称。

    hive_server

    hive_metastore_uris

    Hive MetaStore的URI。格式为thrift://<Hive metastore的IP地址>:<端口号>,端口号默认为9083。

    说明

    您可以登录E-MapReduce控制台,单击目标集群操作列中的节点管理。在节点管理页签,获取master节点的内网 IP,内网IP即Hive metastore的IP地址。

    thrift://172.16.0.250:9083

    oss_endpoint

    OSS的Endpoint地址。您可以根据自己实际业务选择:

    • 原生OSS存储:为获得更好的访问性能,推荐使用OSS的内网Endpoint。

    • OSS-HDFS存储:目前仅支持内网访问。

    说明

    您可以登录OSS管理控制台,进入Bucket文件的概览页面,在访问端口区域,获取OSS的Endpoint地址。

    • OSS

      oss-cn-shanghai-internal.aliyuncs.com
    • OSS-HDFS

      <bucket_name>.cn-beijing.oss-dls.aliyuncs.com
  3. (可选)创建用户映射。

    Hologres支持通过CREATE USER MAPPING来指定其他用户身份访问特定的Foreign Server。例如:Foreign Server的Owner可以通过CREATE USER MAPPING指定RAM用户(123xxx)来访问OSS外部数据。CREATE USER MAPPING详情,请参见postgres create user mapping

    CREATE USER mapping FOR <账号> server <server_name> options
    (
        dlf_access_id 'accessid', 
        dlf_access_key 'accesskey',
        oss_access_id 'accessid', 
        oss_access_key 'accesskey'
    );

    示例如下。

    --为当前用户创建用户映射
    CREATE USER mapping FOR current_user server <server_name> options
    (
        dlf_access_id 'LTAI5txxx', 
        dlf_access_key 'y8LUUyyy',
        oss_access_id 'LTAI5txxx', 
        oss_access_key 'y8LUUyyy'
    );
    
    --为RAM用户123xxx创建用户映射
    CREATE USER mapping FOR "p4_123xxx" server <server_name> options
    (
        dlf_access_id 'LIlY5txxx', 
        dlf_access_key 'KsjkXKyyy',
        oss_access_id 'LIlY5txxx', 
        oss_access_key 'KsjkXKyyy'
    );
    
    --删除用户映射
    Drop USER MAPPING FOR CURRENT_USER server <server_name>;
    Drop USER MAPPING FOR "p4_123xxx" server <server_name>;
  4. 创建外部表。

    Hologres支持以下命令创建外部表:

    • CREATE FOREIGN TABLE:一次仅创建一张外部表,但支持通过指定部分列来自定义创建外部表,适用于需要创建的外部表较少且无需映射所有外部表字段的情况。

    • IMPORT FOREIGN SCHEMA:批量创建外部表,适用于需要创建多张外部表或者外部数据源批量映射的场景。

    说明
    • Hologres支持读取OSS中的分区表,并且支持将TEXT、VARCHAR和INT作为分区键的数据类型。使用CREATE FOREIGN TABLE方式时,由于只进行字段映射而不实际存储数据,只需要将分区字段作为普通字段来创建即可;而使用IMPORT FOREIGN SCHEMA方式时,则无需关心表字段,系统会自动处理表字段映射。

    • 如果OSS外部表存在和Hologres内部表同名的表,IMPORT FOREIGN SCHEMA会跳过该外部表的创建。建议使用CREATE FOREIGN TABLE来定义一个非重复表名来创建。

    -- CREATE FOREIGN TABLE方式
    CREATE FOREIGN TABLE <holo_schema_name>.<table_name>
    (
      { column_name data_type }
      [, ... ]
      ] )
    )
    SERVER <hive_server_name>
    OPTIONS
    (
      schema_name '<ext_db_name>',
      table_name '<ext_table_name>'
    );
    
    
    -- IMPORT FOREIGN SCHEMA方式
    IMPORT FOREIGN SCHEMA <ext_db_name> 
    [
      { limit TO | EXCEPT } 
      ( table_name [, ...] ) 
    ]
    FROM server <hive_server_name>
    INTO <holo_schema_name> 
    options(
      if_table_exist 'update',
      if_unsupported_type 'error'
            );
  5. 查询外部表。

    创建外部表成功后,可以直接查询外部表读取OSS中的数据。

    • 非分区表

      SELECT * FROM <holo_schema>.<hive_table>;
    • 分区表

      SELECT * FROM <holo_schema>.<hive_partition_table> WHERE <partition_key> = '<partition_value>';