

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用外部 Hive 元存储
<a name="external-metastore"></a>

您可以配置 EMR Serverless Spark 和 Hive 作业，使其连接到外部 Hive 元存储，如 Amazon Aurora 或 Amazon RDS for MySQL。本节介绍了如何设置 Amazon RDS Hive 元存储、配置 VPC 和配置 EMR Serverless 作业以使用外部元存储。

## 创建外部 Hive 元存储
<a name="external-metastore-create"></a>

1. 按照[创建 VPC](https://docs.amazonaws.cn/vpc/latest/userguide/working-with-vpcs.html#Create-VPC) 中的说明，创建具有私有子网的 Amazon Virtual Private Cloud（Amazon VPC）。

1. 使用新的 Amazon VPC 和私有子网创建 EMR Serverless 应用程序。当您使用 VPC 配置 EMR Serverless 应用程序时，首先会为您指定的每个子网预置一个弹性网络接口。然后，将您指定的安全组附加到该网络接口。这样就可以对应用程序进行访问控制。有关如何设置 VPC 的更多详细信息，请参阅 [为 EMR Serverless 应用程序配置 VPC 访问权限以连接数据](vpc-access.md)。

1. 在 Amazon VPC 的私有子网中创建 MySQL 或 Aurora PostgreSQL 数据库。有关如何创建 Amazon RDS 数据库的信息，请参阅[创建 Amazon RDS 数据库实例](https://docs.amazonaws.cn/AmazonRDS/latest/UserGuide/USER_CreateDBInstance.html)。

1. 按照[修改 Amazon RDS 数据库实例](https://docs.amazonaws.cn/AmazonRDS/latest/UserGuide/Overview.DBInstance.Modifying.html)中的步骤修改 MySQL 或 Aurora 数据库的安全组，允许来自 EMR Serverless 安全组的 JDBC 连接。为从其中一个 EMR Serverless 安全组到 RDS 安全组的入站流量添加规则。    
[See the AWS documentation website for more details](http://docs.amazonaws.cn/emr/latest/EMR-Serverless-UserGuide/external-metastore.html)

## 配置 Spark 选项
<a name="external-metastore-spark"></a>

**使用 JDBC**

要将 EMR Serverless Spark 应用程序配置为连接到基于 Amazon RDS for MySQL 或 Amazon Aurora MySQL 实例的 Hive 元存储，请使用 JDBC 连接。在作业运行的 `spark-submit` 参数中传递带有 `--jars` 的 `mariadb-connector-java.jar`。

```
aws emr-serverless start-job-run \
  --application-id "{{application-id}}" \
  --execution-role-arn "{{job-role-arn}}" \
  --job-driver '{
        "sparkSubmit": {
            "entryPoint": "s3://{{amzn-s3-demo-bucket}}/scripts/spark-jdbc.py",
            "sparkSubmitParameters": "--jars s3://{{amzn-s3-demo-bucket}}/mariadb-connector-java.jar 
            --conf spark.hadoop.javax.jdo.option.ConnectionDriverName=org.mariadb.jdbc.Driver 
            --conf spark.hadoop.javax.jdo.option.ConnectionUserName=<connection-user-name> 
            --conf spark.hadoop.javax.jdo.option.ConnectionPassword=<connection-password>
            --conf spark.hadoop.javax.jdo.option.ConnectionURL=<JDBC-Connection-string> 
            --conf spark.driver.cores=2
            --conf spark.executor.memory=10G 
            --conf spark.driver.memory=6G 
            --conf spark.executor.cores=4"
        }
    }' \
    --configuration-overrides '{
        "monitoringConfiguration": {
        "s3MonitoringConfiguration": {
            "logUri": "s3://{{amzn-s3-demo-bucket}}/spark/logs/"
        }
    }
}'
```

以下代码示例是一个 Spark 入口点脚本，与 Amazon RDS 上的 Hive 元存储交互。

```
from os.path import expanduser, join, abspath
from pyspark.sql import SparkSession
from pyspark.sql import Row
# warehouse_location points to the default location for managed databases and tables
warehouse_location = abspath('spark-warehouse')
spark = SparkSession \
    .builder \
    .config("spark.sql.warehouse.dir", warehouse_location) \
    .enableHiveSupport() \
    .getOrCreate()
spark.sql("SHOW DATABASES").show()
spark.sql("CREATE EXTERNAL TABLE `sampledb`.`sparknyctaxi`(`dispatching_base_num` string, `pickup_datetime` string, `dropoff_datetime` string, `pulocationid` bigint, `dolocationid` bigint, `sr_flag` bigint) STORED AS PARQUET LOCATION 's3://<s3 prefix>/nyctaxi_parquet/'")
spark.sql("SELECT count(*) FROM sampledb.sparknyctaxi").show()
spark.stop()
```

**使用 thrift 服务**

您可以将 EMR Serverless Hive 应用程序配置为连接到基于 Amazon RDS for MySQL 或 Amazon Aurora MySQL 实例的 Hive 元存储。为此，请在现有 Amazon EMR 集群的主节点上运行 thrift 服务器。如果您已经有一个 Amazon EMR 集群，其中包含用于简化 EMR Serverless 作业配置的 thrift 服务器，则此选项是理想之选。

```
aws emr-serverless start-job-run \
  --application-id "{{application-id}}" \
  --execution-role-arn "{{job-role-arn}}" \
  --job-driver '{
        "sparkSubmit": {
            "entryPoint": "s3://{{amzn-s3-demo-bucket}}/thriftscript.py",
            "sparkSubmitParameters": "--jars s3://{{amzn-s3-demo-bucket}}/mariadb-connector-java.jar 
            --conf spark.driver.cores=2
            --conf spark.executor.memory=10G 
            --conf spark.driver.memory=6G 
            --conf spark.executor.cores=4"
        }
    }' \
    --configuration-overrides '{
        "monitoringConfiguration": {
        "s3MonitoringConfiguration": {
            "logUri": "s3://{{amzn-s3-demo-bucket}}/spark/logs/"
        }
    }
}'
```

以下代码示例是一个入口点脚本（`thriftscript.py`），使用 thrift 协议连接到 Hive 元存储。请注意，需要将 `hive.metastore.uris` 属性设置为从外部 Hive 元存储读取。

```
from os.path import expanduser, join, abspath
from pyspark.sql import SparkSession
from pyspark.sql import Row
# warehouse_location points to the default location for managed databases and tables
warehouse_location = abspath('spark-warehouse')
spark = SparkSession \
    .builder \
    .config("spark.sql.warehouse.dir", warehouse_location) \
    .config("hive.metastore.uris","thrift://{{thrift-server-host}}:{{thift-server-port}}") \
    .enableHiveSupport() \
    .getOrCreate()
spark.sql("SHOW DATABASES").show()
spark.sql("CREATE EXTERNAL TABLE sampledb.`sparknyctaxi`( `dispatching_base_num` string, `pickup_datetime` string, `dropoff_datetime` string, `pulocationid` bigint, `dolocationid` bigint, `sr_flag` bigint) STORED AS PARQUET LOCATION 's3://<s3 prefix>/nyctaxi_parquet/'")
spark.sql("SELECT * FROM sampledb.sparknyctaxi").show()
spark.stop()
```

## 配置 Hive 选项
<a name="external-metastore-hive"></a>

**使用 JDBC**

如果要在 Amazon RDS MySQL 或 Amazon Aurora 实例上指定外部 Hive 数据库位置，可以覆盖默认的元存储配置。

**注意**  
在 Hive 中，您可以同时对元存储表执行多次写入。如果在两个作业之间共享元存储信息，请确保不要同时写入同一个元存储表，除非写入同一元存储表的不同分区。

在 `hive-site` 分类中设置以下配置以激活外部 Hive 元存储。

```
{
    "classification": "hive-site",
    "properties": {
        "hive.metastore.client.factory.class": "org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClientFactory",
        "javax.jdo.option.ConnectionDriverName": "org.mariadb.jdbc.Driver",
        "javax.jdo.option.ConnectionURL": "jdbc:mysql://{{db-host}}:{{db-port}}/{{db-name}}",
        "javax.jdo.option.ConnectionUserName": "{{username}}",
        "javax.jdo.option.ConnectionPassword": "{{password}}"
    }
}
```

**使用 thrift 服务器**

您可以将 EMR Serverless Hive 应用程序配置为连接到基于 Amazon RDS for MySQL 或 Amazon Aurora MySQL 实例的 Hive 元存储。为此，请在现有 Amazon EMR 集群的主节点上运行 thrift 服务器。如果您已经有一个运行 thrift 服务器的 Amazon EMR 集群，希望使用 EMR Serverless 作业配置，则此选项是理想之选。

在 `hive-site` 分类中设置以下配置，以便 EMR Serverless 可以访问远程 thrift 元存储。请注意，必须将 `hive.metastore.uris` 属性设置为从外部 Hive 元存储读取。

```
{
    "classification": "hive-site",
    "properties": {
        "hive.metastore.client.factory.class": "org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClientFactory",
        "hive.metastore.uris": "thrift://{{thrift-server-host}}:{{thrift-server-port}}"
    }
}
```