Amazon EMR の Hive と Amazon RDS MySQL のメタストアとの間で SSL 接続を設定する方法を教えてください。

最終更新日: 2020 年 9 月 4 日

Apache Hiveと、Amazon Relational Database Service (Amazon RDS) MySQL DB インスタンスにあるメタストア間の SSL 接続を設定したいと思います。どうすればできますか?

簡単な説明

Hive と外部メタストア間の暗号化された接続を設定するには、SSL 証明書を使用します。この接続は、新しい Amazon EMR クラスターを起動するとき、またはクラスターの実行後に設定できます。

解決方法

注: 次の手順は、Amazon EMR リリースバージョン 5.18.0 および Amazon RDS MySQL バージョン 5.7 でテストしました。

新しい Amazon EMR クラスターで SSL 接続を設定する

1.     次のようなコマンドを実行して、Amazon RDS MySQL DB インスタンスを作成します。$RDS_MASTER_USER_NAME$RDS_MASTER_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_MASTER_USER_NAME --master-user-password $RDS_MASTER_PASSWORD\
    --allocated-storage 20 --storage-type gp2 --vpc-security-group-ids $RDS_VPC_SG --publicly-accessible

2.     マスターユーザーとして Amazon RDS MySQL DB インスタンスに接続します 。次に、以下の例に示すように、Hive メタストアのユーザーを作成します。

重要: このユーザーのアクセスは、ステップ 1 で作成した DB インスタンスに制限してください。

mysql -h mysql-hive-meta.########.us-east-1.rds.amazonaws.com -P 3306 -u $RDS_MASTER_USER_NAME -p
Enter password: $RDS_MASTER_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 DB インスタンスのエンドポイントに置き換えます。

このファイルを使用して、次のステップで Amazon EMR クラスターを起動します。このファイルにより、RDS DB インスタンスへの SSL 接続が有効になります。詳細については、「MySQL DB インスタンスでの SSL の使用」を参照してください。

[
    {
        "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] が選択されています。
[Source] に、マスターノードに関連付けられている Amazon EMR 管理セキュリティグループのグループ ID を入力します。

このルールにより、Amazon EMR クラスターのマスターノードが Amazon RDS インスタンスにアクセスできるようになります。詳細については、「VPC セキュリティグループ」を参照してください。

5.     ステップ 3 の JSON ファイルと、マスターノードの /home/hadoop/ に SSL 証明書をダウンロードするブートストラップアクションを使用して、create-cluster コマンドを実行して Amazon EMR クラスターを起動します。例:

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_MASTER_USER_NAME -p
Enter password: $RDS_MASTER_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 DB インスタンスがあることを前提としています。

1.     SSH を使用してマスターノードに接続します

2.     次のコマンドを実行して、マスターノードの /home/hadoop/ に SSL 証明書をダウンロードします。

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 ファイルの次の行を追加または編集します。これにより、RDS DB インスタンスへの SSL 接続が有効になります。次の例では、JDBC URL のエンドポイントを RDS DB インスタンスのエンドポイントに置き換えます。

<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>

重要: アンパサンド (&) は、XML の特殊文字です。JDBC 文字列など、hive-site.xml でアンパサンドを使用するには、「&」の代わりに「&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_MASTER_USER_NAME -p
Enter password: $RDS_MASTER_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 を再起動しようとすると、次のようなエラーメッセージが表示されることがあります。これは、通常、セキュリティ対策として RDS MySQL DB インスタンスが EMR クラスターのマスターノードをブロックする場合に発生します。

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'

このエラーを解決するには、別のローカルマシンに接続するか、または mysqladmin ツールがインストールされている Amazon Elastic Compute Cloud (Amazon EC2) インスタンスに接続します。DB インスタンスからマスターノードをフラッシュするには、次のコマンドを実行します。

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

これで、hive-hcatalog-server を正常に再起動できるはずです。


この記事はお役に立ちましたか?


請求に関するサポートまたは技術的なサポートが必要ですか?