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"]
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 インスタンスがあることを前提としています。
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&useSSL=true&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 でアンパサンドを使用するには、「&」の代わりに「&」を使用する必要があります。 そうしないと、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-server2 と hive-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 を正常に再起動できるはずです。