Amazon EMR 上の Hive と Amazon RDS for MySQL 上のメタストアとの間に SSL 接続を設定する方法を教えてください。
Amazon EMR 上の Hive と Amazon Relational Database Service (Amazon RDS) for MySQL 上のメタストアの間に SSL 接続を設定したいです。
簡単な説明
Hive と外部メタストア間に暗号化された接続を設定するには、SSL 証明書を使用します。SSL 接続は、新しい Amazon EMR クラスターを起動するときか、クラスターの実行後に設定できます。
注: 次の手順は、Amazon EMR バージョン 7.3.0 と Amazon RDS for MySQL バージョン 8.0.39 でテストされました。
解決策
注: AWS コマンドラインインターフェイス (AWS CLI) コマンドの実行中にエラーが発生した場合は、「AWS CLI で発生したエラーのトラブルシューティング」を参照してください。また、AWS CLI の最新バージョンを使用していることを確認してください。
新しい Amazon EMR クラスターで SSL 接続を設定する
次の手順を実行します。
-
Amazon RDS for MySQL DB インスタンスを作成するには、次の 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 を DB インスタンス識別子に、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) セキュリティグループ名に置き換えます。
-
Amazon RDS for MySQL DB インスタンスにプライマリユーザーとして接続します。次に、Hive メタストアのユーザーを作成します。
注: プライマリユーザーのアクセスを、先ほど作成した DB インスタンスに制限していることを確認してください。mysql -h example-rds-db-instance-endpoint -P 3306 -u example-rds-primary-user -p Enter password: example-rds-primary-passwordCREATE 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 DB インスタンスのエンドポイントに、example-rds-primary-user を Amazon RDS のプライマリユーザー名に、example-rds-primary-password を Amazon RDS のプライマリパスワードに変更します。さらに、example-hive-username を Hive のユーザー名に、example-hive-password を example-hive-username で使用するパスワードに変更します。
-
次のような JSON 設定ファイルを作成します。
注: 次のステップでは、以下の JSON ファイルを使用して Amazon EMR クラスターを起動します。このファイルにより、Hive は Amazon RDS DB インスタンスへの 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 DB インスタンスのエンドポイントに、example-hive-username を Hive が Amazon RDS DB インスタンスへの接続に使用するユーザー名に、example-hive-password を example-hive-username のパスワードに置き換えます。
-
次のように、Amazon RDS for MySQL インスタンスに関連付けられたセキュリティグループ用のインバウンドルールを作成します。
[タイプ] で [MYSQL/Aurora (3306)] を選択します。
[プロトコル] では [TCP (6)] がデフォルトで選択されています。
[ポート範囲] には、3306 がデフォルトで選択されています。
[ソース] に、プライマリノードに関連付けられた Amazon EMR マネージドセキュリティグループのグループ ID を入力します。
注: このルールにより、Amazon EMR クラスターのプライマリノードが Amazon RDS インスタンスにアクセスすることができます。詳細については、「VPC セキュリティグループの概要」を参照してください。 -
次のブートストラップアクション用スクリプトファイルを作成します。作成したファイルを 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 -
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}]}}]' -
プライマリノードで Hive セッションを開きます。次に、テスト用のテーブルを作成します。
例:
hive> create table tb_test (col1 STRING, col2 BIGINT); OK Time taken: 2.371 secondshive> describe tb_test; OK col1 string col2 bigint Time taken: 0.254 seconds, Fetched: 2 row(s) -
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 DB インスタンスのエンドポイントに、example-rds-primary-user を Amazon RDS のプライマリユーザー名に、example-rds-primary-password を Amazon RDS のプライマリパスワードに変更します。
実行中の Amazon EMR クラスターで SSL 接続を設定する
注: 開始する前に、Amazon RDS for MySQL DB インスタンスがあることを確認してください。
-
SSL 証明書をプライマリノードの /home/hadoop/ にダウンロードします。
cd /home/hadoop && wget -S -T 10 -t 5 https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem -
/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&useSSL=true&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 DB インスタンスのエンドポイントに、example-hive-username を Hive が Amazon RDS DB インスタンスへの接続に使用するユーザー名に、example-hive-password を example-hive-username のパスワードに置き換えます。なお、アンパサンド (&) は XML の特殊文字です。hive-site.xml において、JDBC 文字列などにアンパサンドを使用するには、& ではなく & を使用します。& を使用しなかった場合は、hive-hcatalog-server の再起動時にエラーが発生します。
-
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 DB インスタンスのエンドポイントに、example-hive-username を Hive が Amazon RDS DB インスタンスへの接続に使用するユーザー名に、example-hive-password を example-hive-username のパスワードに置き換えます。
-
プライマリノードで hive-hcatalog-server を再起動します。
-
サービスが正常に再起動したことを確認します。
sudo systemctl status hive-hcatalog-server.service -
プライマリノードで 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) -
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 DB インスタンスのエンドポイントに、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, username = masteruser.接続プールを終了します (アプリケーションの実行後にデータベースを起動する予定であれば、lazyInit を true に設定してください)。元の例外: ------java.sql.SQLException: 接続エラーが多数発生したため、ホスト '172.31.41.187' はブロックされています。'mysqladmin flush-hosts' でブロックを解除してください」
このエラーは、Amazon RDS for MySQL DB インスタンスがセキュリティ対策として Amazon EMR クラスターのプライマリノードをブロックした場合に発生します。このエラーを解決するには、次の手順を実行します。
- mysqladmin ツールがインストールされている、別のローカルマシンまたは Amazon Elastic Compute Cloud (Amazon EC2) インスタンスに接続します。
- DB インスタンスからプライマリノードをフラッシュします。
注: お使いのものでそれぞれ、example-rds-primary-username を Amazon RDS のプライマリユーザー名に、example-rds-primary-password を Amazon RDS のプライマリパスワードに変更します。mysqladmin -h example-rds-db-instance-endpoint -P 3306 -u example-rds-primary-username -p flush-hosts Enter password: example-rds-primary-password - hive-hcatalog-server を再起動します。

