Saltar al contenido

¿Cómo puedo configurar una conexión SSL entre Hive en Amazon EMR y un metastore en Amazon RDS para MySQL?

9 minutos de lectura
0

Quiero configurar una conexión SSL entre Hive en Amazon EMR y un metastore en Amazon Relational Database Service (Amazon RDS) para MySQL.

Descripción corta

Para configurar una conexión cifrada entre Hive y un metastore externo, use un certificado SSL. Puede configurar una conexión SSL al iniciar un nuevo clúster de Amazon EMR o después de que el clúster esté en ejecución.

Nota: Los pasos siguientes se probaron en la versión 7.3.0 de Amazon EMR y en la versión 8.0.39 de Amazon RDS para MySQL.

Resolución

Nota: Si se muestran errores al ejecutar comandos de la Interfaz de la línea de comandos de AWS (AWS CLI), consulte Solución de problemas de AWS CLI. Además, asegúrese de utilizar la versión más reciente de la AWS CLI.

Configuración de una conexión SSL en un nuevo clúster de Amazon EMR

Siga estos pasos:

  1. Para crear una instancia de base de datos de Amazon RDS para MySQL, ejecute el siguiente comando 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

    Nota: Sustituya example-db-instance-identifier por su identificador de instancia de base de datos, example-subnet-group por el nombre de su grupo de subredes, example-rds-primary-user por su nombre de usuario principal de Amazon RDS y example-rds-primary-password por su contraseña principal de Amazon RDS. Además, sustituya example-rds-vpc-security-group por el nombre del grupo de seguridad de Amazon Virtual Private Cloud (Amazon VPC) de Amazon RDS.

  2. Conéctese a la instancia de base de datos de Amazon RDS para MySQL como usuario principal. A continuación, cree un usuario para el metastore de Hive:
    Nota: Asegúrese de restringir el acceso del usuario principal a la instancia de base de datos que creó anteriormente.

    mysql -h example-rds-db-instance-endpoint -P 3306 -u example-rds-primary-user -p
    Enter password: example-rds-primary-password
    CREATE 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;

    Nota: Sustituya example-rds-db-instance-endpoint por el punto de enlace de la instancia de base de datos de Amazon RDS, example-rds-primary-user por su nombre de usuario principal de Amazon RDS y example-rds-primary-password por su contraseña principal de Amazon RDS. Además, sustituya example-hive-username por su nombre de usuario de Hive y example-hive-password por la contraseña para example-hive-username.

  3. Cree un archivo de configuración JSON similar al siguiente:

    Nota: Utilice el siguiente archivo JSON para iniciar el clúster de Amazon EMR en el siguiente paso. El archivo permite a Hive establecer una conexión SSL con la instancia de base de datos de Amazon RDS.

    [
        {
            "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"
            }
        }
    ]

    Nota: Sustituya example-rds-db-instance-endpoint por el punto de enlace de la instancia de base de datos de Amazon RDS, example-hive-username por el nombre de usuario que Hive utilizará para conectarse a la instancia de base de datos de Amazon RDS y example-hive-password por la contraseña para example-hive-username.

  4. Cree una regla de entrada en el grupo de seguridad asociado a su instancia de Amazon RDS para MySQL de la siguiente manera:
    En Tipo, elija MYSQL/Aurora (3306).
    En Protocolo, TCP (6) está seleccionado de forma predeterminada.
    En Intervalo de puertos, 3306 está seleccionado de forma predeterminada.
    En Origen, introduzca el ID de grupo del grupo de seguridad administrado de Amazon EMR que está asociado al nodo principal.
    Nota: Esta regla permite que el nodo principal del clúster de Amazon EMR acceda a la instancia de Amazon RDS. Para obtener más información, consulte Descripción general de los grupos de seguridad de VPC.

  5. Cree el siguiente archivo de script de acción de arranque. A continuación, cárguelo en un bucket de Amazon S3. La acción de arranque descarga el certificado SSL en /home/hadoop/ en el nodo principal.

    #!/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
  6. Para iniciar un clúster de Amazon EMR, ejecute el siguiente comando create-cluster con el archivo JSON y la acción de arranque anteriores:

    Ejemplo:

    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}]}}]'
  7. Use SSH para conectarse al nodo principal.

  8. Abra una sesión de Hive en el nodo principal. A continuación, cree una tabla con fines de prueba.

    Ejemplo:

    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)
  9. Para conectarse al metastore de Amazon RDS para MySQL, utilice el cliente mysql en el nodo principal. A continuación, compruebe los metadatos de la tabla en el metastore. Si los metadatos corresponden a la tabla que creó en el paso anterior, la conexión SSL funciona.

    Ejemplo:

    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)

    Nota: Sustituya example-rds-db-instance-endpoint por el punto de enlace de la instancia de base de datos de Amazon RDS, example-rds-primary-user por su nombre de usuario principal de Amazon RDS y example-rds-primary-password por su contraseña principal de Amazon RDS.

Configuración de una conexión SSL en un clúster de Amazon EMR en ejecución

Nota: Antes de empezar, asegúrese de que dispone de una instancia de base de datos de Amazon RDS para MySQL.

  1. Para conectarse al nodo principal, use SSH.

  2. Descargue el certificado SSL en /home/hadoop/ en el nodo principal:

    cd /home/hadoop && wget -S -T 10 -t 5 https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem
  3. En el directorio /etc/hive/conf.dist, agregue o edite las siguientes líneas en el archivo hive-site.xml:

    <property>
      <name>javax.jdo.option.ConnectionURL</name>
      <value>jdbc:mysql://example-rds-db-instance-endpoint:3306/hive?createDatabaseIfNotExist=true&amp;useSSL=true&amp;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>

    Nota: Sustituya example-rds-db-instance-endpoint por el punto de enlace de la instancia de base de datos de Amazon RDS, example-hive-username por el nombre de usuario que Hive utilizará para conectarse a la instancia de base de datos de Amazon RDS y example-hive-password por la contraseña para example-hive-username. Además, el signo & es un carácter especial en XML. Para usar un signo & en hive-site.xml, como en la cadena JDBC, utilice & en lugar de &. Si no utiliza &, se producirá un error cuando reinicie hive-hcatalog-server.

  4. Prueba de la conexión 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

    Nota: Sustituya example-rds-db-instance-endpoint por el punto de enlace de la instancia de base de datos de Amazon RDS, example-hive-username por el nombre de usuario que Hive utilizará para conectarse a la instancia de base de datos de Amazon RDS y example-hive-password por la contraseña para example-hive-username.

  5. Reinicie hive-hcatalog-server en el nodo principal.

  6. Confirme que los servicios se reiniciaron correctamente:

    sudo systemctl status hive-hcatalog-server.service
  7. Abra una sesión de Hive en el nodo principal. A continuación, cree una tabla con fines de prueba.

    Ejemplo:

    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. Para conectarse al metastore de Amazon RDS para MySQL, utilice el cliente mysql en el nodo principal. A continuación, compruebe los metadatos de la tabla en el metastore. Si los metadatos corresponden a la tabla que creó en el paso anterior, la conexión SSL funciona.

    Ejemplo:

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

    Nota: Sustituya example-rds-db-instance-endpoint por el punto de enlace de la instancia de base de datos de Amazon RDS, example-rds-primary-user por su nombre de usuario principal de Amazon RDS y example-rds-primary-password por su contraseña principal de Amazon RDS.

Solución de errores de reinicio de hive-hcatalog-server

Cuando intente reiniciar hive-hcatalog-server, es posible que se produzca el siguiente error o similar:

«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://mysql-hive-meta.########.us-east-1.rds.amazonaws.com:3306/hive?createDatabaseIfNotExist=true&useSSL=true&serverSSlCert=/home/hadoop/global-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'»

Este error se produce cuando la instancia de base de datos de Amazon RDS para MySQL bloquea el nodo principal del clúster de Amazon EMR como medida de seguridad. Para resolver este error, siga estos pasos:

  1. Conéctese a otro equipo local o instancia de Amazon Elastic Compute Cloud (Amazon EC2) que tenga instalada la herramienta mysqladmin.
  2. Vacíe el nodo principal de la instancia de base de datos:
    mysqladmin -h example-rds-db-instance-endpoint -P 3306 -u example-rds-primary-username -p flush-hosts
    Enter password: example-rds-primary-password
    Nota: Sustituya example-rds-primary-username por su nombre de usuario principal de Amazon RDS y example-rds-primary-password por su contraseña principal de Amazon RDS.
  3. Reinicie hive-hcatalog-server.

Información relacionada

Uso de una base de datos MySQL externa o Amazon Aurora

OFICIAL DE AWSActualizada hace un año