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

上次更新日期:2021 年 4 月 28 日

我想在 Apache Hive 和 Amazon Relational Database Service (Amazon RDS) MySQL 数据库实例上的元存储之间设置 SSL 连接。该如何操作?

简短描述

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

解决方法

注意:以下步骤已通过 Amazon EMR 5.18.0 版本和 Amazon RDS MySQL 5.7 版本测试。

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

1.    运行与以下内容类似的命令以创建 Amazon RDS MySQL 数据库实例。将 $RDS_LEADER_USER_NAME$RDS_LEADER_PASSWORD 替换为您的用户名和密码。有关更多信息,请参阅 create-db-instance

注意:如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请确保您使用的是最新的 CLI 版本。

aws rds create-db-instance --db-name hive --db-instance-identifier mysql-hive-meta --db-instance-class db.t2.micro\ 
    --engine mysql --engine-version 5.7.19 --master-username $RDS_LEADER_USER_NAME --master-user-password $RDS_LEADER_PASSWORD\
    --allocated-storage 20 --storage-type gp2 --vpc-security-group-ids $RDS_VPC_SG --publicly-accessible

2.    以主用户身份连接到 Amazon RDS MySQL 数据库实例。然后,为 Hive 元存储创建用户,如以下示例所示。

重要提示:确保将此用户的访问权限限制为在第 1 步中创建的数据库实例。

mysql -h mysql-hive-meta.########.us-east-1.rds.amazonaws.com -P 3306 -u $RDS_LEADER_USER_NAME -p
Enter password: $RDS_LEADER_PASSWORD

CREATE USER 'hive_user'@'%' IDENTIFIED BY 'hive_user_password';
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'hive_user'@'%';
GRANT ALL PRIVILEGES ON hive.* TO 'hive_user'@'%' REQUIRE SSL;
FLUSH PRIVILEGES;

3.    创建与以下内容类似的 JSON 配置文件。将 hive_user 和 hive_user_password 替换为您在步骤 2 中在 JSON 脚本中使用的值。将 JDBC URL 中的终端节点替换为 RDS 数据库实例的终端节点。

下一步,您将使用此文件启动 Amazon EMR 集群。此文件将启用与 RDS 数据库实例的 SSL 连接。有关更多信息,请参阅将 SSL 与 MySQL 数据库实例结合使用

[
    {
        "Classification": "hive-site",
        "Properties": {
            "javax.jdo.option.ConnectionURL": "jdbc:mysql:\/\/mysql-hive-meta.########.us-east-1.rds.amazonaws.com:3306\/hive?createDatabaseIfNotExist=true&useSSL=true&serverSslCert=\/home\/hadoop\/rds-combined-ca-bundle.pem",
            "javax.jdo.option.ConnectionDriverName": "org.mariadb.jdbc.Driver",
            "javax.jdo.option.ConnectionUserName": "hive_user",
            "javax.jdo.option.ConnectionPassword": "hive_user_password"
        }
    }
]

4.    在与 Amazon RDS MySQL 实例关联的安全组中,使用以下参数创建入站规则
对于 Type(类型),选择 MYSQL/Aurora (3306)
对于 Protocol(协议),默认情况下选择 TCP (6)
对于 Port Range(端口范围),默认情况下选择 3306
对于,输入与领导节点关联的 Amazon EMR 托管安全组的组 ID

此规则允许 Amazon EMR 集群的领导节点访问 Amazon RDS 实例。有关更多信息,请参阅 VPC 安全组

5.    运行 create-cluster 命令以使用步骤 3 中的 JSON 文件以及引导操作来启动 Amazon EMR 集群。引导操作会将 SSL 证书下载到领导节点上的 /home/hadoop/

例如:

aws emr create-cluster --applications Name=Hadoop Name=Hive --tags Name="EMR Hive Metastore"\
    --ec2-attributes KeyName=$EC2_KEY_PAIR,InstanceProfile=EMR_EC2_DefaultRole,SubnetId=$EMR_SUBNET,EmrManagedSlaveSecurityGroup=$EMR_CORE_AND_TASK_VPC_SG,EmrManagedMasterSecurityGroup=$EMR_MASTER_VPC_SG\
   
    --service-role EMR_DefaultRole --release-label emr-5.18.0 --log-uri s3://awsdoc-example-bucket/emr-logs-path/ --name "Hive External Metastore RDS MySQL w/ SSL"\
    --instance-groups InstanceGroupType=MASTER,InstanceCount=1,InstanceType=m3.xlarge,Name="Master
    - 1"\ 
    --configurations file://hive-ext-meta-mysql-ssl.json\
    --bootstrap-actions Path=s3://elasticmapreduce/bootstrap-actions/run-if,Args=["instance.isMaster=true","cd /home/hadoop && wget -S -T
    10 -t 5 https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem"]

6.    使用 SSH 连接到领导节点

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.    使用领导节点上的 mysql 客户端连接到 RDS MySQL 元存储。然后,验证元存储中的表元数据。如果元数据与您在上一步中创建的表相对应,则表示 SSL 连接工作正常。

例如:

mysql -h mysql-hive-meta.########.us-east-1.rds.amazonaws.com -P 3306 -u $RDS_LEADER_USER_NAME -p
Enter password: $RDS_LEADER_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)

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

注意:以下步骤假定您有一个 Amazon RDS MySQL 数据库实例。

1.    使用 SSH 连接到领导节点

2.    运行以下命令以将 SSL 证书下载到领导节点上的 /home/hadoop/

cd /home/hadoop && wget -S -T 10 -t 5 https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem

3.    在 /etc/hive/conf.dist 目录中,在 hive-site.xml 文件中添加或编辑以下行:

<property>
  <name>javax.jdo.option.ConnectionURL</name>
  <value>jdbc:mysql://mysql-hive-meta.########.us-east-1.rds.amazonaws.com:3306/hive?createDatabaseIfNotExist=true&amp;useSSL=true&amp;serverSslCert=/home/hadoop/rds-combined-ca-bundle.pem</value>
  <description>JDBC URL for the metastore database</description>
</property>

<property>
    <name>javax.jdo.option.ConnectionUserName</name>
    <value>hive_user</value>
    <description>User name for the metastore database</description>
</property>

<property>
    <name>javax.jdo.option.ConnectionPassword</name>
    <value>HIVE_USER_PASSWORD</value>
    <description>Password for metastore database</description>
</property>

此语法将启用与 RDS 数据库实例的 SSL 连接。确保将 JDBC URL 中的终端节点替换为 RDS 数据库实例的终端节点。

重要提示:与符号 (&) 是 XML 中的特殊字符。要在 hive-site.xml 中使用与符号(例如在 JDBC 字符串中),必须使用“&amp;”而不是“&”。 否则,当您重新启动 hive-hcatalog-server 时会出现错误。

4.    运行与以下内容类似的命令以测试 SSL 连接:

mysql -h mysql-hive-meta.########.us-east-1.rds.amazonaws.com -P 3306 -u hive_user -p --ssl-ca ./rds-combined-ca-bundle.pem

5.    在领导节点上重启 hive-server2hive-hcatalog-server。有关更多信息,请参阅重新启动进程

6.    在 /var/log/ 目录中,验证服务是否已成功重新启动。日志的条目应如下所示:

sudo stop hive-server2
sudo stop hive-hcatalog-server
sudo start hive-hcatalog-server
sudo start hive-server2

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.    使用领导节点上的 mysql 客户端连接到 RDS MySQL 元存储。然后,验证元存储中的表元数据。如果元数据与您在上一步中创建的表相对应,则表示 SSL 连接工作正常。

例如:

$ mysql -h mysql-hive-meta.########.us-east-1.rds.amazonaws.com -P 3306 -u $RDS_LEADER_USER_NAME -p
Enter password: $RDS_LEADER_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)

排除 hive-hcatalog-server 重新启动错误

当您尝试重启 hive-hcatalog-server 时,可能收到与以下内容类似的错误消息:

2020-08-20T14:18:50,750 WARN [main] org.apache.hadoop.hive.metastore.HiveMetaStore - Retrying creating default database after error: Unable to open a test connection to the given database. JDBC url = jdbc:mysql://mariadb-hive-meta.ch1nkjp4jjbq.eu-west-1.rds.amazonaws.com:3306/hive?createDatabaseIfNotExist=true&useSSL=true&serverSSlCert=/home/hadoop/rds-combined-ca-bundle.pem, username = masteruser. Terminating connection pool (set lazyInit to true if you expect to start your database after your app). Original Exception: ------
java.sql.SQLException: Host '172.31.41.187' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'

当 RDS MySQL 数据库实例将阻止 Amazon EMR 集群的领导节点作为安全预防措施实施时,通常会出现此错误消息。

要纠正此错误,请连接到其他本地计算机或已安装 mysqladmin 工具的 Amazon Elastic Compute Cloud (Amazon EC2) 实例。运行以下命令从数据库实例刷新领导节点。

mysqladmin -h mysql-hive-meta.########.us-east-1.rds.amazonaws.com -P 3306 -u $RDS_LEADER_USER_NAME -p flush-hosts
Enter password: $RDS_LEADER_PASSWORD

您现在应该能够成功重新启动 hive-hcatalog-server


这篇文章对您有帮助吗?


您是否需要账单或技术支持?