如何在 Amazon EMR 上的 Hive 和 Amazon RDS for MySQL 上的元存储之间设置 SSL 连接?

6 分钟阅读
0

我想在 Amazon EMR 上的 Hive 和 Amazon Relational Database Service (Amazon RDS) for MySQL 上的元存储之间设置 SSL 连接。

简短描述

要在 Hive 和外部元存储之间设置加密连接,请使用 SSL 证书。您可以在启动新的 Amazon EMR 集群时或在集群运行之后设置 SSL 连接。

**注意:**以下步骤已通过 Amazon EMR 版本 7.3.0 和 Amazon RDS for MySQL 版本 8.0.39 测试。

解决方法

**注意:**如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI

在新的 Amazon EMR 集群上设置 SSL 连接

完成以下步骤:

  1. 要创建 Amazon RDS for MySQL 数据库实例,请运行以下 create-db-instance 命令:

    aws rds create-db-instance \
     --db-name hive \
     --db-instance-identifier example-db-instance-identifier \
     --db-instance-class db.c6gd.large \
     --engine mysql --engine-version 8.0.39 \
     --db-subnet-group-name example-subnet-group \
     --master-username example-rds-primary-user \
     --master-user-password example-rds-primary-password \
     --allocated-storage 200 \
     --storage-type gp3 \
     --vpc-security-group-ids example-rds-vpc-security-group

    **注意:**请将 example-db-instance-identifier 替换为您的数据库实例标识符,将 example-subnet-group 替换为您的子网组名称,将 example-rds-primary-user 替换为您的 Amazon RDS 主用户名,将 example-rds-primary-password 替换为您的 Amazon RDS 主密码。此外,请将 example-rds-vpc-security-group 替换为您的 Amazon RDS Amazon Virtual Private Cloud (Amazon VPC) 安全组名称。

  2. 以主用户身份连接到 Amazon RDS for MySQL 数据库实例。然后,为 Hive 元存储创建一个用户:
    **注意:**确保限制主用户对先前创建的数据库实例的访问权限。

    mysql -h example-rds-db-instance-endpoint -P 3306 -u example-rds-primary-user -p
    Enter password: example-rds-primary-password
    CREATE USER 'example-hive-username' IDENTIFIED BY 'example-hive-password' REQUIRE SSL;
    REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'example-hive-username';
    GRANT ALL PRIVILEGES ON hive.* TO 'example-hive-username';
    FLUSH PRIVILEGES;

    注意: 请将 example-rds-db-instance-endpoint 替换为您的 Amazon RDS 数据库实例端点,将 example-rds-primary-user 替换为您的 Amazon RDS 主用户名,将 example-rds-primary-password 替换为您的 Amazon RDS 主密码。此外,请将 example-hive-username 替换为您的 Hive 用户名,将 example-hive-password 替换为 example-hive-username 的密码。

  3. 创建类似于以下的 JSON 配置文件:

    **注意:**使用以下 JSON 文件在下一步中启动 Amazon EMR 集群。该文件允许 Hive 与 Amazon RDS 数据库实例建立 SSL 连接

    [
        {
            "Classification": "hive-site",
            "Properties": {
                "javax.jdo.option.ConnectionURL": "jdbc:mysql://example-rds-db-instance-endpoint:3306/hive?createDatabaseIfNotExist=true&useSSL=true&serverSslCert=/home/hadoop/global-bundle.pem",
                "javax.jdo.option.ConnectionDriverName": "org.mariadb.jdbc.Driver",
                "javax.jdo.option.ConnectionUserName": "example-hive-username",
                "javax.jdo.option.ConnectionPassword": "example-hive-password"
            }
        }
    ]

    **注意:**请将 example-rds-db-instance-endpoint 替换为您的 Amazon RDS 数据库实例端点,将 example-hive-username 替换为 Hive 将用于连接 Amazon RDS 数据库实例的用户名,将 example-hive-password 替换为 example-hive-username 的密码。

  4. 在与您的 Amazon RDS for MySQL 实例关联的安全组中创建入站规则,如下所示:
    对于 Type(类型),选择 MYSQL/Aurora (3306)
    对于 Protocol(协议),默认情况下选择 TCP (6)
    对于 Port Range(端口范围),默认情况下选择 3306
    对于 Source(源),输入与主节点关联的 Amazon EMR 托管式安全组的 Group ID(组 ID)。
    **注意:**此规则允许 Amazon EMR 集群的主节点访问 Amazon RDS 实例。有关详细信息,请参阅 VPC 安全组概述

  5. 创建以下引导操作脚本文件。然后,将其上传到 Amazon S3 存储桶。引导操作会将 SSL 证书下载到主节点上的 /home/hadoop/

    #!/bin/bash
    if grep isMaster /mnt/var/lib/info/instance.json | grep false;
    then        
        echo "This is not primary node, do nothing, exiting"
        exit 0
    fi
    echo "This is primary, continuing to execute script"
    cd /home/hadoop
    wget -S -T 10 -t 5 https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem
  6. 要启动 Amazon EMR 集群,请通过先前的 JSON 文件和引导操作运行以下 create-cluster 命令:

    示例:

    aws emr create-cluster \
     --name "EMR Hive Metastore SSL" \
     --log-uri $LOG_URI \
     --release-label "emr-7.3.0" \
     --service-role $EMRServiceRole \
     --ec2-attributes KeyName=$EC2_KEY_PAIR,InstanceProfile=$EMREC2Role,SubnetId=$EMR_SUBNET,EmrManagedSlaveSecurityGroup=$EMR_CORE_AND_TASK_VPC_SG,EmrManagedMasterSecurityGroup=$EMR_PRIMARY_VPC_SG \
     --applications Name=Hadoop Name=Hive \
     --bootstrap-actions Path=$BOOTSTRAP_ACTION_SCRIPT_PATH \
     --configurations file:///<Full-Path-To>/hive-ext-meta-mysql-ssl.json \
     --instance-groups '[{"InstanceCount":1,"InstanceGroupType":"CORE","Name":"Core","InstanceType":"m5.xlarge","EbsConfiguration":{"EbsBlockDeviceConfigs":[{"VolumeSpecification":{"VolumeType":"gp2","SizeInGB":32},"VolumesPerInstance":2}]}},{"InstanceCount":1,"InstanceGroupType":"MASTER","Name":"Primary","InstanceType":"m5.xlarge","EbsConfiguration":{"EbsBlockDeviceConfigs":[{"VolumeSpecification":{"VolumeType":"gp2","SizeInGB":32},"VolumesPerInstance":2}]}},{"InstanceCount":1,"InstanceGroupType":"TASK","Name":"Task - 1","InstanceType":"m5.xlarge","EbsConfiguration":{"EbsBlockDeviceConfigs":[{"VolumeSpecification":{"VolumeType":"gp2","SizeInGB":32},"VolumesPerInstance":2}]}}]'
  7. 使用 SSH 连接到主节点

  8. 在主节点上打开 Hive 会话。然后,创建用于测试目的的表。

    示例:

    hive> create table tb_test (col1 STRING, col2 BIGINT);
    OK
    Time taken: 2.371 seconds
    hive> describe tb_test;
    OK
    col1                    string
    col2                    bigint
    Time taken: 0.254 seconds, Fetched: 2 row(s)
  9. 要连接到 Amazon RDS for MySQL 元存储,请在主节点上使用 mysql 客户端。然后,检查元存储中的表元数据。如果元数据与您在上一步中创建的表相对应,则表示 SSL 连接有效。

    示例:

    mysql -h example-rds-db-instance-endpoint -P 3306 -u example-rds-primary-user -pEnter password: example-rds-primary-password
    
    mysql> use hive;
    Database changed
    
    mysql> select t1.OWNER, t1.TBL_NAME, t1.TBL_TYPE, s1.INPUT_FORMAT, s1.OUTPUT_FORMAT, s1.LOCATION from TBLS t1 inner join SDS s1 on s1.SD_ID = t1.SD_ID where t1.TBL_NAME = 'tb_test'\G
    *************************** 1. row ***************************
            OWNER: hadoop
         TBL_NAME: tb_test
         TBL_TYPE: MANAGED_TABLE
     INPUT_FORMAT: org.apache.hadoop.mapred.TextInputFormat
    OUTPUT_FORMAT: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
         LOCATION: hdfs://ip-xxx-xx-xx-xxx.ec2.internal:8020/user/hive/warehouse/tb_test
    1 row in set (0.23 sec)
    
    mysql> select t1.OWNER, t1.TBL_NAME, c1.COLUMN_NAME, c1.TYPE_NAME from TBLS t1 inner join SDS s1 on s1.SD_ID = t1.SD_ID inner join COLUMNS_V2 c1 on c1.CD_ID = s1.CD_ID where t1.TBL_NAME = 'tb_test';
    +--------+----------+-------------+-----------+
    | OWNER  | TBL_NAME | COLUMN_NAME | TYPE_NAME |
    +--------+----------+-------------+-----------+
    | hadoop | tb_test  | col1        | string    |
    | hadoop | tb_test  | col2        | bigint    |
    +--------+----------+-------------+-----------+
    2 rows in set (0.22 sec)

    **注意:**请将 example-rds-db-instance-endpoint 替换为您的 Amazon RDS 数据库实例端点,将 example-rds-primary-user 替换为您的 Amazon RDS 主用户名,将 example-rds-primary-password 替换为您的 Amazon RDS 主密码。

在正在运行的 Amazon EMR 集群上设置 SSL 连接

**注意:**在开始之前,请确保您拥有 Amazon RDS for MySQL 数据库实例。

  1. 要连接到主节点,请使用 SSH

  2. 将 SSL 证书下载到主节点上的 /home/hadoop/

    cd /home/hadoop && wget -S -T 10 -t 5 https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem
  3. /etc/hive/conf.dist 目录中,在 hive-site.xml 文件中添加或编辑以下行:

    <property>
      <name>javax.jdo.option.ConnectionURL</name>
      <value>jdbc:mysql://example-rds-db-instance-endpoint:3306/hive?createDatabaseIfNotExist=true&amp;useSSL=true&amp;serverSslCert=/home/hadoop/global-bundle.pem</value>
      <description>example-rds-db-instance-endpoint</description>
    </property>
    
    <property>
        <name>javax.jdo.option.ConnectionUserName</name>
        <value>example-hive-username</value>
        <description>example-metastore-db-user</description>
    </property>
    
    <property>
        <name>javax.jdo.option.ConnectionPassword</name>
        <value>example-hive-password</value>
        <description>example-metastore-db-password</description>
    </property>

    注意:请将 example-rds-db-instance-endpoint 替换为您的 Amazon RDS 数据库实例端点,将 example-hive-username 替换为 Hive 将用于连接 Amazon RDS 数据库实例的用户名,将 example-hive-password 替换为 example-hive-username 的密码。此外,和符号 (&) 是 XML 中的特殊字符。要在 hive-site.xml 中使用和符号,例如在 JDBC 字符串中,请使用 & 而不是 &。如果您不使用 &,则当你重启 hive-hcatalog-server 时,您会收到错误。

  4. 测试 SSL 连接:

    mysql -h example-rds-db-instance-endpoint -P 3306 -u example-hive-username -p --ssl-ca /home/hadoop/global-bundle.pem
    Enter password: example-hive-password

    **注意:**请将 example-rds-db-instance-endpoint 替换为您的 Amazon RDS 数据库实例端点,将 example-hive-username 替换为 Hive 将用于连接 Amazon RDS 数据库实例的用户名,将 example-hive-password 替换为 example-hive-username 的密码。

  5. 在主节点上重启 hive-hcatalog-server

  6. 确认服务已成功重启:

    sudo systemctl status hive-hcatalog-server.service
  7. 在主节点上打开 Hive 会话。然后,创建用于测试目的的表。

    示例:

    hive> create table tb_test (col1 STRING, col2 BIGINT);OK
    Time taken: 2.371 seconds
    
    hive> describe tb_test;
    OK
    col1                    string
    col2                    bigint
    Time taken: 0.254 seconds, Fetched: 2 row(s)
  8. 要连接到 Amazon RDS for MySQL 元存储,请在主节点上使用 mysql 客户端。然后,检查元存储中的表元数据。如果元数据与您在上一步中创建的表相对应,则表示 SSL 连接有效。

    示例:

    $ mysql -h example-rds-db-instance-endpoint -P 3306 -u example-rds-primary-user -p
    Enter password: example-rds-primary-password
    
    mysql> use hive;
    Database changed
    
    mysql> select t1.OWNER, t1.TBL_NAME, t1.TBL_TYPE, s1.INPUT_FORMAT, s1.OUTPUT_FORMAT, s1.LOCATION from TBLS t1 inner join SDS s1 on s1.SD_ID = t1.SD_ID where t1.TBL_NAME = 'tb_test'\G
    *************************** 1. row ***************************
            OWNER: hadoop
         TBL_NAME: tb_test
         TBL_TYPE: MANAGED_TABLE
     INPUT_FORMAT: org.apache.hadoop.mapred.TextInputFormat
    OUTPUT_FORMAT: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
         LOCATION: hdfs://ip-xxx-xx-xx-xxx.ec2.internal:8020/user/hive/warehouse/tb_test
    1 row in set (0.23 sec)
    
    mysql> select t1.OWNER, t1.TBL_NAME, c1.COLUMN_NAME, c1.TYPE_NAME from TBLS t1 inner join SDS s1 on s1.SD_ID = t1.SD_ID inner join COLUMNS_V2 c1 on c1.CD_ID = s1.CD_ID where t1.TBL_NAME = 'tb_test';
    +--------+----------+-------------+-----------+
    | OWNER  | TBL_NAME | COLUMN_NAME | TYPE_NAME |
    +--------+----------+-------------+-----------+
    | hadoop | tb_test  | col1        | string    |
    | hadoop | tb_test  | col2        | bigint    |
    +--------+----------+-------------+-----------+
    2 rows in set (0.22 sec)

    **注意:**请将 example-rds-db-instance-endpoint 替换为您的 Amazon RDS 数据库实例端点,将 example-rds-primary-user 替换为您的 Amazon RDS 主用户名,将 example-rds-primary-password 替换为您的 Amazon RDS 主密码。

对 hive-hcatalog-server 重启错误进行故障排除

当您尝试重启 hive-hcatalog-server 时,您可能会收到以下错误或类似错误:

“2020-08-20T14:18:50,750 WARN [main] org.apache.hadoop.hive.metastore.HiveMetaStore - 出错后重新尝试创建默认数据库: 无法打开与给定数据库的测试连接。JDBC url = jdbc:mysql://mysql-hive-meta.########.us-east-1.rds.amazonaws.com:3306/hive?createDatabaseIfNotExist=true&useSSL=true&serverSSlCert=/home/hadoop/global-bundle.pem, 用户名 = masteruser。终止连接池(如果希望在应用程序之后启动数据库,请将 lazyInit 设置为 true)。原始异常:------java.sql.SQLException: 由于许多连接错误,主机 '172.31.41.187' 被阻止;使用 'mysqladmin flush-hosts' 取消阻止”

作为安全预防措施,当 Amazon RDS for MySQL 数据库实例阻止 Amazon EMR 集群的主节点时,就会出现此错误。要解决此错误,请完成以下步骤:

  1. 连接到安装了 mysqladmin 工具的其他本地计算机或 Amazon Elastic Compute Cloud (Amazon EC2) 实例。
  2. 从数据库实例刷新主节点:
    mysqladmin -h example-rds-db-instance-endpoint -P 3306 -u example-rds-primary-username -p flush-hosts
    Enter password: example-rds-primary-password
    **注意:**请将 example-rds-primary-username 替换为您的 Amazon RDS 主用户名,将 example-rds-primary-password 替换为您的 Amazon RDS 主密码。
  3. 重启 hive-hcatalog-server

相关信息

使用外部 MySQL 数据库或 Amazon Aurora

AWS 官方
AWS 官方已更新 3 个月前