Amazon EMR의 Hive와 Amazon RDS MySQL의 메타스토어 간에 SSL 연결을 설정하려면 어떻게 해야 합니까?

최종 업데이트 날짜: 2020년 9월 4일

Apache Hive와 Amazon Relational Database Service(Amazon RDS) MySQL DB 인스턴스에 있는 메타스토어 간에 SSL 연결을 설정하려고합니다. 어떻게 해야 하나요?

간략한 설명

SSL 인증서를 사용하여 Hive와 외부 메타스토어 간에 암호화된 연결을 설정합니다. 새 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를 사용자 이름과 암호로 바꿉니다. 자세한 내용은 데이터베이스 인스턴스 생성을 참조하십시오.

참고: AWS Command Line Interface(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/오로라(3306)(MYSQL/Aurora(3306))]를 선택합니다.
[프로토콜(Protocol)]의 경우 기본적으로 [TCP(6)]가 선택됩니다.
[포트 범위(Port Range)]의 경우 기본적으로 [3306]이 선택됩니다.
[소스(Source)]에 마스터 노드와 연결된 Amazon EMR에서 관리하는 보안 그룹의 [그룹 ID(Group 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_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.     다음 명령을 실행하여 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 파일에 다음 줄을 추가하거나 편집합니다. 이렇게 하면 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를 다시 시작하려고 할 때 다음과 유사한 오류 메시지가 나타날 수 있습니다. 일반적으로 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를 다시 시작할 수 있습니다.


이 문서가 도움이 되었습니까?


결제 또는 기술 지원이 필요합니까?