

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# EMR Serverless 的中繼存放區組態
<a name="metastore-config"></a>

*Hive 中繼存放*區是集中位置，可存放資料表的結構資訊，包括結構描述、分割區名稱和資料類型。使用 EMR Serverless， 會將此資料表中繼資料保留在可存取您任務的中繼存放區中。

Hive 中繼存放區有兩個選項：
+  AWS Glue Data Catalog
+ 外部 Apache Hive 中繼存放區

## 使用 AWS Glue Data Catalog 做為中繼存放區
<a name="glue-metastore"></a>

您可以將 Spark 和 Hive 任務設定為使用 AWS Glue Data Catalog 作為其中繼存放區。當您需要持久性中繼存放區或不同應用程式、服務或共用的中繼存放區時，建議您使用此組態 AWS 帳戶。如需 Data Catalog 的詳細資訊，請參閱[填入 AWS Glue Data Catalog](https://docs.aws.amazon.com/glue/latest/dg/populate-data-catalog.html)。如需 AWS Glue 定價的相關資訊，請參閱 [AWS Glue 定價](https://aws.amazon.com/glue/pricing)。

您可以將 EMR Serverless 任務設定為在 AWS 帳戶 與應用程式相同的 或不同的 中使用 AWS Glue Data Catalog AWS 帳戶。

### 設定 AWS Glue Data Catalog
<a name="glue-metastore-configure"></a>

若要設定 Data Catalog，請選擇您要使用的 EMR Serverless 應用程式類型。

------
#### [ Spark ]

當您使用 EMR Studio 搭配 EMR Serverless Spark 應用程式執行任務時， AWS Glue Data Catalog 是預設中繼存放區。

當您使用 SDKs或 時 AWS CLI，請在任務執行的`sparkSubmit`參數`com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory`中將`spark.hadoop.hive.metastore.client.factory.class`組態設定為 。下列範例示範如何使用 設定 Data Catalog AWS CLI。

```
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/code/pyspark/extreme_weather.py",
            "sparkSubmitParameters": "--conf spark.hadoop.hive.metastore.client.factory.class=com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory --conf spark.driver.cores=1 --conf spark.driver.memory=3g --conf spark.executor.cores=4 --conf spark.executor.memory=3g"
        }
    }'
```

或者，您可以在 Spark 程式碼`SparkSession`中建立新的 時設定此組態。

```
from pyspark.sql import SparkSession

spark = (
    SparkSession.builder.appName("SparkSQL")
    .config(
        "spark.hadoop.hive.metastore.client.factory.class",
        "com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory",
    )
    .enableHiveSupport()
    .getOrCreate()
)

# we can query tables with SparkSQL
spark.sql("SHOW TABLES").show()

# we can also them with native Spark
print(spark.catalog.listTables())
```

------
#### [ Hive ]

對於 EMR Serverless Hive 應用程式，Data Catalog 是預設中繼存放區。也就是說，當您在 EMR Serverless Hive 應用程式上執行任務時，Hive 會在 AWS 帳戶 與您應用程式相同的 資料目錄中記錄中繼存放區資訊。您不需要虛擬私有雲端 (VPC) 即可使用 Data Catalog 做為中繼存放區。

若要存取 Hive 中繼存放區資料表，請新增設定 AWS Glue [的 IAM 許可中概述的必要 Glue AWS](https://docs.aws.amazon.com/glue/latest/dg/getting-started-access.html)政策。

------

### 設定 EMR Serverless 和 Glue Data Catalog AWS 的跨帳戶存取
<a name="glue-metastore-cross-account"></a>

若要設定 EMR Serverless 的跨帳戶存取權，請先登入以下內容 AWS 帳戶：
+ `AccountA` – 您已在 AWS 帳戶 其中建立 EMR Serverless 應用程式。
+ `AccountB` – AWS 帳戶 包含您希望 EMR Serverless 任務執行存取的 AWS Glue Data Catalog。

1. 確定 中的管理員或其他授權身分將資源政策`AccountB`連接到 中的 Data Catalog`AccountB`。此政策授予`AccountA`特定跨帳戶許可，以對`AccountB`目錄中的資源執行操作。

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Action": [
           "glue:GetDatabase",
           "glue:CreateDatabase",
           "glue:GetDataBases",
           "glue:CreateTable",
           "glue:GetTable",
           "glue:UpdateTable",
           "glue:DeleteTable",
           "glue:GetTables",
           "glue:GetPartition",
           "glue:GetPartitions",
           "glue:CreatePartition",
           "glue:BatchCreatePartition",
           "glue:GetUserDefinedFunctions"
         ],
         "Resource": [
           "arn:aws:glue:*:123456789012:catalog"
         ],
         "Sid": "AllowGLUEGetdatabase"
       }
     ]
   }
   ```

------

1. 將 IAM 政策新增至 中的 EMR Serverless 任務執行期角色，`AccountA`讓角色可以存取 中的 Data Catalog 資源`AccountB`。

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Action": [
           "glue:GetDatabase",
           "glue:CreateDatabase",
           "glue:GetDataBases",
           "glue:CreateTable",
           "glue:GetTable",
           "glue:UpdateTable",
           "glue:DeleteTable",
           "glue:GetTables",
           "glue:GetPartition",
           "glue:GetPartitions",
           "glue:CreatePartition",
           "glue:BatchCreatePartition",
           "glue:GetUserDefinedFunctions"
         ],
         "Resource": [
           "arn:aws:glue:*:123456789012:catalog"
         ],
         "Sid": "AllowGLUEGetdatabase"
       }
     ]
   }
   ```

------

1.  啟動您的任務執行。此步驟會因 `AccountA`的 EMR Serverless 應用程式類型而略有不同。

------
#### [ Spark ]

   在 中傳遞 `spark.hadoop.hive.metastore.glue.catalogid` 屬性`sparkSubmitParameters`，如下列範例所示。*`AccountB-catalog-id`* 將 取代為 中 Data Catalog 的 ID`AccountB`。

   ```
   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/test.py",
            "sparkSubmitParameters": "--conf spark.hadoop.hive.metastore.client.factory.class=com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory --conf spark.hadoop.hive.metastore.glue.catalogid=AccountB-catalog-id --conf spark.executor.cores=1 --conf spark.executor.memory=1g --conf spark.driver.cores=1 --conf spark.driver.memory=1g --conf spark.executor.instances=1"
       }
     }' \
   --configuration-overrides '{
       "monitoringConfiguration": {
       "s3MonitoringConfiguration": {
       "logUri": "s3://amzn-s3-demo-bucket/logs/"
       }
     }
   }'
   ```

------
#### [ Hive ]

   在`hive-site`分類中設定 `hive.metastore.glue.catalogid` 屬性，如下列範例所示。*`AccountB-catalog-id`* 將 取代為 中 Data Catalog 的 ID`AccountB`。

   ```
   aws emr-serverless start-job-run \
   --application-id "application-id" \
   --execution-role-arn "job-role-arn" \
   --job-driver '{
       "hive": {
       "query": "s3://amzn-s3-demo-bucket/hive/scripts/create_table.sql",
       "parameters": "--hiveconf hive.exec.scratchdir=s3://amzn-s3-demo-bucket/hive/scratch --hiveconf hive.metastore.warehouse.dir=s3://amzn-s3-demo-bucket/hive/warehouse"
       }
   }' \
   --configuration-overrides '{
       "applicationConfiguration": [{
           "classification": "hive-site",
           "properties": {
               "hive.metastore.glue.catalogid": "AccountB-catalog-id"
           }
       }]
   }'
   ```

------

### 使用 Glue Data Catalog AWS 時的考量事項
<a name="glue-metastore-considerations"></a>

您可以在 Hive 指令碼`ADD JAR`中使用 新增輔助 JARs。如需其他考量，請參閱[使用 Glue Data Catalog AWS 時的考量](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-hive-metastore-glue.html#emr-hive-glue-considerations-hive)。

# 使用外部 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 中的指示，使用私有子網路建立 Amazon Virtual Private Cloud (Amazon VPC)。 [https://docs.aws.amazon.com/vpc/latest/userguide/working-with-vpcs.html#Create-VPC](https://docs.aws.amazon.com/vpc/latest/userguide/working-with-vpcs.html#Create-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.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_CreateDBInstance.html)。

1. 依照修改 [Amazon RDS 資料庫執行個體](https://docs.aws.amazon.com/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.aws.amazon.com/zh_tw/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/"
        }
    }
}'
```

下列程式碼範例是與 Amazon RDS 上的 Hive 中繼存放區互動的 Spark 進入點指令碼。

```
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 MySQLinstance 連線至 Hive 中繼存放區。若要這樣做，請在現有 Amazon EMR 叢集的主節點上執行 thrift 伺服器。如果您已經有執行 thrift 伺服器的 Amazon EMR 叢集，並且想要使用 EMR Serverless 任務組態，則此選項是理想的選擇。

在 `hive-site`分類中設定下列組態，讓 EMR Serverless 可以存取遠端漂移中繼存放區。請注意，您必須將 `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:thirft-server-port"
    }
}
```

# 在 EMR Serverless 上使用 AWS Glue 多目錄階層
<a name="external-metastore-glue-multi"></a>

您可以設定 EMR Serverless 應用程式以使用 AWS Glue 多目錄階層。下列範例示範如何搭配 AWS Glue 多目錄階層使用 EMR-S Spark。

若要進一步了解多目錄階層，請參閱[使用 Glue Data Catalog with Spark on AWS Amazon EMR 中的多目錄階層](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-multi-catalog.html)。

## 搭配 Iceberg 和 Glue Data Catalog 使用 Redshift 受管儲存 AWS (RMS)
<a name="emr-serverless-lf-enable-spark-session-glue"></a>

以下示範如何設定 Spark 以與 Iceberg AWS 的 Glue Data Catalog 整合：

```
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/myscript.py",
            "sparkSubmitParameters": "--conf spark.sql.catalog.nfgac_rms = org.apache.iceberg.spark.SparkCatalog
             --conf spark.sql.catalog.rms.type=glue 
             --conf spark.sql.catalog.rms.glue.id=Glue RMS catalog ID 
             --conf spark.sql.defaultCatalog=rms
             --conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions"
        }
    }'
```

整合後，來自 目錄中資料表的範例查詢：

```
SELECT * FROM my_rms_schema.my_table
```

## 搭配 Iceberg REST API 和 Glue Data Catalog AWS 使用 Redshift 受管儲存 (RMS)
<a name="emr-serverless-lf-enable-spark-session-rest"></a>

以下示範如何設定 Spark 以使用 Iceberg REST 目錄：

```
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/myscript.py",
    "sparkSubmitParameters": "
    --conf spark.sql.catalog.rms=org.apache.iceberg.spark.SparkCatalog
    --conf spark.sql.catalog.rms.type=rest
    --conf spark.sql.catalog.rms.warehouse=Glue RMS catalog ID
    --conf spark.sql.catalog.rms.uri=Glue endpoint URI/iceberg
    --conf spark.sql.catalog.rms.rest.sigv4-enabled=true
    --conf spark.sql.catalog.rms.rest.signing-name=glue
    --conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions"
    }
  }'
```

目錄中資料表的範例查詢：

```
SELECT * FROM my_rms_schema.my_table
```

# 使用外部中繼存放區時的考量事項
<a name="external-metastore-considerations"></a>
+ 您可以設定與 MariaDB JDBC 相容的資料庫做為中繼存放區。這些資料庫的範例包括 RDS for MariaDB、MySQL 和 Amazon Aurora。
+ 中繼存放區不會自動初始化。如果您的中繼存放區未使用 Hive 版本的結構描述初始化，請使用 [Hive 結構描述工具](https://cwiki.apache.org/confluence/display/Hive/Hive+Schema+Tool)。
+ EMR Serverless 不支援 Kerberos 身分驗證。您無法將 thrift 中繼存放區伺服器與 Kerberos 身分驗證搭配 EMR Serverless Spark 或 Hive 任務使用。
+ 您必須設定 VPC 存取以使用多目錄階層。