

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

# Apache Spark
<a name="emr-spark"></a>

[Apache Spark](https://aws.amazon.com/emr/features/spark/) 是一種分散式處理架構和程式設計模型，可協助您使用 Amazon EMR 叢集執行機器學習、串流處理或圖形分析。與 Apache Hadoop 類似，Spark 是一種開放原始碼、分散式處理系統，通常用於大數據的工作負載。不過，Spark 與 Hadoop MapReduce 擁有許多顯著的差異。Spark 有一個最佳化有向無環圖 (DAG) 執行引擎，並主動快取記憶體內的資料，可以提高效能 (尤其是針對某些演算法和互動式查詢)。

Spark 原本就支援 Scala、Python 和 Java 編寫的應用程式。它還包含數個緊密整合的 SQL ([Spark](https://spark.apache.org/sql/))、機器學習 ([MLlib](https://spark.apache.org/mllib/))、串流處理 ([Spark 串流](https://spark.apache.org/streaming/)) 和圖形處理 ([GraphX](https://spark.apache.org/graphx/)) 程式庫。這些工具可讓您更輕鬆地將 Spark 架構用於各式各樣的使用案例。

您可以在 Amazon EMR 叢集上安裝 Spark 以及其他 Hadoop 應用程式，也可以利用 Amazon EMR 檔案系統 (EMRFS) 直接存取 Amazon S3 中的資料。Hive 也與 Spark 整合，因此您可以使用 HiveContext 物件來使用 Spark 執行 Hive 指令碼。Hive 內容包含在 spark-shell 做為 `sqlContext`。

如需使用 Spark 設定 EMR 叢集和分析範例資料集的範例教學課程，請參閱 AWS 新聞部落格上的[教學課程：Amazon EMR 入門](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-gs.html)。

您可以使用 Apache Spark 故障診斷代理程式，對 EC2 上的 EMR 和 EMR Serverless 上的 Apache Spark 應用程式進行故障診斷。若要進一步了解，請參閱 [什麼是適用於 Amazon EMR 的 Apache Spark 故障診斷代理程式](spark-troubleshoot.md)。

**重要**  
自 Amazon EMR 5.16.0 版開始提供 Apache Spark 版本 2.3.1，以因應 [CVE-2018-8024](https://nvd.nist.gov/vuln/detail/CVE-2018-8024) 和 [CVE-2018-1334](https://nvd.nist.gov/vuln/detail/CVE-2018-1334)。建議您將舊版 Spark 遷移至 Spark 版本 2.3.1 或更高版本。

以下表格列出了 Amazon EMR 7.x 系列最新版本中包含的 Spark 版本，以及 Amazon EMR 隨 Spark 一起安裝的元件。

如需此版本中與 Spark 一起安裝的元件版本，請參閱[發行版本 7.12.0 元件版本。](emr-7120-release.md)


**emr-7.12.0 的 Spark 版本資訊**  

| Amazon EMR 發行標籤 | Spark 版本 | 與 Spark 一起搭配安裝的元件 | 
| --- | --- | --- | 
| emr-7.12.0 | Spark 3.5.6-amzn-1 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-hdfs-zkfc, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 

下表列出 Amazon EMR 6.x 系列最新版本中包含的 Spark 版本，以及 Amazon EMR 隨 Spark 一起安裝的元件。

如需此版本中與 Spark 一起搭配安裝的元件版本，請參閱[發行版本 6.15.0 元件版本](emr-6150-release.md)。


**emr-6.15.0 的 Spark 版本資訊**  

| Amazon EMR 發行標籤 | Spark 版本 | 與 Spark 一起搭配安裝的元件 | 
| --- | --- | --- | 
| emr-6.15.0 | Spark 3.4.1-amzn-2 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 

**注意**  
Amazon EMR 6.8.0 版隨附 Apache Spark 3.3.0。此 Spark 版本使用 Apache Log4j 2 和 `log4j2.properties` 檔案，以設定 Spark 程序中的 Log4j。如果您在叢集中使用 Spark，或使用自訂組態參數建立 EMR 叢集，並且想要升級至 Amazon EMR 6.8.0 版，則必須為 Apache Log4j 2 遷移至新的 `spark-log4j2` 組態分類和金鑰格式。如需詳細資訊，請參閱[從 Apache Log4j 1.x 遷移至 Log4j 2.x](emr-spark-configure.md#spark-migrate-logj42)。

下表列出 Amazon EMR 5.x 系列最新版本中包含的 Spark 版本，以及 Amazon EMR 隨 Spark 一起安裝的元件。

如需此版本中與 Spark 一起安裝的元件版本，請參閱[發行版本 5.36.2 元件版本。](emr-5362-release.md)


**emr-5.36.2 的 Spark 版本資訊**  

| Amazon EMR 發行標籤 | Spark 版本 | 與 Spark 一起搭配安裝的元件 | 
| --- | --- | --- | 
| emr-5.36.2 | Spark 2.4.8-amzn-2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 

**Topics**
+ [使用 Apache Spark 建立叢集](emr-spark-launch.md)
+ [在 Amazon EMR 6.x 上使用 Docker 執行 Spark 應用程式](emr-spark-docker.md)
+ [在 AWS Amazon EMR 上使用 Glue Data Catalog Catalog 搭配 Spark](emr-spark-glue.md)
+ [在 Glue Data Catalog AWS 中使用 Amazon EMR 上的 Spark 的多目錄階層](emr-multi-catalog.md)
+ [設定 Spark](emr-spark-configure.md)
+ [什麼是適用於 Amazon EMR 的 Apache Spark 故障診斷代理程式](spark-troubleshoot.md)
+ [優化 Spark 效能](emr-spark-performance.md)
+ [Spark 結果片段快取](emr-spark-fragment-result-caching.md)
+ [使用適用於 Apache Spark 的 Nvidia RAPIDS Accelerator](emr-spark-rapids.md)
+ [存取 Spark Shell](emr-spark-shell.md)
+ [使用適用於機器學習的 Amazon SageMaker Spark](emr-spark-sagemaker.md)
+ [撰寫 Spark 應用程式](emr-spark-application.md)
+ [使用 Amazon S3 提升 Spark 效能](emr-spark-s3-performance.md)
+ [新增 Spark 步驟](emr-spark-submit-step.md)
+ [檢視 Spark 應用程式歷史記錄](emr-spark-application-history.md)
+ [存取 Spark Web UI](emr-spark-webui.md)
+ [使用 Spark 結構化串流 Amazon Kinesis Data Streams 連接器](emr-spark-structured-streaming-kinesis.md)
+ [使用 Amazon EMR 整合 Amazon Redshift 與 Apache Spark](emr-spark-redshift.md)
+ [Spark 版本歷史記錄](Spark-release-history.md)
+ [搭配 Amazon EMR 使用具體化視觀表](emr-spark-materialized-views.md)

# 使用 Apache Spark 建立叢集
<a name="emr-spark-launch"></a>

下列程序會在 Amazon EMR 主控台中使用透過**快速選項**安裝的 [Spark](https://aws.amazon.com/big-data/what-is-spark/) 來建立叢集。

您也可以使用**進階選項**進一步自訂叢集設定，或提交步驟來以程式設計方式安裝應用程式，然後執行自訂應用程式。使用任一叢集建立選項，您可以選擇將 AWS Glue 用作您的 Spark SQL 中繼存放區。如需詳細資訊，請參閱[在 AWS Amazon EMR 上使用 Glue Data Catalog Catalog 搭配 Spark](emr-spark-glue.md)。

**使用安裝的 Spark 啟動叢集**

1. 在 https：//[https://console.aws.amazon.com/emr](https://console.aws.amazon.com/emr/) 開啟 Amazon EMR 主控台。

1. 選擇**建立叢集**，以使用**快速建立**。

1. 輸入**叢集名稱**。您的叢集名稱不能包含字元 <、＞、\$1、\$1 或 ` (backtick)。

1.  對於**軟體組態**，請選擇**版本**選項。

1.  對於**應用程式**，請選擇 **Spark** 應用程式套件。

1.  依需要選取其他選項，然後選擇 **Create cluster (建立叢集)**。
**注意**  
若要在建立叢集時設定 Spark，請參閱 [設定 Spark](emr-spark-configure.md)。

**使用 啟動已安裝 Spark 的叢集 AWS CLI**
+ 使用下列命令建立一個叢集。

  ```
  aws emr create-cluster --name "Spark cluster" --release-label emr-7.12.0 --applications Name=Spark \
  --ec2-attributes KeyName=myKey --instance-type m5.xlarge --instance-count 3 --use-default-roles
  ```

**注意**  
包含 Linux 行接續字元 (\$1) 是為了提高可讀性。它們可以在 Linux 命令中移除或使用。對於 Windows，請將其移除或取代為插入符號 (^)。

**若要使用適用於 Java 的 SDK 啟動已安裝 Spark 的叢集**

指定 Spark 做為與在 `SupportedProductConfig` 中使用之 `RunJobFlowRequest` 搭配使用的應用程式。
+ 以下範例說明如何使用 Java 透過 Spark 建立叢集。

  ```
  import com.amazonaws.AmazonClientException;
  import com.amazonaws.auth.AWSCredentials;
  import com.amazonaws.auth.AWSStaticCredentialsProvider;
  import com.amazonaws.auth.profile.ProfileCredentialsProvider;
  import com.amazonaws.services.elasticmapreduce.AmazonElasticMapReduce;
  import com.amazonaws.services.elasticmapreduce.AmazonElasticMapReduceClientBuilder;
  import com.amazonaws.services.elasticmapreduce.model.*;
  import com.amazonaws.services.elasticmapreduce.util.StepFactory;
  
  public class Main {
  
          public static void main(String[] args) {
                  AWSCredentials credentials_profile = null;
                  try {
                          credentials_profile = new ProfileCredentialsProvider("default").getCredentials();
                  } catch (Exception e) {
                          throw new AmazonClientException(
                                          "Cannot load credentials from .aws/credentials file. " +
                                                          "Make sure that the credentials file exists and the profile name is specified within it.",
                                          e);
                  }
  
                  AmazonElasticMapReduce emr = AmazonElasticMapReduceClientBuilder.standard()
                                  .withCredentials(new AWSStaticCredentialsProvider(credentials_profile))
                                  .withRegion(Regions.US_WEST_1)
                                  .build();
  
                  // create a step to enable debugging in the AWS Management Console
                  StepFactory stepFactory = new StepFactory();
                  StepConfig enabledebugging = new StepConfig()
                                  .withName("Enable debugging")
                                  .withActionOnFailure("TERMINATE_JOB_FLOW")
                                  .withHadoopJarStep(stepFactory.newEnableDebuggingStep());
  
                  Application spark = new Application().withName("Spark");
  
                  RunJobFlowRequest request = new RunJobFlowRequest()
                                  .withName("Spark Cluster")
                                  .withReleaseLabel("emr-5.20.0")
                                  .withSteps(enabledebugging)
                                  .withApplications(spark)
                                  .withLogUri("s3://path/to/my/logs/")
                                  .withServiceRole("EMR_DefaultRole")
                                  .withJobFlowRole("EMR_EC2_DefaultRole")
                                  .withInstances(new JobFlowInstancesConfig()
                                                  .withEc2SubnetId("subnet-12ab3c45")
                                                  .withEc2KeyName("myEc2Key")
                                                  .withInstanceCount(3)
                                                  .withKeepJobFlowAliveWhenNoSteps(true)
                                                  .withMasterInstanceType("m4.large")
                                                  .withSlaveInstanceType("m4.large"));
                  RunJobFlowResult result = emr.runJobFlow(request);
                  System.out.println("The cluster ID is " + result.toString());
          }
  }
  ```

# 在 Amazon EMR 6.x 上使用 Docker 執行 Spark 應用程式
<a name="emr-spark-docker"></a>

**注意**  
所述的程序僅適用於 Amazon EMR 6.x 版。

透過 Amazon EMR 6.0.0，Spark 應用程式可以使用 Docker 容器來定義它們的程式庫相依性，而不用在叢集中的個別 Amazon EC2 執行個體上安裝相依項。要執行 Spark 與 Docker，您必須先設定 Docker 登錄檔並在提交 Spark 應用程式時定義其他參數。如需詳細資訊，請參閱[設定 Docker 整合](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-docker.html)。

在提交應用程式時，YARN 會叫用 Docker 以提取指定的 Docker 影像，並執行一個 Docker 容器內的 Spark 應用程式。這可讓您輕鬆定義並隔離依存項目。它可以使用作業執行所需的程式庫來減少引導或準備 Amazon EMR 叢集中執行個體的時間。

## 使用 Docker 執行 Spark 時的考量事項
<a name="emr-spark-docker-considerations"></a>

使用 Docker 執行 Spark 時，請確保符合以下先決條件：
+ `docker` 套件和 CLI 只安裝在核心和任務節點上。
+ 在 Amazon EMR 6.1.0 及更高版本上，您也可以使用下列命令在主節點上安裝 Docker。
  + 

    ```
    sudo yum install -y docker
    sudo systemctl start docker
    ```
+ `spark-submit` 命令應始終從 Amazon EMR 叢集的主執行個體上執行。
+ 用於解析 Docker 影像的 Docker 登錄檔必須使用具有 `container-executor` 分類索引鍵的分類 API 來定義，以便在啟動叢集時定義其他參數：
  + `docker.trusted.registries`
  + `docker.privileged-containers.registries`
+ 若要在 Docker 容器中執行 Spark 應用程式，以下為必要設定選項：
  + `YARN_CONTAINER_RUNTIME_TYPE=docker`
  + `YARN_CONTAINER_RUNTIME_DOCKER_IMAGE={DOCKER_IMAGE_NAME}`
+ 使用 Amazon ECR 擷取 Docker 映像檔時，您必須設定叢集以讓其自行驗證。若要執行此操作，您必須使用下列組態選項：
  + YARN\$1CONTAINER\$1RUNTIME\$1DOCKER\$1CLIENT\$1CONFIG=\$1DOCKER\$1CLIENT\$1CONFIG\$1PATH\$1ON\$1HDFS\$1
+ 在 Amazon EMR 6.1.0 及更高版本中，您不需要在啟用 ECR 自動身分驗證功能時使用列出的命令 `YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG={DOCKER_CLIENT_CONFIG_PATH_ON_HDFS}`。
+ 任何與 Spark 一起使用的 Docker 影像，都必須在該 Docker 影像中安裝 Java。

如需有關先決條件的詳細資訊，請參閱[設定 Docker 整合](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-docker.html)。

## 建立 Docker 映像檔
<a name="emr-spark-docker-image"></a>

Docker 影像是使用 Dockerfile 建立的，該檔案會定義要包含在映像中的套件和組態。以下兩個範例 Dockerfile 使用 PySpark 和 SparkR。

**PySpark Dockerfile**

從此 Dockerfile 建立的 Docker 影像包括 Python 3 和 NumPy Python 套件。該 Dockerfile 使用 Amazon Linux 2 和 Amazon Corretto JDK 8。

```
FROM amazoncorretto:8

RUN yum -y update
RUN yum -y install yum-utils
RUN yum -y groupinstall development

RUN yum list python3*
RUN yum -y install python3 python3-dev python3-pip python3-virtualenv

RUN python -V
RUN python3 -V

ENV PYSPARK_DRIVER_PYTHON python3
ENV PYSPARK_PYTHON python3

RUN pip3 install --upgrade pip
RUN pip3 install numpy pandas

RUN python3 -c "import numpy as np"
```

**SparkR Dockerfile**

從此 Dockerfile 建立的 Docker 影像包括 R 和 randomForest CRAN 套件。這個 Dockerfile 包括 Amazon Linux 2 和 Amazon Corretto JDK 8。

```
FROM amazoncorretto:8

RUN java -version

RUN yum -y update
RUN amazon-linux-extras install R4

RUN yum -y install curl hostname

#setup R configs
RUN echo "r <- getOption('repos'); r['CRAN'] <- 'http://cran.us.r-project.org'; options(repos = r);" > ~/.Rprofile

RUN Rscript -e "install.packages('randomForest')"
```

如需有關 Dockerfile 語法的更多資訊，請參閱 [Dockerfile 參考文件](https://docs.docker.com/engine/reference/builder/)。

## 使用 Amazon ECR 的 Docker 映像檔
<a name="emr-spark-docker-ECR"></a>

Amazon Elastic Container Registry (Amazon ECR) 是一種完全受管的 Docker 容器登錄檔，可讓您輕鬆存放、管理和部署 Docker 容器映像。使用 Amazon ECR 時，叢集必須設定為信任您的 ECR 執行個體，而且您必須設定身分驗證，才能讓叢集使用來自 Amazon ECR 的 Docker 映像檔。如需詳細資訊，請參閱[設定 YARN 以存取 Amazon ECR](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-docker.html#emr-docker-ECR)。

若要確保 Amazon EMR 主機可以存取 Amazon ECR 中存放的映像，叢集擁有的許可必須來自與執行個體設定檔相關聯的 `AmazonEC2ContainerRegistryReadOnly` 政策。如需詳細資訊，請參閱 [`AmazonEC2ContainerRegistryReadOnly` 政策](https://docs.aws.amazon.com/AmazonECR/latest/userguide/ecr_managed_policies.html#AmazonEC2ContainerRegistryReadOnly)。

在此範例中，叢集必須使用下列其他組態來建立，以確保 Amazon ECR 登錄檔受到信任。使用您的 Amazon ECR 端點取代 *123456789123.dkr.ecr.us-east-1.amazonaws.com* 端點。

```
[
  {
    "Classification": "container-executor",
    "Configurations": [
      {
        "Classification": "docker",
        "Properties": {
          "docker.privileged-containers.registries": "local,centos,123456789123.dkr.ecr.us-east-1.amazonaws.com",
          "docker.trusted.registries": "local,centos,123456789123.dkr.ecr.us-east-1.amazonaws.com"
        }
      }
    ],
    "Properties": {}
  }
]
```

**搭配使用 PySpark 和 Amazon ECR**

以下範例使用 PySpark Dockerfile，並將被標記並上傳到 Amazon EC。上傳 Dockerfile 後，您可以執行 PySpark 作業並從 Amazon ECR 中參閱 Docker 映像檔。

啟動叢集後，使用 SSH 連接到核心節點，並執行以下命令以從 PySpark Dockerfile 範例建構本機 Docker 影像。

首先，建立一個目錄和一個 Dockerfile。

```
mkdir pyspark
vi pyspark/Dockerfile
```

貼上 PySpark Dockerfile 的內容，並執行以下命令來建構一個 Docker 影像。

```
sudo docker build -t local/pyspark-example pyspark/
```

為範例建立 `emr-docker-examples` ECR 儲存庫。

```
aws ecr create-repository --repository-name emr-docker-examples
```

標記在本機建構的映像並上傳至 ECR，並以您的 ECR 端點取代 *123456789123.dkr.ecr.us-east-1.amazonaws.com*。

```
sudo docker tag local/pyspark-example 123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example
sudo docker push 123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example
```

使用 SSH 連線到主節點，並準備具有 `main.py` 檔名的 Python 指令碼。將下列內容貼入 `main.py` 檔案並儲存。

```
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName("docker-numpy").getOrCreate()
sc = spark.sparkContext

import numpy as np
a = np.arange(15).reshape(3, 5)
print(a)
```

在 Amazon EMR 6.0.0 中，若要提交作業，請參考 Docker 映像檔的名稱。定義其他組態參數，以確定任務執行使用 Docker 做為執行時間。使用 Amazon ECR 時，`YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG` 必須參考 `config.json` 檔案，該檔案包含用於向 Amazon ECR 進行驗證的登入資料。

```
DOCKER_IMAGE_NAME=123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example
DOCKER_CLIENT_CONFIG=hdfs:///user/hadoop/config.json
spark-submit --master yarn \
--deploy-mode cluster \
--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \
--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \
--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG=$DOCKER_CLIENT_CONFIG \
--conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \
--conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \
--conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG=$DOCKER_CLIENT_CONFIG \
--num-executors 2 \
main.py -v
```

在 Amazon EMR 6.1.0 及更高版本中，若要提交作業，請參考 Docker 映像檔的名稱。啟用 ECR 自動身分驗證時，請執行以下命令。

```
DOCKER_IMAGE_NAME=123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example
spark-submit --master yarn \
--deploy-mode cluster \
--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \
--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \
--conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \
--conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \
--num-executors 2 \
main.py -v
```

當任務完成時，請記下 YARN 應用程式 ID，並使用下列命令來取得 PySpark 任務的輸出。

```
yarn logs --applicationId application_id | grep -C2 '\[\['
LogLength:55
LogContents:
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]
```

**搭配使用 SparkR 和 Amazon ECR**

下面的範例使用將被標記並上傳到 ECR 的 SparkR Dockerfile。一旦 Dockerfile 上傳後，您便可以執行 SparkR 作業並從 Amazon ECR 中參考 Docker 映像檔。

啟動叢集後，使用 SSH 連接到核心節點，並執行以下命令以從 SparkR Dockerfile 範例建構本機 Docker 影像。

首先，建立一個目錄和 Dockerfile。

```
mkdir sparkr
vi sparkr/Dockerfile
```

貼上 SparkR Dockerfile 的內容，並執行以下命令來建構一個 Docker 影像。

```
sudo docker build -t local/sparkr-example sparkr/
```

標記在本機建構的映像並上傳至 Amazon ECR，並使用您的 Amazon ECR 端點取代 *123456789123.dkr.ecr.us-east-1.amazonaws.com*。

```
sudo docker tag local/sparkr-example 123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:sparkr-example
sudo docker push 123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:sparkr-example
```

使用 SSH 連接到主節點，並準備具有 `sparkR.R` 名稱的 R 指令碼。將以下內容貼到 `sparkR.R` 檔案。

```
library(SparkR)
sparkR.session(appName = "R with Spark example", sparkConfig = list(spark.some.config.option = "some-value"))

sqlContext <- sparkRSQL.init(spark.sparkContext)
library(randomForest)
# check release notes of randomForest
rfNews()

sparkR.session.stop()
```

在 Amazon EMR 6.0.0 中，若要提交作業，請參考 Docker 映像檔的名稱。定義其他組態參數，以確定任務執行使用 Docker 做為執行時間。使用 Amazon ECR 時，`YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG` 必須參考 `config.json` 檔案，該檔案包含用於向 ECR 進行驗證的登入資料。

```
DOCKER_IMAGE_NAME=123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:sparkr-example
DOCKER_CLIENT_CONFIG=hdfs:///user/hadoop/config.json
spark-submit --master yarn \
--deploy-mode cluster \
--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \
--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \
--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG=$DOCKER_CLIENT_CONFIG \
--conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \
--conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \
--conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG=$DOCKER_CLIENT_CONFIG \
sparkR.R
```

在 Amazon EMR 6.1.0 及更高版本中，若要提交作業，請參考 Docker 映像檔的名稱。啟用 ECR 自動身分驗證時，請執行以下命令。

```
DOCKER_IMAGE_NAME=123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:sparkr-example
spark-submit --master yarn \
--deploy-mode cluster \
--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \
--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \
--conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \
--conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \
sparkR.R
```

當任務完成後，請記下 YARN 應用程式 ID，並使用下面的命令來取得 SparkR 任務的輸出。此範例包含測試，以確定 randomForest 程式庫、安裝的版本和版本備註都可以使用。

```
yarn logs --applicationId application_id | grep -B4 -A10 "Type rfNews"
randomForest 4.6-14
Type rfNews() to see new features/changes/bug fixes.
Wishlist (formerly TODO):

* Implement the new scheme of handling classwt in classification.

* Use more compact storage of proximity matrix.

* Allow case weights by using the weights in sampling?

========================================================================
Changes in 4.6-14:
```

# 在 AWS Amazon EMR 上使用 Glue Data Catalog Catalog 搭配 Spark
<a name="emr-spark-glue"></a>

使用 Amazon EMR 5.8.0 版或更新版本，您可以將 Spark 設定為使用 AWS Glue Data Catalog 作為其 Apache Hive 中繼存放區。當您需要由不同叢集、服務、應用程式或 AWS 帳戶共用的持久性 Hive 中繼存放區或 Hive 中繼存放區時，我們建議您使用此組態。

使用 Amazon EMR 6.5.0 版或更新版本，您可以將 Spark 設定為搭配 Apache Iceberg 使用 AWS Glue Data Catalog。

您可以使用 Amazon EMR 7.5.0 版或更新版本，將 Spark 設定為使用 AWS Glue Data Catalog 作為其 Iceberg REST 目錄。

AWS Glue 是一種全受管的擷取、轉換和載入 (ETL) 服務，可讓您以簡單且經濟實惠的方式分類資料、清理資料、擴充資料，並在各種資料存放區之間可靠地移動資料。 AWS Glue Data Catalog 提供跨各種資料來源和資料格式的統一中繼資料儲存庫，與 Amazon EMR 以及 Amazon RDS、Amazon Redshift、Redshift Spectrum、Athena 以及與 Apache Hive 中繼存放區相容的任何應用程式整合。 AWS Glue 爬蟲程式可以從 Amazon S3 中的來源資料自動推斷結構描述，並將相關聯的中繼資料存放在 Data Catalog 中。如需 Data Catalog 的詳細資訊，請參閱《[Glue AWS 開發人員指南》中的填入 Glue Data Catalog](https://docs.aws.amazon.com/glue/latest/dg/populate-data-catalog.html)。 *AWS *

Glue AWS 會另外收費。儲存和存取 Data Catalog 中中繼資料的每月費率、Glue ETL AWS 任務和爬蟲程式執行期每分鐘計費的每小時費率，以及每個佈建開發端點每分鐘計費的每小時費率。Data Catalog 可讓您免費儲存多達一百萬個物件。如果您存放超過一百萬個物件，之後每 100,000 個物件會向您收費 1 美元。Data Catalog 中的物件是資料表、分割區或資料庫。如需詳細資訊，請參閱 [Glue 定價](https://aws.amazon.com/glue/pricing)。

**重要**  
如果您在 2017 年 8 月 14 日之前使用 Amazon Athena 或 Amazon Redshift Spectrum 建立資料表，資料庫和資料表會存放在 Athena 受管目錄中，這與 AWS Glue Data Catalog 不同。若要整合 Amazon EMR 與這些資料表，您必須升級至 AWS Glue Data Catalog。如需詳細資訊，請參閱《*Amazon Athena 使用者指南*》中的[升級至 AWS Glue Data Catalog](https://docs.aws.amazon.com/athena/latest/ug/glue-upgrade.html)。

## 將 AWS Glue Data Catalog 指定為 Apache Hive 中繼存放區
<a name="emr-spark-glue-configure"></a>

您可以使用 AWS AWS 管理主控台 AWS CLI或 Amazon EMR API，將 Glue Data Catalog 指定為中繼存放區。當使用 CLI 或 API 時，您要使用 Spark 的組態分類來指定 Data Catalog。此外，使用 Amazon EMR 5.16.0 及更新版本時，您可以使用組態分類在不同的 中指定資料目錄 AWS 帳戶。在使用主控台時，您可以透過**進階選項**或**快速選項**指定 Data Catalog。

**注意**  
Zeppelin 也提供使用 AWS Glue Data Catalog 的選項，因為 Zeppelin 與 Spark 元件一起安裝。

------
#### [ Console ]

**使用新主控台將 AWS Glue Data Catalog 指定為 Apache Hive 中繼存放區**

1. 登入 AWS 管理主控台，並在 https：//[https://console.aws.amazon.com/emr](https://console.aws.amazon.com/emr) 開啟 Amazon EMR 主控台。

1. 在左側導覽窗格中的 **EC2 上的 Amazon EMR** 下，選擇**叢集**，然後選擇**建立叢集**。

1. 在**應用程式套件**下方，選擇 **Spark** 或**自訂**。如果您自訂叢集，確保選取 Zeppelin 或 Spark 作為您的其中一個應用程式。

1. 在 **AWS Glue Data Catalog 設定**下方，選取**用於 Spark 資料表中繼資料**核取方塊。

1. 選擇適用於您的叢集的任何其他選項。

1. 若要啟動您的叢集，請選擇**建立叢集**。

------
#### [ AWS CLI ]

**使用 將 AWS Glue Data Catalog 指定為 Apache Hive 中繼存放區 AWS CLI**

如需使用 AWS CLI 和 Amazon EMR API 指定組態分類的詳細資訊，請參閱 [設定應用程式](emr-configure-apps.md)。
+ 使用以下範例中顯示的 `spark-hive-site` 分類來為 `hive.metastore.client.factory.class` 指定值：

  ```
  [
    {
      "Classification": "spark-hive-site",
      "Properties": {
        "hive.metastore.client.factory.class": "com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory"
      }
    }
  ]
  ```

  若要在不同帳戶中指定 Data Catalog AWS ，請新增 `hive.metastore.glue.catalogid` 屬性，如下列範例所示。使用 Data Catalog 的 AWS 帳戶取代 `acct-id`。

  ```
  [
    {
      "Classification": "spark-hive-site",
      "Properties": {
        "hive.metastore.client.factory.class": "com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory",
        "hive.metastore.glue.catalogid": "acct-id"
      }
    }
  ]
  ```

------

## 將 AWS Glue Data Catalog 指定為 Apache Iceberg 目錄
<a name="emr-spark-glue-configure-iceberg"></a>

您可以使用 、 或 AWS Amazon EMR API， AWS 管理主控台 AWS CLI或在 Spark 工作階段執行時間組態中，將 Glue Data Catalog 指定為 Apache Iceberg 目錄實作或 Apache Iceberg REST 目錄端點。當使用 CLI 或 API 時，您要使用 Spark 的組態分類來指定 Data Catalog。如需詳細資訊，請參閱[將 AWS Glue Data Catalog 指定為 Apache Iceberg 目錄](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-spark-glue.html#emr-spark-glue-configure-iceberg)。

## IAM 許可
<a name="emr-hive-glue-permissions"></a>

叢集的 EC2 執行個體描述檔必須具有 Glue 動作的 IAM AWS 許可。此外，如果您啟用 AWS Glue Data Catalog 物件的加密，也必須允許該角色加密、解密和產生 AWS KMS key 用於加密的 。

### Glue AWS 動作的許可
<a name="emr-hive-glue-permissions-actions"></a>

如果您將預設的 EC2 執行個體設定檔用於 Amazon EMR，就不需要採取任何動作。連接到 的 `AmazonElasticMapReduceforEC2Role`受管政策`EMR_EC2_DefaultRole`允許所有必要的 AWS Glue 動作。不過，如果您指定自訂 EC2 執行個體描述檔和許可，則必須設定適當的 AWS Glue 動作。使用 `AmazonElasticMapReduceforEC2Role` 受管政策做為起點。如需詳細資訊，請參閱《Amazon EMR 管理指南》**中的[叢集 EC2 執行個體的服務角色 (EC2 執行個體設定檔)](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-iam-role-for-ec2.html)。

### 加密和解密 Glue Data Catalog AWS 的許可
<a name="emr-hive-glue-permissions-encrypt"></a>

您的執行個體設定檔需要許可，以便使用您的金鑰來加密和解密資料。如若下列兩個陳述式均適用，則您*不*需要設定這些許可：
+ 您可以使用 Glue AWS 的受管金鑰啟用 AWS Glue Data Catalog 物件的加密。
+ 您可以使用與 Glue Data Catalog AWS AWS 帳戶 位於相同 中的叢集。

否則，您必須新增以下陳述式至附接至您的 EC2 執行個體設定檔的許可政策。

如需 AWS Glue Data Catalog 加密的詳細資訊，請參閱《*AWS Glue 開發人員指南*》中的[加密您的資料目錄](https://docs.aws.amazon.com/glue/latest/dg/encrypt-glue-data-catalog.html)。

### 資源型許可
<a name="emr-hive-glue-permissions-resource"></a>

如果您在 AWS Amazon EMR 中使用 Glue 搭配 Hive、Spark 或 Presto， AWS Glue 支援以資源為基礎的政策來控制對 Data Catalog 資源的存取。這些資源包含資料庫、資料表、連線和使用者定義的函數。如需詳細資訊，請參閱《AWS Glue 開發人員指南》**中的 [AWS Glue 資源政策](https://docs.aws.amazon.com/glue/latest/dg/glue-resource-policies.html)。

使用資源型政策限制從 AWS Amazon EMR 內存取 Glue 時，您在許可政策中指定的委託人必須是與建立叢集時指定的 EC2 執行個體描述檔相關聯的角色 ARN。例如，對於附接至型錄的資源型政策，您可以使用下列範例所示的格式，將叢集 EC2 執行個體的預設服務角色的角色 ARN (*EMR\$1EC2\$1DefaultRole*) 指定為 `Principal`：

```
arn:aws:iam::acct-id:role/EMR_EC2_DefaultRole
```

*acct-id* 可以與 Glue AWS 帳戶 ID 不同。這可讓您從不同帳戶中的 EMR 叢集進行存取。您可以指定多個主體，每個主體都來自不同的帳戶。

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

使用 AWS Glue Data Catalog 做為具有 Spark 的 Apache Hive 中繼存放區時，請考慮下列項目：
+ 擁有預設資料庫，無需在建立表格時會導致的位置 URI。為了解決此問題，當您使用 `LOCATION` 時，請使用 `s3://amzn-s3-demo-bucket1` 條款來指定儲存貯體的位置 (例如 `CREATE TABLE`)。或者建立預設資料庫以外之資料庫內的表格。
+ 不支援從 Glue AWS 中重新命名資料表。
+ 當您建立 Hive 資料表而未指定 `LOCATION` 時，資料表資料將儲存在 `hive.metastore.warehouse.dir` 屬性指定的位置。依預設，該位置在 HDFS 中。如果另一個叢集需要存取該資料表，除非它對建立資料表的叢集具有足夠的許可，否則存取將會失敗。此外，由於 HDFS 儲存是暫時性的，若叢集終止，資料表資料將會丟失，還必須重新建立資料表。當您使用 Glue 建立 Hive 資料表時，建議您在 Amazon S3 AWS `LOCATION`中指定 。或者，您可以使用 `hive-site` 組態分類在 Amazon S3 中指定 `hive.metastore.warehouse.dir` 的位置，該位置將套用到全部 Hive 資料表。如果在 HDFS 位置建立資料表，且建立資料表的叢集仍在執行中，您可以從 Glue 內將資料表位置更新為 AWS Amazon S3。如需詳細資訊，請參閱《[Glue AWS 開發人員指南》中的在 Glue 主控台上使用資料表](https://docs.aws.amazon.com/glue/latest/dg/console-tables.html)。 *AWS *
+ 不支援包含引號和撇號的分割區值，例如，`PARTITION (owner="Doe's").`
+ emr-5.31.0 及更高版本不支援[資料欄統計資料](https://cwiki.apache.org/confluence/display/Hive/StatsDev#StatsDev-ColumnStatistics)。
+ 不支援使用 [Hive 授權](https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Authorization)。或者，您可以考慮使用 [AWS Glue 資源型政策](https://docs.aws.amazon.com/glue/latest/dg/glue-resource-policies.html)。如需詳細資訊，請參閱[使用資源型政策來存取 AWS Glue Data Catalog](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-iam-roles-glue.html)。

搭配 Spark 使用 AWS Glue Data Catalog 做為 Apache Iceberg REST Catalog 時，請考慮下列事項：
+ 如果您將 Spark 工作階段目錄與 Iceberg 搭配使用，如中所述[使用 Iceberg SparkCatalog 與 SparkSessionCatalog 時的組態差異](emr-iceberg-use-spark-cluster.md#emr-iceberg-spark-catalog)，除了將 AWS Glue Data Catalog 設定為 Apache Iceberg REST 目錄之外，您還必須將 AWS Glue Data Catalog 設定為 Apache Hive 中繼存放區。
+  AWS Glue Data Catalog IRC 端點僅支援 Amazon SigV4 身分驗證機制。不支援 OAuth。對於 OAuth 使用者，請使用 IAM Identity Center 設定存取權。請參閱將 [Lake Formation 與 IAM Identity Center 連線](https://docs.aws.amazon.com/lake-formation/latest/dg/connect-lf-identity-center.html)。
+ Glue Iceberg REST AWS 目錄不支援開放原始碼中的所有操作。

# 在 Glue Data Catalog AWS 中使用 Amazon EMR 上的 Spark 的多目錄階層
<a name="emr-multi-catalog"></a>

您可以註冊 Amazon EMR 叢集以存取 AWS Glue Data Catalog，讓資料表和其他目錄資源可供各種消費者使用。 AWS Glue Data Catalog 支援多目錄階層，可在 Amazon S3 資料湖中統一您的資料。它還提供 Hive 中繼存放區 API 和開放原始碼 Apache Iceberg REST API 來存取資料。這些功能可供 Amazon EMR 和其他 服務使用，例如 Amazon Athena 和 Amazon Redshift。

## 目錄資源的組織方式
<a name="emr-lakehouse-org"></a>

當您在 AWS Glue Data Catalog 中建立資源時，您可以從支援 Apache Iceberg REST API 或 Hive 中繼存放區的任何 SQL 引擎存取資源。 AWS Lake Formation 會管理許可。

在 AWS Glue Data Catalog 中，資料會組織在目錄、資料庫和資料表的邏輯階層中：
+ **目錄** – 包含資料存放區物件的邏輯容器，例如結構描述或資料表。
+ **存放 Redshift 受管儲存 (RMS) 資料表的目錄** – 當您管理存放 RMS 資料表的目錄時，您可以使用 Iceberg 存取這些資料表。
+ **資料庫** – 整理目錄中的資料表和檢視等資料物件。
+ **資料表和檢視** – 資料庫中的資料物件，可提供具有可理解結構描述的抽象層。它們提供層來存取基礎資料，這些資料可以是各種格式和不同位置。



## 設定資料目錄以搭配 Amazon EMR 使用
<a name="emr-lakehouse-configuration"></a>

若要開始使用，請將目錄設定為支援 Amazon EMR 工具。Glue Data Catalog AWS 提供 Hive 中繼存放區相容性和 Iceberg REST 相容 APIs。

**使用 Hive 中繼存放區設定 Amazon EMR**

 如需如何設定的詳細資訊，請參閱《[AWS Glue 使用者指南》中的 Spark 任務的 Glue Data Catalog 支援](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-glue-data-catalog-hive.html)。 AWS 本主題說明如何將 AWS Glue Data Catalog 設定為 Hive 中繼存放區，並將其做為端點使用。此外，還有 Amazon EMR 文件，說明如何在使用 AWS Glue Data Catalog 作為 Spark [的 Apache Hive 中繼存放區中，將 AWS Glue Data Catalog 指定為 Spark 中繼存放區](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-spark-glue.html)。

## 存取 Glue Data Catalog AWS 中資源的許可
<a name="emr-lakehouse-using-irc-prereqs"></a>

本節說明搭配目錄資料使用 Amazon EMR 工具的 IAM 政策需求。向 Glue Data Catalog AWS 註冊叢集之後，您需要下列許可，才能探索後續建立的資料目錄的建立和變更：
+ **glue：GetCatalog**
+ **glue：GetCatalogs**
+ **sts：AssumeRole**
+ **sts：TagSession**
+ **sts：SetContext**
+ **sts：SetSourceIdentity**

在大多數情況下，當您指派許可時，建議您建立 IAM 角色並為其指派許可。

此外，若要查詢目錄資料，您必須使用 設定資料目錄的許可 AWS Lake Formation。如需在 中設定資料目錄許可的詳細資訊 AWS Lake Formation，請參閱[授予和撤銷資料目錄資源的許可](https://docs.aws.amazon.com/lake-formation/latest/dg/granting-catalog-permissions.html)。

在您建立和設定叢集，並設定目錄物件的許可之後，您可以提交任務來查詢和處理資料。

## 設定 Spark 以存取 Glue Data Catalog AWS 中的多目錄階層
<a name="emr-lakehouse-using-spark-access"></a>

透過 EMR 7.5，您可以將 Spark 設定為使用 AWS Glue 的多目錄階層。多目錄階層可讓您：
+ 將現有 Amazon Redshift 資料倉儲中的資料表、檢視和具體化檢視等 Redshift 受管儲存 (RMS) 資料帶到 AWS Glue Data Catalog。您可以使用 EC2 上的 EMR 和 EMR Serverless 來查詢這些物件。
+ 建立 RMS 目錄、 AWS Glue Data Catalog，並使用 ZeroETL 將資料存放在 RMS 中，並使用 Iceberg 相容查詢引擎查詢資料。
+ 使用包含壓縮、快照和保留的完整功能儲存管理，在 AWS Glue Data Catalog 中建立受管 Iceberg 資料表。

### 初始化 Spark 工作階段時連線至多目錄
<a name="emr-iceberg-initialize-spark-session-spark"></a>

下列範例示範如何使用互動式 Spark shell、Spark 提交或 Amazon EMR 筆記本來使用 AWS Glue 的多目錄階層。

------
#### [ spark-shell ]

1. 使用 SSH 連接至主節點。如需詳細資訊，請參閱《Amazon EMR 管理指南》**中的[使用 SSH 連接至主節點](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-connect-master-node-ssh.html)。

1. 輸入以下命令啟動 Spark shell。若要使用 PySpark Shell，請將 `spark-shell` 取代為 `pyspark`。

   ```
   spark-shell \
       --conf spark.sql.catalog.my_catalog=org.apache.iceberg.spark.SparkCatalog \
       --conf spark.sql.catalog.my_catalog.warehouse=s3://amzn-s3-demo-bucket/prefix/
       --conf spark.sql.catalog.my_catalog.type=glue \
       --conf spark.sql.catalog.my_catalog.glue.id=Glue RMS catalog ID \
       --conf spark.sql.defaultCatalog=my_catalog \
       --conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions
   ```

------
#### [ spark-submit ]

1. 使用 SSH 連接至主節點。如需詳細資訊，請參閱《Amazon EMR 管理指南》**中的[使用 SSH 連接至主節點](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-connect-master-node-ssh.html)。

1. 輸入下列命令以啟動 Spark 的 Spark 工作階段。

   ```
   spark-submit \
   --conf spark.sql.catalog.my_catalog=org.apache.iceberg.spark.SparkCatalog \
   --conf spark.sql.catalog.my_catalog.warehouse=s3://amzn-s3-demo-bucket1/prefix \
   --conf spark.sql.catalog.my_catalog.type=glue \
   --conf spark.sql.catalog.my_catalog.glue.id=Glue RMS catalog ID \
   --conf spark.sql.defaultCatalog=my_catalog \
   --conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions
   ```

------
#### [ EMR Studio notebooks ]

若要使用 EMR Studio 筆記本初始化 Spark 工作階段，請使用 Amazon EMR Notebooks 中的 `%%configure` 魔法命令來設定 Spark 工作階段，如下列範例所示。如需詳細資訊，請參閱《Amazon EMR 管理指南》**中的[使用 EMR Notebooks 魔法](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-studio-magics.html#emr-magics)。

```
%%configure -f{
"conf":{
    "spark.sql.catalog.my_catalog":"org.apache.iceberg.spark.SparkCatalog",
    "spark.sql.catalog.my_catalog.type":"glue",
    "spark.sql.catalog.my_catalog.glue.id":"Glue RMS catalog ID",
    "spark.sql.catalog.my_catalog.warehouse":"s3://amzn-s3-demo-bucket1/prefix/",
    "spark.sql.defaultCatalog", "my_catalog",
    "spark.sql.extensions":"org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions"
    }
}
```

------
#### [ CLI ]

若要使用 CLI 初始化 Spark 工作階段，請執行下列範例。如需使用 AWS CLI 和 Amazon EMR API 指定組態分類的詳細資訊，請參閱[設定應用程式](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-configure-apps.html)。

```
[
  {
    "Classification": "spark-defaults",
    "Properties": {
      "spark.sql.catalog.my_catalog":"org.apache.iceberg.spark.SparkCatalog",
      "spark.sql.catalog.my_catalog.type":"glue",
      "spark.sql.catalog.my_catalog.glue.id":"Glue RMS catalog ID",
      "spark.sql.catalog.my_catalog.warehouse":"s3://amzn-s3-demo-bucket1/prefix/",
      "spark.sql.defaultCatalog", "my_catalog",
      "spark.sql.extensions":"org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions"
    }
  }
]
```

------

#### 使用 Glue Data Catalog 將 Spark 工作階段初始化至 Redshift AWS 受管儲存
<a name="considerations-multi-catalog-glue-connect"></a>

下列範例命令會使用 AWS Glue Data Catalog 初始化 Spark 工作階段。

```
spark-sql \
  --conf spark.sql.catalog.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
```

下列範例會使用 Iceberg REST API 和 Redshift 受管儲存搭配 Glue Data Catalog 來初始化 Spark AWS 工作階段。

```
spark-sql \
  --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.defaultCatalog=rms \
  --conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions
```

如需搭配 Spark Iceberg 使用 AWS Glue 多目錄階層的詳細資訊，請參閱[搭配 Spark 使用 Iceberg 叢集](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-iceberg-use-spark-cluster.html)。

## 多目錄組態的考量和限制
<a name="considerations-multi-catalog"></a>
+ 不支援搭配 Apache Hive 中繼存放區使用多目錄階層。
+ 使用 時，搭配 Apache Iceberg 使用多目錄階層無法支援回復至 Apache Hive 中繼存放區`SparkSessionCatalog`。
+ 具有執行期角色的 EC2 叢集上的 EMR 不支援多目錄階層。
+ 啟用 的 EC2 叢集上的 EMR AWS Lake Formation 不支援多目錄階層。

# 設定 Spark
<a name="emr-spark-configure"></a>

您可以使用組態類別來設定 [Amazon EMR 上的 Spark](https://aws.amazon.com/elasticmapreduce/details/spark/)。如需有關組態分類的詳細資訊，請參閱 [設定應用程式](emr-configure-apps.md)。

在 Amazon EMR 上適用於 Spark 的組態分類包括下列項目：
+ **`spark`** – 將 `maximizeResourceAllocation` 屬性設為 true 或 false。設為 true 時，Amazon EMR 會自動根據叢集硬體組態設定 `spark-defaults` 屬性。如需詳細資訊，請參閱[使用 `maximizeResourceAllocation`](#emr-spark-maximizeresourceallocation)。
+ **`spark-defaults`** – 設定 `spark-defaults.conf` 檔案中的值。如需詳細資訊，請參閱 Spark 文件中的 [Spark 組態](https://spark.apache.org/docs/latest/configuration.html)。
+ **`spark-env`** – 設定 `spark-env.sh` 檔案中的值。如需詳細資訊，請參閱 Spark 文件中的[環境變數](https://spark.apache.org/docs/latest/configuration.html#environment-variables)。
+ **`spark-hive-site`** – 為 Spark 設定 `hive-site.xml` 中的值。
+ **`spark-log4j`** – (Amazon EMR 6.7.x 版及更早版本) 設定 `log4j.properties` 檔案中的值。如需詳細資訊，請參閱 Github 上的 [log4j.properties.template](https://github.com/apache/spark/blob/branch-3.2/conf/log4j.properties.template) 檔案。
+ **`spark-log4j2`** – (Amazon EMR 6.8.0 版及更高版本) 設定 `log4j2.properties` 檔案中的值。如需詳細資訊，請參閱 Github 上的 [log4j2.properties.template](https://github.com/apache/spark/blob/v3.3.0/conf/log4j2.properties.template) 檔案。
+ **`spark-metrics`** – 設定 `metrics.properties` 檔案中的值。如需了解設定和詳細資訊，請參閱 Github 上的 [metrics.properties.template](https://github.com/apache/spark/blob/master/conf/metrics.properties.template) 檔案和 Spark 文件中的[指標](https://spark.apache.org/docs/latest/monitoring.html#metrics)。

**注意**  
如果您要從其他平台將 Spark 工作負載遷移到 Amazon EMR，則建議您在新增自訂組態前使用 [Amazon EMR 設定的 Spark 預設值](#spark-defaults) 測試您的工作負載。大多數客戶在使用我們的預設設定後會經歷效能提升。

**Topics**
+ [Amazon EMR 設定的 Spark 預設值](#spark-defaults)
+ [設定 Amazon EMR 6.1.0 上的 Spark 垃圾回收](#spark-gc-config)
+ [使用 `maximizeResourceAllocation`](#emr-spark-maximizeresourceallocation)
+ [設定節點除役行為](#spark-decommissioning)
+ [Spark ThriftServer 環境變數](#spark-thriftserver)
+ [變更 Spark 預設設定](#spark-change-defaults)
+ [從 Apache Log4j 1.x 遷移至 Log4j 2.x](#spark-migrate-logj42)

## Amazon EMR 設定的 Spark 預設值
<a name="spark-defaults"></a>

下表顯示了 Amazon EMR 在 `spark-defaults` 中設定預設值時將如何影響應用程式。


**Amazon EMR 設定的 Spark 預設值**  

| 設定 | Description | 預設值 | 
| --- | --- | --- | 
| spark.executor.memory | 每個執行器程序要使用的記憶體量。例如：`1g`、`2g`。 |  此設定由叢集中的核心和任務執行個體類型決定。  | 
| spark.executor.cores | 每個執行器上要使用的核心數。 | 此設定由叢集中的核心和任務執行個體類型決定。 | 
| spark.dynamicAllocation.enabled | 若為 true，請使用動態資源分配，依據工作負載的情況擴增及縮減應用程式，從而擴展註冊執行器的數量。 |  `true` (使用 Amazon EMR 4.4.0 及更高版本)  Amazon EMR 會自動設定 Spark 隨機顯示服務。   | 
| spark.sql.hive.advancedPartitionPredicatePushdown.enabled | 若為 true，將啟用進階分割區述詞下推至 Hive 中繼存放區。 | true | 
| spark.sql.hive.stringLikePartitionPredicatePushdown.enabled | 下推 `startsWith`、`contains` 和 `endsWith` 篩選條件至 Hive 中繼存放區。  Glue 不支援為 `startsWith`、`contains` 或 `endsWith` 下推述詞。如果您使用的是 Glue 中繼存放區，且因為這些函數的述詞下推而發生錯誤，請將此組態設定為 `false`。   | true | 

## 設定 Amazon EMR 6.1.0 上的 Spark 垃圾回收
<a name="spark-gc-config"></a>

使用 `spark.driver.extraJavaOptions` 和 `spark.executor.extraJavaOptions` 設定自訂的垃圾回收組態會導致 Amazon EMR 6.1 的驅動程式或執行器啟動失敗，因為垃圾回收組態與 Amazon EMR 6.1.0 發生衝突。對於 Amazon EMR 6.1.0，透過 `spark.driver.defaultJavaOptions` 和 `spark.executor.defaultJavaOptions` 設定預設的垃圾回收組態。此組態僅套用至 Amazon EMR 6.1.0。與垃圾回收不相關之 JVM 選項，例如設定記錄的選項 (`-verbose:class`)，仍可透過 `extraJavaOptions` 設定。如需詳細資訊，請參閱 [Spark 應用程式屬性](https://spark.apache.org/docs/latest/configuration.html#application-properties)。

## 使用 `maximizeResourceAllocation`
<a name="emr-spark-maximizeresourceallocation"></a>

若要設定您的執行器，以便在叢集中每個節點上利用可用的最大資源，請在您的 `spark` 組態分類中將 `maximizeResourceAllocation` 設定為 `true`。`maximizeResourceAllocation` 專屬於 Amazon EMR。當您啟用 `maximizeResourceAllocation` 時，Amazon EMR 會計算在核心執行個體群組中，執行個體上執行器可用的最大運算和記憶體資源。然後，它會依據計算的最大值設定對應的 `spark-defaults` 設定。

Amazon EMR 會根據核心執行個體機群中的執行個體類型，計算執行器可用的運算和記憶體資源上限。由於每個執行個體機群在機群內都有不同的執行個體類型和大小，因此 Amazon EMR 使用的執行器組態可能不適合您的叢集，因此在使用資源配置上限時，我們不建議使用預設設定。為您的執行個體機群叢集設定自訂設定。

**注意**  
您不應該在叢集上搭配其他分散式應用程式 (例如 HBase) 來使用 `maximizeResourceAllocation` 選項。Amazon EMR 針對分散式應用程式使用自訂 YARN 組態，這可能會與 `maximizeResourceAllocation` 發生衝突並導致 Spark 應用程式失敗。

以下是 `maximizeResourceAllocation` 設定為 `true` 的 Spark 組態類別範例。

```
[
  {
    "Classification": "spark",
    "Properties": {
      "maximizeResourceAllocation": "true"
    }
  }
]
```


**當 `spark-defaults`啟用時，設定 `maximizeResourceAllocation` 中的組態設定**  

| 設定 | Description | Value | 
| --- | --- | --- | 
| spark.default.parallelism | 使用者未設定時，轉換 (如加入、reduceByKey，並平行處理) 傳回的 RDD 中的分割預設數量。 |  YARN 容器可用的 CPU 核心 2X 數。  | 
| spark.driver.memory | 用於驅動程式程序 (也就是 SparkContext) 的記憶體數量。(例如 1g，2g)。 |  設定是以叢集中的執行個體類型為基礎來設定。然而，由於 Spark 驅動程式應用程式可能會在主執行個體或其中一個核心執行個體上執行 (例如分別在 YARN 用戶端和叢集模式中執行)，此會以這兩種執行個體群組中較小型的執行個體類型為依據來設定。  | 
| spark.executor.memory | 每個執行器程序要使用的記憶體量。(例如 1g，2g) |  設定是以叢集中的核心和任務執行個體類型為基礎來設定。  | 
| spark.executor.cores | 每個執行器上要使用的核心數。 | 設定是以叢集中的核心和任務執行個體類型為基礎來設定。 | 
| spark.executor.instances |  執行器數。 |  設定是以叢集中的核心和任務執行個體類型為基礎來設定。除非 `spark.dynamicAllocation.enabled` 同時明確設定設為 true，否則請如此設定。  | 

## 設定節點除役行為
<a name="spark-decommissioning"></a>

使用 Amazon EMR 5.9.0 版及更高版本時，Amazon EMR 上的 Spark 包含一組功能，可協助確保 Spark 從容地處理由於手動調整或自動擴展政策請求而終止的節點。Amazon EMR 在 Spark 實作列入拒絕清單機制，該 Spark 是根據 YARN 的除役機制而建置。此機制有助於確保不會在停用的節點上排定任何新任務的時程，同時讓已經在執行中的任務得以完成。此外，若混洗區塊在節點終止時遺失，有功能可幫助您更快地恢復 Spark 任務。重新計算程序的觸發速度更快，且已最佳化，重新計算速度更快，階段重試數更少，同時因為遺失混洗區塊而造成的擷取故障可避免任務失敗。

**重要**  
在 Amazon EMR 5.11.0 版中已新增 `spark.decommissioning.timeout.threshold` 設定，以改善在您使用 Spot 執行個體時的 Spark 彈性。當節點在較舊的版本中使用 Spot 執行個體時，執行個體會因為出價而終止，Spark 可能無法從容地處理終止。任務可能會失敗，且混洗重新計算可能需要耗費大量時間。因此，如果您使用的是 Spot 執行個體，建議您使用 5.11.0 版或更高版本。


**Spark 節點除役設定**  

| 設定 | Description | 預設值 | 
| --- | --- | --- | 
|  `spark.blacklist.decommissioning.enabled`  |  當設定為 `true` 時，Spark 會將在 YARN 中狀態為 `decommissioning` 的節點列入拒絕清單。Spark 不會在該節點上執行的執行者上排定新任務的時程。允許讓已執行的任務得以完成。  |  `true`  | 
|  `spark.blacklist.decommissioning.timeout`  |  節點狀態為 `decommissioning` 且列入拒絕清單的時間。在預設情況下，這個值會設為 1 小時，此值同樣是 `yarn.resourcemanager.decommissioning.timeout` 的預設值。為了確保節點在整個除役期間都是列入拒絕清單的狀態，將這個值設為等於或大於 `yarn.resourcemanager.decommissioning.timeout`。停用逾時過期後，節點會轉換至 `decommissioned` 狀態，而 Amazon EMR 可終止節點的 EC2 執行個體。如果任何任務在逾時過期後仍在執行中，他們在其他節點上執行的執行器上會遺失或遭移除或重新排程。  |  `1h`  | 
|  `spark.decommissioning.timeout.threshold`  |  在 Amazon EMR 5.11.0 版或更高版本中可供使用。以秒為單位指定。節點轉換至除役狀態時，如果主機在等於或小於此值的期間內除役，Amazon EMR 不僅會將節點列入拒絕清單，還會清除主機狀態 (如 `spark.resourceManager.cleanupExpiredHost` 中所指定)，而不會等待節點轉換至除役狀態。這可讓 Spark 用有效地處理 Spot 執行個體的終止，因為 Spot 執行個體會在 20 秒逾時內停用 (不論 `yarn.resourcemager.decommissioning.timeout` 值為何)，而使得其他節點沒有足夠的時間來讀取混洗檔案。  |  `20s`  | 
|  `spark.resourceManager.cleanupExpiredHost`  |  當設定為 `true`，Spark 會取消註冊狀態為 `decommissioned` 之節點上執行器中存放的所有快取資料與混洗區塊。這可加快復原程序。  |  `true`  | 
|  `spark.stage.attempt.ignoreOnDecommissionFetchFailure`  |  設定為 `true` 有助於避免 Spark 在階段中失敗與在最終的任務失敗，因為從停用節點中擷取的失敗過多。無法從狀態為 `decommissioned` 的節點中擷取混洗區塊將不會計入連續擷取故障數上限。  | true | 

## Spark ThriftServer 環境變數
<a name="spark-thriftserver"></a>

Spark 會將 Hive Thrift 伺服器連接埠環境變數 (`HIVE_SERVER2_THRIFT_PORT`) 設為 10001。

## 變更 Spark 預設設定
<a name="spark-change-defaults"></a>

您可以在 `spark-defaults.conf` 中使用 `spark-defaults` 組態分類，或使用 `spark` 組態分類中的 `maximizeResourceAllocation` 變更預設值。

以下程序示範如何使用 CLI 或主控台修改設定。

**若要使用 CLI 建立 spark.executor.memory 設定為 2g 的叢集**
+ 使用以下命令，建立已安裝 Spark 且 `spark.executor.memory` 設為 2g 的叢集，該命令會參考存放於 Amazon S3 的檔案 `myConfig.json`。

  ```
  aws emr create-cluster --release-label emr-7.12.0 --applications Name=Spark \
  --instance-type m5.xlarge --instance-count 2 --service-role EMR_DefaultRole_V2 --ec2-attributes InstanceProfile=EMR_EC2_DefaultRole --configurations https://s3.amazonaws.com/amzn-s3-demo-bucket/myfolder/myConfig.json
  ```
**注意**  
包含 Linux 行接續字元 (\$1) 是為了提高可讀性。它們可以在 Linux 命令中移除或使用。對於 Windows，請將其移除或取代為插入符號 (^)。

  `myConfig.json`:

  ```
  [
      {
        "Classification": "spark-defaults",
        "Properties": {
          "spark.executor.memory": "2G"
        }
      }
    ]
  ```

**若要使用主控台建立 spark.executor.memory 設定為 2g 的叢集**

1. 導覽至新的 Amazon EMR 主控台，然後從側邊導覽選取**切換至舊主控台**。如需有關切換至舊主控台時預期情況的詳細資訊，請參閱[使用舊主控台](https://docs.aws.amazon.com/emr/latest/ManagementGuide/whats-new-in-console.html#console-opt-in)。

1. 選擇 **Create cluster (建立叢集)**，然後選擇 **Go to advanced options (前往進階選項)**。

1. 選擇 **Spark (Spark)**。

1. 在 **Edit software settings (編輯軟體設定)**，將 **Enter configuration (輸入組態)** 保持為選取的狀態，然後輸入以下組態：

   ```
   classification=spark-defaults,properties=[spark.executor.memory=2G]
   ```

1. 選取其他選項，選擇 ****，然後選擇 **Create cluster (建立叢集)**。

**若要設定 maximizeResourceAllocation**
+ 使用 建立已安裝 Spark 並`maximizeResourceAllocation`設為 true AWS CLI的叢集，參考`myConfig.json`存放在 Amazon S3 中的檔案 。

  ```
  aws emr create-cluster --release-label emr-7.12.0 --applications Name=Spark \
  --instance-type m5.xlarge --instance-count 2 --service-role EMR_DefaultRole_V2 --ec2-attributes InstanceProfile=EMR_EC2_DefaultRole --configurations https://s3.amazonaws.com/amzn-s3-demo-bucket/myfolder/myConfig.json
  ```
**注意**  
包含 Linux 行接續字元 (\$1) 是為了提高可讀性。它們可以在 Linux 命令中移除或使用。對於 Windows，請將其移除或取代為插入符號 (^)。

  `myConfig.json`:

  ```
  [
    {
      "Classification": "spark",
      "Properties": {
        "maximizeResourceAllocation": "true"
      }
    }
  ]
  ```

**注意**  
對於 Amazon EMR 版本 5.21.0 及更高版本，您可以覆寫叢集組態，並且為執行中叢集的每個執行個體群組，指定額外組態分類。您可以使用 Amazon EMR 主控台、 AWS Command Line Interface (AWS CLI) 或 AWS SDK 來執行此操作。如需詳細資訊，請參閱[為執行中叢集的執行個體群組提供組態](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-configure-apps-running-cluster.html)。

## 從 Apache Log4j 1.x 遷移至 Log4j 2.x
<a name="spark-migrate-logj42"></a>

[Apache Spark](https://aws.amazon.com/emr/features/spark/) 3.2.x 版及更早版本使用舊版 Apache Log4j 1.x 和 `log4j.properties` 檔案，設定 Spark 程序中的 Log4j。Apache Spark 3.3.0 版及更高版本使用 Apache Log4j 2.x 和 `log4j2.properties` 檔案，設定 Spark 程序中的 Log4j。

如果您已使用低於 6.8.0 的 Amazon EMR 版本設定 Apache Spark Log4j，則必須先移除舊版 `spark-log4j` 組態分類並遷移至 `spark-log4j2` 組態分類和金鑰格式，然後才能升級至 Amazon EMR 6.8.0 或更高版本。在 Amazon EMR 6.8.0 版及更高版本中，舊版 `spark-log4j` 分類會導致叢集建立失敗，並發生 `ValidationException` 錯誤。您不需要為與 Log4j 不相容性相關的失敗付費，但您必須移除已停用的 `spark-log4j` 組態分類才能繼續。

如需有關從 Apache Log4j 1.x 遷移至 Log4j 2.x 的詳細資訊，請參閱 Github 上的[《Apache Log4j 遷移指南》](https://logging.apache.org/log4j/2.x/manual/migration.html)和 [Spark Log4j 2 範本](https://github.com/apache/spark/blob/master/conf/log4j2.properties.template)。

**注意**  
藉由 Amazon EMR，Apache Spark 使用 `log4j2.properties` 檔案，而非《[Apache Log4j 遷移指南](https://logging.apache.org/log4j/2.x/manual/migration.html)》中所述的 .xml 檔案。此外，我們不建議使用 Log4j 1.x 橋接方法來轉換為 Log4j 2.x。

# 什麼是適用於 Amazon EMR 的 Apache Spark 故障診斷代理程式
<a name="spark-troubleshoot"></a>

## 簡介
<a name="spark-troubleshooting-agent-intro"></a>

Amazon EMR 專用 Apache Spark 故障診斷代理程式是一種對話式 AI 功能，可簡化 Amazon EMR、 AWS Glue 和 Amazon SageMaker 筆記本上 Apache Spark 應用程式的故障診斷。傳統 Spark 疑難排解需要對日誌、效能指標和錯誤模式進行廣泛的手動分析，以識別根本原因和程式碼修正。代理程式透過自然語言提示、自動化工作負載分析和智慧型程式碼建議來簡化此程序。

您可以使用代理程式對 PySpark 和 Scala 應用程式失敗進行故障診斷。代理程式會分析失敗的任務、識別效能瓶頸，並提供可行的建議和程式碼修正，同時讓您完全掌控實作決策。

**注意**  
Apache Spark 故障診斷代理程式在 Amazon EMR 中可免費使用。代理程式僅提供分析和建議。您只需為執行應用程式時用來驗證任何建議修正的 Amazon EMR 資源付費。

## 架構概觀
<a name="spark-troubleshooting-agent-architecture"></a>

故障診斷代理程式有三個主要元件：開發環境中與 MCP 相容的互動 AI 助理、處理用戶端 AWS 和服務之間安全通訊和身分驗證的 [AmazonCP Proxy AWS](https://github.com/aws/mcp-proxy-for-aws)，以及為 Amazon EMR、Glue 和 Amazon SageMaker Notebooks 提供專用 Spark 故障診斷工具的 Amazon SageMaker Unified Studio Remote MCP Server。 `(preview)` AWS Amazon SageMaker 此圖表說明如何透過 AI 助理與 Amazon SageMaker Unified Studio 遠端 MCP 伺服器互動。

![\[Spark 疑難排解代理程式架構。\]](http://docs.aws.amazon.com/zh_tw/emr/latest/ReleaseGuide/images/spark-troubleshooting-agent-architecture.png)


AI 助理將依照下列步驟，使用 MCP 伺服器提供的專用工具來協調故障診斷：
+ **特徵擷取和內容建置：**代理程式會自動從 Spark 應用程式收集和分析遙測資料，包括 Spark 歷史記錄伺服器日誌、組態設定和錯誤追蹤。它會擷取關鍵效能指標、資源使用率模式和失敗簽章，以建立全方位的內容描述檔，以進行智慧型故障診斷。
+ **GenAI 根本原因分析器和建議引擎：**代理程式利用 AI 模型和 Spark 知識庫來關聯擷取的功能，並識別效能問題或故障的根本原因。它提供 Spark 應用程式執行中發生錯誤的診斷洞察和分析。
+ **GenAI Spark 程式碼建議：**根據上一個步驟的根本原因分析，代理程式會分析您現有的程式碼模式，並識別需要修正應用程式失敗程式碼的效率低下操作。它提供可行的建議，包括特定的程式碼修改、組態調整和具有具體範例的架構改進。

**Topics**
+ [簡介](#spark-troubleshooting-agent-intro)
+ [架構概觀](#spark-troubleshooting-agent-architecture)
+ [客服人員故障診斷的設定](spark-troubleshooting-agent-setup.md)
+ [使用 故障診斷代理程式](spark-troubleshooting-using-troubleshooting-agent.md)
+ [功能和功能](spark-troubleshooting-features.md)
+ [故障診斷和問答](spark-troubleshooting-agent-troubleshooting.md)
+ [詳細資訊中的 Spark 對客服人員工作流程進行故障診斷](spark-troubleshooting-agent-workflow.md)
+ [提示範例](spark-troubleshooting-agent-prompt-examples.md)
+ [IAM 角色設定](spark-troubleshooting-agent-iam-setup.md)
+ [使用 Spark 疑難排解工具](spark-troubleshooting-agent-using-tools.md)
+ [設定 Amazon SageMaker Unified Studio MCP 的介面 VPC 端點](spark-troubleshooting-agent-vpc-endpoints.md)
+ [Apache Spark 故障診斷代理程式的跨區域處理](spark-troubleshooting-cross-region-processing.md)
+ [使用 記錄 Amazon SageMaker Unified Studio MCP 呼叫 AWS CloudTrail](spark-troubleshooting-cloudtrail-integration.md)
+ [Apache Spark 代理程式的服務改進](spark-agents-service-improvements.md)

# 客服人員故障診斷的設定
<a name="spark-troubleshooting-agent-setup"></a>

**注意**  
Apache Spark 疑難排解代理程式使用跨區域推論來處理自然語言請求並產生回應。如需詳細資訊，請參閱 [Apache Spark 故障診斷代理程式的跨區域處理](spark-troubleshooting-cross-region-processing.md)。Amazon SageMaker Unified Studio MCP 伺服器處於預覽狀態，可能會有所變更。

## 先決條件
<a name="spark-troubleshooting-agent-prerequisites"></a>

在我們開始與 Kiro CLI 整合的設定程序之前，請確定您的工作站已安裝下列項目：
+  [ 安裝 AWS CLI ](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) 
+  [ 安裝 Python 3.10\$1 ](https://www.python.org/downloads/release/python-3100/) 
+  [ 安裝適用於 的 MCP Proxy `uv`套件管理員 ](https://docs.astral.sh/uv/getting-started/installation/) [AWS](https://github.com/aws/mcp-proxy-for-aws?tab=readme-ov-file) 
+  [ 安裝 Kiro CLI ](https://kiro.dev/docs/cli/) 
+ AWS 已設定的本機登入資料 （透過 [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html)、環境變數或 IAM 角色） - 用於本機操作，例如上傳升級的任務成品以進行 EMR 驗證任務執行。

## 設定資源
<a name="spark-troubleshooting-agent-setup-resources"></a>

您可以使用 AWS CloudFormation 範本來設定 MCP 伺服器的資源。這些範本是範例，您應加以修改以符合您的需求。範本會為疑難排解程序建立下列資源：

1. IAM 角色，其具有呼叫 MCP Server 的許可，以及對所選平台進行疑難排解程序所需的許可。

選擇下表中的其中一個 **Launch Stack (啟動堆疊)** 按鈕。這會在個別區域的 AWS CloudFormation 主控台上啟動堆疊。


| 區域 | 啟動 | 
| --- | --- | 
| 美國東部 (俄亥俄) |  [https://console.aws.amazon.com/cloudformation/home?region=us-east-2#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-us-east-2.s3.us-east-2.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=us-east-2#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-us-east-2.s3.us-east-2.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| 美國東部 (維吉尼亞北部) |  [https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-us-east-1.s3.us-east-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-us-east-1.s3.us-east-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| 美國西部 (奧勒岡) |  [https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-us-west-2.s3.us-west-2.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-us-west-2.s3.us-west-2.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| 亞太地區 (東京) |  [https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ap-northeast-1.s3.ap-northeast-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ap-northeast-1.s3.ap-northeast-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| 歐洲 (愛爾蘭) |  [https://console.aws.amazon.com/cloudformation/home?region=eu-west-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-eu-west-1.s3.eu-west-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=eu-west-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-eu-west-1.s3.eu-west-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| 亞太地區 (新加坡) |  [https://console.aws.amazon.com/cloudformation/home?region=ap-southeast-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ap-southeast-1.s3.ap-southeast-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=ap-southeast-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ap-southeast-1.s3.ap-southeast-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| 亞太地區 (雪梨) |  [https://console.aws.amazon.com/cloudformation/home?region=ap-southeast-2#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ap-southeast-2.s3.ap-southeast-2.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=ap-southeast-2#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ap-southeast-2.s3.ap-southeast-2.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| 加拿大 (中部) |  [https://console.aws.amazon.com/cloudformation/home?region=ca-central-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ca-central-1.s3.ca-central-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=ca-central-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ca-central-1.s3.ca-central-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| 南美洲 (聖保羅) |  [https://console.aws.amazon.com/cloudformation/home?region=sa-east-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-sa-east-1.s3.sa-east-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=sa-east-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-sa-east-1.s3.sa-east-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| 歐洲 (法蘭克福) |  [https://console.aws.amazon.com/cloudformation/home?region=eu-central-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-eu-central-1.s3.eu-central-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=eu-central-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-eu-central-1.s3.eu-central-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| 歐洲 (斯德哥爾摩) |  [https://console.aws.amazon.com/cloudformation/home?region=eu-north-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-eu-north-1.s3.eu-north-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=eu-north-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-eu-north-1.s3.eu-north-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| 歐洲 (倫敦) |  [https://console.aws.amazon.com/cloudformation/home?region=eu-west-2#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-eu-west-2.s3.eu-west-2.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=eu-west-2#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-eu-west-2.s3.eu-west-2.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| Europe (Paris) |  [https://console.aws.amazon.com/cloudformation/home?region=eu-west-3#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-eu-west-3.s3.eu-west-3.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=eu-west-3#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-eu-west-3.s3.eu-west-3.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| 亞太地區 (首爾) |  [https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-2#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ap-northeast-2.s3.ap-northeast-2.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-2#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ap-northeast-2.s3.ap-northeast-2.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| 亞太地區 (孟買) |  [https://console.aws.amazon.com/cloudformation/home?region=ap-south-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ap-south-1.s3.ap-south-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=ap-south-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ap-south-1.s3.ap-south-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 

繼續前往**指定堆疊詳細資訊**頁面，輸入**堆疊名稱**。在 **Parameters** (參數) 下輸入其他資訊。提供以下資訊並繼續建立堆疊。
+ **TroubleshootingRoleName** - 要為故障診斷操作建立的 IAM 角色名稱
+ **EnableEMREC2** - 啟用 EMR-EC2 疑難排解許可 （預設值： true)
+ **EnableEMRServerless** - 啟用 EMR-Serverless 疑難排解許可 （預設值： true)
+ **EnableGlue** - 啟用 Glue 故障診斷許可 （預設值： true)
+ **CloudWatchKmsKeyArn** - （選用） CloudWatch Logs 加密現有 KMS 金鑰的 ARN （僅限 EMR Serverless，預設加密保留空白）

您也可以下載並檢閱 [ CloudFormation 範本](https://github.com/aws-samples/aws-emr-utilities/blob/03c20fece616de23ec0ea5389f0113a5bc65fc3a/utilities/apache-spark-agents/spark-troubleshooting-agent-cloudformation/spark-troubleshooting-mcp-setup.yaml)、指定上述選項，並使用 CloudFormation CLI 命令自行啟動範本，請參閱下列範例：

```
# deploy the stack with CloudFormation CLI commands
aws cloudformation deploy \
  --template-file spark-troubleshooting-mcp-setup.yaml \
  --stack-name spark-troubleshooting-mcp-setup \
  --region <your Spark MCP server launch region> \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameter-overrides \
    TroubleshootingRoleName=spark-troubleshooting-role


# retrieve the 1-line instruction to set the local environment variables, which will be used for the following MCP server configuration
aws cloudformation describe-stacks \
  --stack-name spark-troubleshooting-mcp-setup \
  --region <your Spark MCP server launch region> \
  --query "Stacks[0].Outputs[?OutputKey=='ExportCommand'].OutputValue" \
  --output text
```

開啟輸出索引標籤 （或從上述 CloudFormation describe-stacks CLI 命令擷取），並從 CloudFormation 輸出複製 1 行指令以設定您的環境變數，然後在您的本機環境中執行。範例 1 行指令：

```
export SMUS_MCP_REGION=<your mcp server launch region> && export IAM_ROLE=arn:aws:iam::111122223333:role/spark-troubleshooting-role-xxxxxx
```

然後在本機執行下列命令來設定 IAM 設定檔和 MCP 伺服器組態：

```
# Step 1: Configure AWS CLI Profile
aws configure set profile.smus-mcp-profile.role_arn ${IAM_ROLE}
aws configure set profile.smus-mcp-profile.source_profile <AWS CLI Profile to assume the IAM role - ex: default>
aws configure set profile.smus-mcp-profile.region ${SMUS_MCP_REGION}

# Step 2: if you are using kiro CLI, use the following command to add the MCP configuration
# Add Spark Troubleshooting MCP Server
kiro-cli-chat mcp add \
    --name "sagemaker-unified-studio-mcp-troubleshooting" \
    --command "uvx" \
    --args "[\"mcp-proxy-for-aws@latest\",\"https://sagemaker-unified-studio-mcp.${SMUS_MCP_REGION}.api.aws/spark-troubleshooting/mcp\", \"--service\", \"sagemaker-unified-studio-mcp\", \"--profile\", \"smus-mcp-profile\", \"--region\", \"${SMUS_MCP_REGION}\", \"--read-timeout\", \"180\"]" \
    --timeout 180000 \
    --scope global
    
# Add Spark Code Recommendation MCP Server
kiro-cli-chat mcp add \
    --name "sagemaker-unified-studio-mcp-code-rec" \
    --command "uvx" \
    --args "[\"mcp-proxy-for-aws@latest\",\"https://sagemaker-unified-studio-mcp.${SMUS_MCP_REGION}.api.aws/spark-code-recommendation/mcp\", \"--service\", \"sagemaker-unified-studio-mcp\", \"--profile\", \"smus-mcp-profile\", \"--region\", \"${SMUS_MCP_REGION}\", \"--read-timeout\", \"180\"]" \
    --timeout 180000 \
    --scope global
```

這應該更新`~/.kiro/settings/mcp.json`為包含 MCP 伺服器組態，如下所示。

```
{
  "mcpServers": {
    "sagemaker-unified-studio-mcp-troubleshooting": {
      "type": "stdio",
      "command": "uvx",
      "args": [
        "mcp-proxy-for-aws@latest",
        "https://sagemaker-unified-studio-mcp.us-east-1.api.aws/spark-troubleshooting/mcp",
        "--service",
        "sagemaker-unified-studio-mcp",
        "--profile",
        "smus-mcp-profile",
        "--region",
        "us-east-1",
        "--read-timeout",
        "180"
      ],
      "timeout": 180000,
      "disabled": false
    },
    "sagemaker-unified-studio-mcp-code-rec": {
      "type": "stdio",
      "command": "uvx",
      "args": [
        "mcp-proxy-for-aws@latest",
        "https://sagemaker-unified-studio-mcp.us-east-1.api.aws/spark-code-recommendation/mcp",
        "--service",
        "sagemaker-unified-studio-mcp",
        "--profile",
        "smus-mcp-profile",
        "--region",
        "us-east-1",
        "--read-timeout",
        "180"
      ],
      "timeout": 180000,
      "disabled": false
    }
  }
}
```

[支援的界面](spark-troubleshooting-using-troubleshooting-agent.md#supported-interfaces) 如需 Kiro、Cline 和 GitHub CoPilot 等不同 MCP 用戶端的組態指引，請參閱 。

# 使用 故障診斷代理程式
<a name="spark-troubleshooting-using-troubleshooting-agent"></a>

## 支援的部署模式
<a name="supported-deployment-modes"></a>

Amazon EMR 專用 Apache Spark 故障診斷代理程式支援故障 Spark 工作負載的全方位分析功能，包括自動錯誤診斷、效能瓶頸識別、程式碼建議和可採取行動的建議，以改善下列 Spark 部署模式的應用程式效能：
+ EC2 上的 EMR
+ EMR Serverless
+ AWS Glue

請參閱 [功能和功能](spark-troubleshooting-features.md) 以了解詳細功能、容量和限制。

## 支援的界面
<a name="supported-interfaces"></a>

### 對 Amazon SageMaker 筆記本中的儲存格進行故障診斷
<a name="troubleshooting-sagemaker-notebooks"></a>

Amazon SageMaker Notebooks 疑難排解體驗的示範。對於任何筆記本儲存格故障，您可以按一下 `Fix with AI` 按鈕，要求 Amazon SageMaker 筆記本代理程式對請求分析失敗進行故障診斷，然後在錯誤由程式碼導致時進行可能的程式碼修復。

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/btW8hwio0tE/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/btW8hwio0tE)


### 使用 Kiro CLI 對 Glue 和 EMR Spark 應用程式進行故障診斷
<a name="troubleshooting-glue-emr-applications"></a>

啟動 Kiro CLI 或您的 AI 助理，並驗證已載入的工具以進行故障診斷程序。

```
...
 sagemaker-unified-studio-mcp-code-rec (MCP)
 - spark_code_recommendation    not trusted
 
 sagemaker-unified-studio-mcp-troubleshooting (MCP)
 - analyze_spark_workload       not trusted
...
```

現在您已準備好開始 Spark 疑難排解代理程式工作流程。

Kiro CLI 疑難排解體驗的示範。您只需使用下列提示啟動故障診斷程序：

```
Analyze my Glue job. The job name is "xxx" and the job run id is "xxx"
```

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/YLwV_EenJXY/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/YLwV_EenJXY)


### 與其他 MCP 用戶端整合
<a name="integration-other-mcp-clients"></a>

中所述的組態[客服人員故障診斷的設定](spark-troubleshooting-agent-setup.md)也可用於其他 MCP 用戶端和 IDEs，以連線至受管 MCP 伺服器：
+ **與 Cline 整合** - 若要搭配 Cline 使用 MCP 伺服器，請修改 `cline_mcp_settings.json`並新增上述組態。如需如何管理 MCP 組態的詳細資訊，請參閱 [Cline 的文件](https://docs.cline.bot/mcp/configuring-mcp-servers)。
+ **與 Claude Code 整合** 若要搭配 Claude Code 使用 MCP 伺服器，請修改組態檔案以包含 MCP 組態。檔案路徑會根據您的作業系統而有所不同。如需詳細設定，請參閱 [ https://code.claude.com/docs/en/mcp](https://code.claude.com/docs/en/mcp)：//。
+ **與 GitHub Copilot 整合** - 若要搭配 GitHub Copilot 使用 MCP 伺服器，請依照 [https://docs.github.com/en/copilot/how-tos/provide-context/use-mcp/extend-copilot-chat-with-mcp](https://docs.github.com/en/copilot/how-tos/provide-context/use-mcp/extend-copilot-chat-with-mcp)：// 中的指示修改對應的組態檔案，並依照每個 IDE 的指示來啟用設定。

# 功能和功能
<a name="spark-troubleshooting-features"></a>

## 支援的平台
<a name="supported-platforms"></a>
+ **語言**：Python 和 Scala Spark 應用程式
+ **目標平台**：Amazon EMR、EMR Serverless 和 AWS Glue

## 運作方式
<a name="how-it-works"></a>

當您的 Spark 應用程式失敗時，您可以使用故障診斷代理程式自動調查發生的問題。它會分析您的 Spark 事件日誌、錯誤訊息和資源用量，以找出確切的問題 - 無論是 Spark 執行器記憶體不足、組態錯誤或程式碼錯誤。

當您要求自然語言提示來分析 Spark 工作負載時，代理程式會連線到您平台的資源並擷取功能 （包括 Spark 事件日誌、查詢計劃、執行器時間表、日誌追蹤、組態和指標）：
+ 在 EMR-EC2 上：它會連線至叢集的 [EMR 持久性 UI](https://docs.aws.amazon.com/emr/latest/ManagementGuide/app-history-spark-UI.html) 
+ 在 Glue 上：它會從 Glue Studio 的 [Spark UI](https://docs.aws.amazon.com/glue/latest/dg/monitor-spark-ui-jobs.html) 建置任務的內容
+ 在 EMR-Serverless 上：它會連線至任務的 EMR-Serverless [Spark 歷史記錄伺服器](https://docs.aws.amazon.com/emr-serverless/latest/APIReference/API_GetDashboardForJobRun.html) 
+ 代理程式也會分析您的錯誤堆疊追蹤和組態詳細資訊，為您提供可行的洞見。

對於失敗的工作負載，您可以取得明確的根本原因說明，以及修正它的特定步驟。如果代理程式偵測到與程式碼相關的問題，它會自動提供程式碼建議，向您顯示程式碼中的確切變更內容。您也可以隨時直接請求程式碼層級的建議，無需完整分析。

## 可用的區域
<a name="available-regions"></a>

Spark 疑難排解代理程式可在下列區域使用：
+ **亞太區域**：東京 (ap-northeast-1)、首爾 (ap-northeast-2)、新加坡 (ap-southeast-1)、雪梨 (ap-southeast-2) 和孟買 (ap-south-1)
+ **北美洲**：加拿大 (ca-central-1)
+ **歐洲**：斯德哥爾摩 (eu-north-1)、愛爾蘭 (eu-west-1)、倫敦 (eu-west-2)、巴黎 (eu-west-3) 和法蘭克福 (eu-central-1)
+ **南美洲**：聖保羅 (sa-east-1)
+ **美國**：北維吉尼亞 (us-east-1)、俄亥俄 (us-east-2) 和奧勒岡 (us-west-2)

## Spark 故障診斷範圍和使用者需求
<a name="scope-requirements"></a>
+ **支援的 Spark 工作負載狀態**：工具僅支援回應失敗的 Spark 工作負載。
+ **EMR 持久性 UI：**分析 Amazon EMR-EC2 工作負載時，分析工具會嘗試連線至 EMR 持久性 UI 以擷取金鑰 Spark 資訊。[ 此處](https://docs.aws.amazon.com/emr/latest/ManagementGuide/app-history-spark-UI.html#app-history-spark-UI-limitations)會記錄 EMR 持久性 UI 考量事項。
+ **Glue Studio Spark UI**：分析 AWS Glue 工作負載時，分析工具會從 Amazon S3 剖析使用者的 Spark 事件日誌，嘗試擷取金鑰 Spark 資訊。[ 此處](https://docs.aws.amazon.com/glue/latest/dg/monitor-spark-ui-jobs.html)會記錄允許的 Spark 事件日誌大小上限：滾動日誌為 512 MB 和 2 GB。
+ **程式碼建議：**僅支援 PySpark 工作負載的 Amazon EMR-EC2 和 AWS Glue 工作負載
+ **區域資源：**Spark 故障診斷代理程式是區域性，並使用該區域中的基礎 EMR 資源進行故障診斷程序。不支援跨區域疑難排解。

# 故障診斷和問答
<a name="spark-troubleshooting-agent-troubleshooting"></a>

## 疑難排解
<a name="spark-troubleshooting-common-issues"></a>

Spark 故障診斷代理程式的錯誤訊息會以不同的方式提供給不同的 MCP 用戶端。在此頁面中，我們會列出一些一般指引，說明使用適用於 Amazon EMR 的 Apache Spark 故障診斷代理程式時可能遇到的常見問題。

主題
+ [錯誤：MCP 伺服器無法載入](#mcp-server-failed-to-load)
+ [觀察：工具載入緩慢](#slow-tool-loading)
+ [錯誤：工具調用失敗，調節錯誤](#throttling-error)
+ [錯誤：工具回應與使用者錯誤](#user-error)
+ [錯誤：工具回應與內部錯誤](#internal-error)

### 錯誤：MCP 伺服器無法載入
<a name="mcp-server-failed-to-load"></a>
+ 確認您的 MCP 組態已正確設定。
+ **驗證 JSON 語法**：
  + 確保您的 JSON 有效，沒有語法錯誤
  + 檢查是否有遺漏的逗號、引號或括號
+ 驗證您的本機 AWS 登入資料，並確認 MCP IAM 角色的政策已正確設定。
+ 執行 /mcp 以驗證`Kiro-CLI`案例的 MCP 伺服器可用性

### 觀察：工具載入緩慢
<a name="slow-tool-loading"></a>
+ 第一次嘗試啟動伺服器時，載入工具可能需要幾秒鐘的時間。
+ 如果工具未顯示，請嘗試重新啟動聊天。
+ 執行 `/tools`命令來驗證工具可用性。
+ `/mcp` 如果伺服器啟動時沒有發生錯誤，請執行 。

### 錯誤：工具調用失敗，調節錯誤
<a name="throttling-error"></a>
+ 如果您達到服務限制，如果您看到調節例外狀況，請等待幾秒鐘發出工具叫用。

### 錯誤：工具回應與使用者錯誤
<a name="user-error"></a>
+ AccessDeniedException - 檢查錯誤訊息並修正許可問題。
+ InvalidInputException - 檢查錯誤訊息並更正工具輸入參數。
+ ResourceNotFoundException - 檢查錯誤訊息並修正資源參考的輸入參數。

### 錯誤：工具回應與內部錯誤
<a name="internal-error"></a>
+ 如果您看到 `The service is handling high-volume requests` ，請在幾秒鐘內重試工具叫用。
+ 如果您看到 `INTERNAL SERVICE EXCEPTION`，請記錄分析 ID、工具名稱、mcp 日誌或工具回應中可用的任何錯誤訊息，以及選用的已淨化對話歷史記錄，並聯絡 AWS 支援。

## 問與答
<a name="spark-troubleshooting-qa"></a>

### 1. 根據預設，我應該為工具啟用「信任」設定嗎？
<a name="qa-trust-setting"></a>

根據預設，所有工具呼叫一開始都不要開啟「信任」設定，並在接受程式碼建議時在 git 版本建置環境中操作。檢閱每個工具執行以了解正在進行的變更。

### 2. 利用故障診斷工具的常見範例提示是什麼？
<a name="qa-example-prompts"></a>

如需利用故障診斷工具[提示範例](spark-troubleshooting-agent-prompt-examples.md)的提示範例，請參閱 。

### 3. 哪些資料會傳輸至 LLM，以及如何處理？
<a name="qa-data-transmitted-to-llm"></a>

客戶資料和檔案會保留在您選擇的 AWS 區域內，不會跨區域傳輸。當代理程式在從 Amazon Bedrock 使用全域跨區域推論的區域中操作時，服務可能會根據需求，將請求路由到具有可用容量的最近區域。在這種情況下，只會傳輸從客戶日誌擷取的中繼資料和已處理的推論結果，而不是基礎客戶資料或檔案。所有資料都會在傳送到 LLM 進行處理之前被 PII 遮罩，無論推論是在相同區域內發生或路由到另一個區域。如需跨區域推論的運作方式和受影響區域的詳細資訊，請參閱 [Apache Spark 故障診斷代理程式的跨區域處理](spark-troubleshooting-cross-region-processing.md)。

# 詳細資訊中的 Spark 對客服人員工作流程進行故障診斷
<a name="spark-troubleshooting-agent-workflow"></a>

若要啟動疑難排解程序，您將需要存取在支援的平台 (EMR-EC2、EMR Serverless、 AWS Glue 或 Amazon SageMaker Data Notebooks) 上執行的失敗 Spark 應用程式識別符。應用程式應具有可存取的日誌、Spark 歷史記錄伺服器和組態詳細資訊。確保您擁有存取平台資源和應用程式中繼資料的必要許可。建立這些要求後，您可以提交如下所示的提示，以啟動故障診斷工作流程：

```
Analyze my EMR step execution failure, EMR id <step-id> with cluster id <cluster-id>
```

此時，代理程式將使用專用工具協調故障診斷。工作流程遵循下列步驟：

1. **功能擷取和內容建置**：代理程式會自動從 Spark 應用程式收集和分析遙測資料，包括歷史記錄伺服器日誌、組態設定和錯誤追蹤。您將看到工具收集有關效能指標、資源使用率模式和失敗簽章的資訊。

1. **分析和根本原因識別**：代理程式利用 AI 模型和 Spark 知識庫來關聯擷取的功能，並識別效能問題或失敗的根本原因。您將會收到：
   + **Analysis Insights**：客服人員探索和分析內容的技術詳細資訊。
   + **根本原因**：明確說明出了什麼問題和原因。
   + **初始評估**：無論問題是程式碼相關、組態相關還是資源相關，都會提供一些一般指引和分析以進行緩解。

1. **程式碼建議 **（如果適用）：如果分析根據錯誤分類識別與程式碼相關的問題，客服人員可以建議利用程式碼建議工具提供特定建議，以實作建議的程式碼修正，以及確切的程式碼之前/之後以及建議的替換。

疑難排解程序是反覆進行的 - 您可以繼續對話，深入探討特定問題；您也可以在我們的本機 Spark 程式碼開發中以互動方式使用工具來解決程式碼錯誤或持續改善程式碼。

# 提示範例
<a name="spark-troubleshooting-agent-prompt-examples"></a>

以下是可用於疑難排解體驗的提示範例清單。

## 1. 故障診斷 Spark 任務執行失敗
<a name="troubleshoot-job-failure"></a>

EC2 上的 EMR 故障診斷：

```
Troubleshoot my EMR-EC2 step with id s-xxxxxxxxxxxx on cluster j-xxxxxxxxxxxxx
```

Glue 任務故障診斷：

```
Troubleshoot my Glue job with job run id jr_xxxxxxxxxxxxxxxxxxxxxxxxxxxx and job name test_job
```

EMR Serverless 故障診斷：

```
Troubleshoot my EMR-Serverless job run with application id 00xxxxxxxx and job run id 00xxxxxxxx
```

## 2. 請求程式碼修正建議
<a name="request-code-fix"></a>

EC2 任務上的 EMR 請求碼修正建議：

```
Recommend code fix for my EMR-EC2 step with id s-STEP_ID on cluster j-CLUSTER_ID
```

Glue 任務的請求碼修正建議：

```
Recommend code fix for my Glue job with job run id jr_JOB_RUN_ID and job name test_job
```

# IAM 角色設定
<a name="spark-troubleshooting-agent-iam-setup"></a>

設定指示中的 CloudFormation 堆疊會為您自動設定 IAM 角色。如果您想要手動執行，請遵循下列指示：

## MCP 伺服器的 IAM 角色設定
<a name="iam-role-mcp-server"></a>

若要存取 SMUS Managed MCP 伺服器，需要具有下列內嵌政策的 IAM 角色：

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AllowUseSagemakerUnifiedStudioMcpServer",
            "Effect": "Allow",
            "Action": [
                "sagemaker-unified-studio-mcp:InvokeMcp",
                "sagemaker-unified-studio-mcp:CallReadOnlyTool",
                "sagemaker-unified-studio-mcp:CallPrivilegedTool"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
```

在後續步驟中，我們將為此角色建立設定檔。無論哪個帳戶擔任此角色以取得登入資料，都應新增至擔任角色政策。

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "AllowAccountToAssumeRole",
      "Effect": "Allow",
      "Principal": { "AWS": "arn:aws:iam::<accountId>:root" },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

## 依部署模式的其他許可 (EMR-EC2/EMR-S/Glue)
<a name="additional-permissions"></a>

### EMR-EC2 應用程式
<a name="emr-ec2-permissions"></a>

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "EMREC2ReadAccess",
            "Effect": "Allow",
            "Action": [
                "elasticmapreduce:DescribeCluster",
                "elasticmapreduce:DescribeStep",
                "elasticmapreduce:ListSteps",
                "elasticmapreduce:ListClusters",
                "elasticmapreduce:DescribeJobFlows"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "EMRS3LogAccess",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": "*"
        },
        {
            "Sid": "EMRPersistentApp",
            "Effect": "Allow",
            "Action": [
                "elasticmapreduce:CreatePersistentAppUI",
                "elasticmapreduce:DescribePersistentAppUI",
                "elasticmapreduce:GetPersistentAppUIPresignedURL"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
```

### Glue 任務
<a name="glue-permissions"></a>

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "GlueReadAccess",
            "Effect": "Allow",
            "Action": [
                "glue:GetJob",
                "glue:GetJobRun",
                "glue:GetJobRuns",
                "glue:GetJobs",
                "glue:BatchGetJobs"
            ],
            "Resource": [
                "arn:aws:glue:*:<account id>:job/*"
            ]
        },
        {
            "Sid": "GlueCloudWatchLogsAccess",
            "Effect": "Allow",
            "Action": [
                "logs:GetLogEvents",
                "logs:FilterLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:*:<account id>:log-group:/aws/glue/*"
            ]
        },
        {
            "Sid": "GlueSparkWebUI",
            "Effect": "Allow",
            "Action": [
                "glue:RequestLogParsing",
                "glue:GetLogParsingStatus",
                "glue:GetEnvironment",
                "glue:GetStage",
                "glue:GetStages",
                "glue:GetStageFiles",
                "glue:BatchGetStageFiles",
                "glue:GetStageAttempt",
                "glue:GetStageAttemptTaskList",
                "glue:GetStageAttemptTaskSummary",
                "glue:GetExecutors",
                "glue:GetExecutorsThreads",
                "glue:GetStorage",
                "glue:GetStorageUnit",
                "glue:GetQueries",
                "glue:GetQuery",
                "glue:GetDashboardUrl"
            ],
            "Resource": [
                "arn:aws:glue:*:<account id>:job/*"
            ]
        },
        {
            "Sid": "GluePassRoleAccess",
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": "*",
            "Condition": {
                "StringLike": {
                    "iam:PassedToService": "glue.amazonaws.com"
                }
            }
        }
    ]
}
```

### EMR Serverless 應用程式
<a name="emr-serverless-permissions"></a>

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "EMRServerlessReadAccess",
            "Effect": "Allow",
            "Action": [
                "emr-serverless:GetJobRun",
                "emr-serverless:GetApplication",
                "emr-serverless:ListApplications",
                "emr-serverless:ListJobRuns",
                "emr-serverless:ListJobRunAttempts",
                "emr-serverless:GetDashboardForJobRun",
                "emr-serverless:ListTagsForResource"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "EMRServerlessCloudWatchLogsAccess",
            "Effect": "Allow",
            "Action": [
                "logs:GetLogEvents",
                "logs:FilterLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:*:<account id>:log-group:/aws/emr-serverless/*"
            ]
        },
        {
            "Sid": "EMRServerlessS3LogsAccess",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": "*"
        }
    ]
}
```

### KMS 許可 - CloudWatch Logs
<a name="kms-permissions"></a>

如果 CloudWatch Logs 使用 CMK 加密，請新增下列政策，讓服務可以讀取 EMR-Serverless 應用程式日誌。

```
{
    "Effect": "Allow",
    "Action": [
        "kms:Decrypt",
        "kms:DescribeKey"
    ],
    "Resource": "arn:aws:kms:<region>:<account-id>:key/<cw-logs-cmk-id>"
}
```

# 使用 Spark 疑難排解工具
<a name="spark-troubleshooting-agent-using-tools"></a>

## 可用的故障診斷工具
<a name="available-tools"></a>

MCP 服務為 Spark 故障診斷代理程式提供不同的工具。主要工具如下：


| 工具名稱 | 工具類別 | Description | 
| --- | --- | --- | 
| analyze\$1spark\$1workload | 根本原因分析 | 提供故障 Apache Spark 工作負載的詳細疑難排解 | 
| spark\$1code\$1recommendation | 程式碼修正建議 | 為失敗的任務提供 Apache Spark 程式碼建議 | 

# 設定 Amazon SageMaker Unified Studio MCP 的介面 VPC 端點
<a name="spark-troubleshooting-agent-vpc-endpoints"></a>

您可以建立*介面 VPC 端點*，在 VPC 與 Amazon SageMaker Unified Studio MCP 服務之間建立私有連線。介面端點採用 [Amazon VPC](https://aws.amazon.com/vpc/) 技術，可讓您在沒有網際網路閘道、NAT 裝置、VPN 連線或連線的情況下，私下存取 VPC 中的 MCP 伺服器。VPC 中的執行個體不需要公有 IP 地址即可與 MCP 服務通訊，而 VPC 和 MCP 服務之間的流量也不會離開 Amazon 網路。

每個界面端點都由 VPC 子網路中的一或多個[彈性網路界面](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html)表示。如需詳細資訊，請參閱《Amazon [VPC 使用者指南》中的界面](https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html) VPC 端點。 **

## 步驟 1：為 Amazon SageMaker Unified Studio MCP 建立介面 VPC 端點
<a name="create-vpc-endpoint"></a>

您可以使用 Amazon VPC 主控台或 ，為 Amazon SageMaker Unified Studio MCP 服務建立 VPC 端點 AWS CLI。如需詳細資訊，請參閱《Amazon VPC 使用者指南》**中的[建立介面端點](https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html#create-interface-endpoint)。

使用下列服務名稱為 Amazon SageMaker Unified Studio MCP 建立 VPC 端點：
+ com.amazonaws.*<aws-region>*.sagemaker-unified-studio-mcp

如果您為端點啟用私有 DNS，則可以使用區域的預設 DNS 名稱向 Amazon SageMaker Unified Studio MCP 提出 API 請求，例如， `sagemaker-unified-studio-mcp.us-east-1.api.aws`

如需詳細資訊，請參閱《Amazon VPC 使用者指南》**中的[透過介面端點存取服務](https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html#access-service-though-endpoint)。

## 步驟 2：為 Amazon SageMaker Unified Studio MCP 建立 VPC 端點政策
<a name="create-vpc-endpoint-policy"></a>

您可以將端點政策連接至 VPC 端點，以控制對 Amazon SageMaker Unified Studio MCP 的存取。此政策會指定下列資訊：
+ 可執行動作的主體。
+ 可執行的動作。
+ 可供執行動作的資源。

如需詳細資訊，請參閱 *Amazon VPC 使用者指南*中的[使用 VPC 端點控制對服務的存取](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-endpoints-access.html)。

### 範例：允許 MCP 存取特定 IAM 角色的 VPC 端點政策
<a name="vpc-endpoint-policy-example"></a>

以下是 Amazon SageMaker Unified Studio MCP 存取的端點政策範例。連接至端點時，此政策會授予所有資源上特定 IAM 角色委託人的所列 Amazon SageMaker Unified Studio MCP 動作的存取權。

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::ACCOUNT-ID:role/YourRoleName"
      },
      "Action": [
        "sagemaker-unified-studio-mcp:InvokeMcp",
        "sagemaker-unified-studio-mcp:CallReadOnlyTool",
        "sagemaker-unified-studio-mcp:CallPrivilegedTool"
      ],
      "Resource": "*"
    }
  ]
}
```

## 步驟 3：測試您的 VPC
<a name="test-vpc-endpoint"></a>

`curl` 命令會透過提出 HTTP/HTTPS 請求，驗證從 VPC 網路 (EC2) 到 VPC 端點的end-to-end網路連線。從 MCP 伺服器接收訊息的 curl 回應會確認完整的網路路徑正常運作。

### 方法 1：啟用私有 DNS （建議）
<a name="test-private-dns-enabled"></a>

```
curl https://sagemaker-unified-studio-mcp.us-east-1.api.aws/spark-troubleshooting/mcp
```

### 方法 2：未啟用私有 DNS
<a name="test-private-dns-disabled"></a>

```
curl -k https://vpce-0069xxxx-ejwhxxx.sagemaker-unified-studio-mcp.us-east-1.vpce.amazonaws.com/spark-troubleshooting/mcp
```

**注意**  
由於 VPC 端點 DNS 名稱與憑證的通用名稱 (CN) 不相符， `-k`旗標會略過 SSL 憑證驗證。

在這兩種情況下，curl 命令都會傳回回應：`{"Message":"...."}`。使用訊息傳回 會驗證 MCP 服務 VPC 端點的成功網路路徑連線。

## 步驟 4：開始使用 MCP VPC 端點
<a name="use-vpc-endpoint"></a>

驗證連線後，您可以依照步驟在 中設定 MCP[客服人員故障診斷的設定](spark-troubleshooting-agent-setup.md)。只需在 MCP 組態中使用私有 VPC 端點即可。

# Apache Spark 故障診斷代理程式的跨區域處理
<a name="spark-troubleshooting-cross-region-processing"></a>

Apache Spark 疑難排解代理程式使用跨區域推論來處理自然語言請求並產生回應。透過跨區域推論，代理程式會自動路由您的推論請求，以最佳化效能、最大化可用的運算資源和模型可用性，並提供最佳的客戶體驗。使用的跨區域推論類型取決於您執行 Apache Spark 故障診斷代理程式的區域。在大多數區域中，代理程式會選取地理位置內的最佳區域，以處理您的推論請求。不過，在某些區域中，代理程式提出的推論請求會安全地路由至所有全球商業 AWS 區域的所有可用運算資源。

## 跨區域推論
<a name="cross-region-inference-overview"></a>

Apache Spark 疑難排解代理程式採用 Amazon Bedrock 技術，並使用跨區域推論將流量分散到不同 AWS 區域，以增強大型語言模型 (LLM) 推論效能和可靠性。

雖然跨區域推論不會變更您 Spark 應用程式或疑難排解體驗的託管位置或儲存資料的位置，但您的輸入提示和輸出結果可能會傳輸到不同的區域以進行推論處理。所有資料都會透過 Amazon 的安全網路進行加密傳輸。

使用跨區域推論無需額外費用。

## 支援跨區域推論的區域
<a name="supported-regions-cross-region"></a>

 **使用地理跨區域推論的區域** 

對於大多數區域，跨區域推論請求會保留在您執行 Apache Spark 故障診斷代理程式的相同地理位置中的 AWS 區域。例如，向美國東部 （維吉尼亞北部） 區域的代理提出的請求只會路由到美國地理區域內的 AWS 區域。下表說明根據發出請求的地理位置，您的請求可能路由到哪些區域：


| 支援的地理位置 | 推論區域 | 
| --- | --- | 
|  美國  |  美國東部 （維吉尼亞北部） (us-east-1)、美國西部 （奧勒岡） (us-west-2)、美國東部 （俄亥俄） (us-east-2)、美國西部 （加利佛尼亞北部） (us-west-1)  | 
|  歐洲  |  歐洲 （法蘭克福） (eu-central-1)、歐洲 （愛爾蘭） (eu-west-1)、歐洲 （巴黎） (eu-west-3)、歐洲 （斯德哥爾摩） (eu-north-1)、歐洲 （倫敦） (eu-west-2)  | 
|  亞太區域  |  亞太區域 （東京） (ap-northeast-1)、亞太區域 （首爾） (ap-northeast-2)、亞太區域 （孟買） (ap-south-1)  | 

### 使用全域跨區域推論的區域
<a name="global-cross-region-inference"></a>

**重要**  
下列 AWS 區域使用全域跨區域推論。當您在這些區域中使用 Apache Spark 故障診斷代理程式時，您的請求可能會全域傳輸到其他 AWS 區域以進行推論處理，以最佳化效能和可用性：  
南美洲 （聖保羅） (sa-east-1)
亞太地區 (新加坡) (ap-southeast-1)
亞太地區 (雪梨) (ap-southeast-2)
加拿大 (中部) (ca-central-1)

# 使用 記錄 Amazon SageMaker Unified Studio MCP 呼叫 AWS CloudTrail
<a name="spark-troubleshooting-cloudtrail-integration"></a>

Amazon SageMaker Unified Studio MCP Server 已與 服務整合 AWS CloudTrail，此服務可提供使用者、角色或 Amazon SageMaker Unified Studio MCP Server 中 AWS 服務所採取動作的記錄。CloudTrail 會將 Amazon SageMaker Unified Studio MCP Server 的所有 API 呼叫擷取為事件。擷取的呼叫包括對 Amazon SageMaker Unified Studio MCP Server 的呼叫，以及在從 SageMaker Unified Studio MCP Server 執行工具期間對其他 AWS 操作的程式碼呼叫。如果您建立線索，則可以將 CloudTrail 事件持續交付至 Amazon S3 儲存貯體，包括 Amazon SageMaker Unified Studio MCP Server 的事件。即使您未設定追蹤，依然可以透過 CloudTrail 主控台中的**事件歷史記錄**檢視最新事件。您可以使用 CloudTrail 所收集的資訊，判斷對 Amazon SageMaker Unified Studio MCP Server 提出的請求、提出請求的 IP 地址、提出請求的人員、提出請求的時間，以及其他詳細資訊。

若要進一步了解 CloudTrail，請參閱[「AWS CloudTrail 使用者指南」](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/)。

## CloudTrail 中的 Amazon SageMaker Unified Studio MCP Server 資訊
<a name="sagemaker-mcp-info-in-cloudtrail"></a>

當您建立 AWS 帳戶時，會在您的帳戶上啟用 CloudTrail。當 Amazon SageMaker Unified Studio MCP Server 中發生活動時，該活動會與**事件歷史記錄**中的其他 AWS 服務事件一起記錄在 CloudTrail 事件中。您可以在 AWS 帳戶中檢視、搜尋和下載最近的事件。如需詳細資訊，請參閱[「使用 CloudTrail 事件歷史記錄檢視事件」](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/view-cloudtrail-events.html)。

若要持續記錄您 AWS 帳戶中的事件，包括 SageMaker Unified Studio MCP Server 的事件，請建立追蹤。線索能讓 CloudTrail 將日誌檔案交付至 Amazon S3 儲存貯體。根據預設，當您在主控台中建立線索時，線索會套用至所有 AWS 區域。線索會記錄 AWS 分割區中所有區域的事件，並將日誌檔案交付至您指定的 Amazon S3 儲存貯體。此外，您可以設定其他 AWS 服務，以進一步分析和處理 CloudTrail 日誌中所收集的事件資料。如需詳細資訊，請參閱下列內容：
+ [建立追蹤的概觀](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-create-and-update-a-trail.html)
+ [CloudTrail 支援的服務和整合](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-aws-service-specific-topics.html)
+ [設定 CloudTrail 的 Amazon SNS 通知](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/configure-sns-notifications-for-cloudtrail.html)
+ [接收多個區域的 CloudTrail 日誌檔案](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html)和[接收多個帳戶的 CloudTrail 日誌檔案](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-receive-logs-from-multiple-accounts.html)

CloudTrail 會記錄工具執行期間對 AWS 服務的所有 SageMaker Unified Studio MCP Server 工具叫用和 API 呼叫。例如，對來自工具的不同工具和 AWS 服務呼叫的呼叫會在 CloudTrail 日誌檔案中產生項目。

每一筆事件或日誌專案都會包含產生請求者的資訊。身分資訊可協助您判斷下列事項：
+ 該請求是否使用根或 IAM 使用者憑證提出。
+ 提出該請求時，是否使用了特定角色或聯合身分使用者的暫時安全憑證。
+ 請求是否由其他 AWS 服務提出。

如需詳細資訊，請參閱 [CloudTrail userIdentity 元素](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-user-identity.html)。

## 了解 Amazon SageMaker Unified Studio MCP Server 日誌檔項目
<a name="understanding-mcp-log-entries"></a>

追蹤是一種組態，能讓事件以日誌檔案的形式交付到您指定的 Amazon S3 儲存貯體。CloudTrail 日誌檔案包含一或多個日誌專案。一個事件為任何來源提出的單一請求，並包含請求動作、請求的日期和時間、請求參數等資訊。CloudTrail 日誌檔並非依公有 API 呼叫的堆疊追蹤排序，因此不會以任何特定順序出現。

以下範例顯示的是展示 `CallTool` 動作的 CloudTrail 日誌項目。

```
{
    "eventVersion": "1.09",
    "userIdentity": {
        ...
    },
    "eventTime": "...",
    "eventSource": "sagemaker-unified-studio-mcp.amazonaws.com",
    "eventName": "CallPrivilegedTool",
    "awsRegion": "us-east-1",
    "sourceIPAddress": "...",
    "userAgent": "...",
    "requestParameters": {
        "id": 1,
        "method": "tools/call",
        "params": {
            "name": "generate_spark_upgrade_plan",
            "arguments": "***",
            "_meta": {
                "progressToken": 1
            }
        },
        "jsonrpc": "2.0"
    },
    "responseElements": {
        "result": {
            "content": "***",
            "structuredContent": "***",
            "isError": false
        },
        "id": 1,
        "jsonrpc": "2.0"
    },
    "requestID": "12345678-1234-1234-1234-123456789012",
    "eventID": "87654321-4321-4321-4321-210987654321",
    "readOnly": false,
    "eventType": "AwsMcpEvent",
    "managementEvent": true,
    "recipientAccountId": "123456789012",
    "eventCategory": "Management"
}
```

下列範例顯示 CloudTrail 日誌項目，示範升級工具調用期間來自 Amazon SageMaker Unified Studio MCP `AddJobFlowSteps`的動作。

```
{
    "eventVersion": "1.11",
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "...",
        "arn": "...",
        "accountId": "123456789012",
        "accessKeyId": "...",
        "sessionContext": {
            ...
        },
        "invokedBy": "sagemaker-unified-studio-mcp.amazonaws.com"
    },
    "eventTime": "...",
    "eventSource": "elasticmapreduce.amazonaws.com",
    "eventName": "AddJobFlowSteps",
    "awsRegion": "us-east-1",
    "sourceIPAddress": "sagemaker-unified-studio-mcp.amazonaws.com",
    "userAgent": "sagemaker-unified-studio-mcp.amazonaws.com",
    "requestParameters": {
        "jobFlowId": "j-2PY4KXXXXXX63",
        "steps": [
            ...
        ]
    },
    "responseElements": {
        "stepIds": [
            ...
        ]
    },
    "requestID": "12345678-1234-1234-1234-123456789013",
    "eventID": "87654321-4321-4321-4321-210987654322",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "123456789012",
    "sharedEventID": "12345678-1234-1234-1234-123456789012",
    "vpcEndpointId": "sagemaker-unified-studio-mcp.amazonaws.com",
    "vpcEndpointAccountId": "sagemaker-unified-studio-mcp.amazonaws.com",
    "eventCategory": "Management"
}
```

# Apache Spark 代理程式的服務改進
<a name="spark-agents-service-improvements"></a>

例如，適用於 Amazon EMR 的 Apache Spark 代理程式可能會使用內容，以協助代理程式對常見問題提供更好的回應、修正操作問題或偵錯。

## AWS 可用於改善服務的內容
<a name="content-used-for-improvement"></a>
+ 您的自然語言提示，並從 Amazon EMR、 AWS Glue 和 Amazon SageMaker 筆記本的 Apache Spark 代理程式產生回應

## AWS 不用於改善服務的內容
<a name="content-not-used-for-improvement"></a>
+ 您為 Spark 應用程式自行撰寫的程式碼
+ SageMaker 筆記本內容和中繼資料
+ 來自 Glue Data Catalog AWS 或其他資料來源的資料

只有 Amazon 員工才能存取資料。您的信任、隱私和客戶內容的安全性是我們最重視的，我們也會確保我們的使用符合我們對您的承諾。如需更多資訊，請參閱 資料隱私權常見問答集。

## 如何選擇退出
<a name="how-to-opt-out"></a>

若要選擇退出 Apache Spark 代理程式的資料收集，請在 AWS Organizations for Amazon SageMaker Unified Studio MCP Service 中設定 AI 服務選擇退出政策。如需詳細資訊，請參閱 *AWS Organizations 使用者指南*中的 [AI 服務選擇退出政策](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_ai-opt-out.html)。

當您設定 AI 服務選擇退出政策時，其具有下列效果：
+ AWS 在您選擇退出 （如果有的話） 之前， 會刪除其為了改善服務而收集和儲存的資料。
+ 在您選擇退出後， AWS 將不再收集或儲存此資料。
+ AWS 將不再使用您的內容來改善服務。

# 優化 Spark 效能
<a name="emr-spark-performance"></a>

Amazon EMR 為 Spark 提供多種效能優化功能。本主題將詳細說明每個最佳化功能。

如需如何設定 Spark 組態的詳細資訊，請參閱 [設定 Spark](emr-spark-configure.md)。

## 自適應查詢執行
<a name="emr-spark-performance-aqe"></a>

自適應查詢執行是一種依據執行期統計資料對查詢計畫進行重新優化的框架。從 Amazon EMR 5.30.0 開始，以下來自 Apache Spark 3 的自適應查詢執行優化也在 Apache Amazon EMR Runtime for Spark 2 上提供。
+ 自適應聯結轉換
+ 隨機分割區的自適應合併

**自適應聯結轉換**

自適應聯結轉換透過依據查詢階段的執行期大小將 sort-merge-join 操作轉換為 broadcast-hash-joins 操作，從而提升查詢的效能。當聯結的一側小到足以將其輸出廣播到所有執行器，因此無需隨機交換並排序聯結的兩側時，broadcast-hash-joins 的效能通常會更出色。當 Spark 自動執行 broadcast-hash-joins 時，自適應聯結轉換會擴大案例的範圍。

此功能預設為啟用。它可透過將 `spark.sql.adaptive.enabled` 設為 `false` 停用，但也會停用自適應查詢執行框架。當其中某個聯結的一側之執行期統計資料不超過 `spark.sql.autoBroadcastJoinThreshold` (預設為 10,485,760 位元組，即 10 MiB) 時，Spark 會決定將 sort-merge-join 轉換為 broadcast-hash-join。

**隨機分割區的自適應合併**

隨機分割區的自適應合併小型接續隨機分割區，以避免過多小型任務產生額外負荷，從而提升查詢的效能。這可讓您預先設定較高數量的初始隨機分割區，然後在執行期縮減為目標大小，提高使分散式隨機分割區變得更均勻的機率。

除非明確設定 `spark.sql.shuffle.partitions`，否則此功能預設為啟用。它可透過將 `spark.sql.adaptive.coalescePartitions.enabled` 設為 `true` 啟用。使用 `spark.sql.adaptive.coalescePartitions.minPartitionNum` 和 `spark.sql.adaptive.advisoryPartitionSizeInBytes` 屬性，可分別調整隨機分割區的初始數量和目標分割區大小。請見下表，了解此功能相關 Spark 屬性的更詳細資訊。


**Spark 自適應合併分割區屬性**  

| 屬性 | 預設值 | Description | 
| --- | --- | --- | 
|  `spark.sql.adaptive.coalescePartitions.enabled`  |  true，除非明確設定 `spark.sql.shuffle.partitions`  |  當為 true 且 spark.sql.adaptive.enabled 也設為 true 時，Spark 會依據目標大小合併接續的隨機分割區 (由 `spark.sql.adaptive.advisoryPartitionSizeInBytes` 指定)，以避免有過多小型任務。  | 
|  `spark.sql.adaptive.advisoryPartitionSizeInBytes`  | 64 MB |  合併時隨機分割區的建議大小 (以位元組為單位)。此組態僅在 `spark.sql.adaptive.enabled` 和 `spark.sql.adaptive.coalescePartitions.enabled` 均為 `true` 時有影響。  | 
|  `spark.sql.adaptive.coalescePartitions.minPartitionNum`  | 25 |  合併後隨機分割區的最小數量。此組態僅在 `spark.sql.adaptive.enabled` 和 `spark.sql.adaptive.coalescePartitions.enabled` 均為 `true` 時有影響。  | 
|  `spark.sql.adaptive.coalescePartitions.initialPartitionNum`  | 1000 |  合併前隨機分割區的初始數量。此組態僅在 `spark.sql.adaptive.enabled` 和 `spark.sql.adaptive.coalescePartitions.enabled` 均為 `true` 時有影響。  | 

## 動態分割區剔除
<a name="emr-spark-performance-dynamic"></a>

動態分割區清除可透過更準確選取表格中需要供特定查詢讀取和處理的特定分割區，來改善任務效能。透過降低讀取和處理的資料量，即可省下任務執行所用的大量時間。使用 Amazon EMR 5.26.0，此功能預設為啟用。在 Amazon EMR 5.24.0 和 5.25.0 中，您可以透過從 Spark 設定 Spark 屬性 `spark.sql.dynamicPartitionPruning.enabled` 或在建立叢集時，來啟用此功能。


**Spark 動態分割區剔除分割區屬性**  

| 屬性 | 預設值 | Description | 
| --- | --- | --- | 
|  `spark.sql.dynamicPartitionPruning.enabled`  |  `true`  |  如果為 true，啟用動態分割區剔除。  | 
|  `spark.sql.optimizer.dynamicPartitionPruning.enforceBroadcastReuse`  |  `true`  |  若為 `true`，Spark 會在查詢執行前執行防禦性檢查，以確保動態剔除篩選條件中廣播交換的重複使用不會被後續的準備規則 (例如使用者定義的單欄規則) 中斷。當重複使用被中斷且此組態為 `true`，Spark 會移除受影響的動態剔除篩選條件，以防範發生效能與正確性問題。當動態剔除篩選條件的廣播交換產生與對應聯結操作的廣播交換不同或不一致的結果時，即可能發生正確性問題。將此組態設為 `false` 時應保持謹慎；它支援規避一些情形，例如重複使用被使用者定義的單欄規則中斷。啟用「自適應查詢執行」時，始終強制執行廣播重複使用。  | 

此最佳化可改善 Spark 2.4.1 現有功能，此版本僅支援下推可在計劃時間解析的靜態述詞。

以下是在 Spark 2.4.2 中下推的靜態述詞範例。

```
partition_col = 5

partition_col IN (1,3,5)

partition_col between 1 and 3

partition_col = 1 + 3
```

動態分割區清除允許 Spark 引擎在執行時間動態推斷需要讀取哪些分割區，以及可安全消除哪些分割區。例如，以下查詢包含兩個表格：`store_sales` 表格，其中包含所有商店的所有總銷售，並依區域分區，而 `store_regions` 表格包含每個國家的區域對應。此表格包含分佈於世界各地的商店相關資料，但我們只會查詢北美洲的資料。

```
select ss.quarter, ss.region, ss.store, ss.total_sales 
from store_sales ss, store_regions sr
where ss.region = sr.region and sr.country = 'North America'
```

在沒有使用動態分割區清除時，這個查詢會讀取所有區域，再篩選符合子查詢結果的區域子集。使用動態分割區清除時，這個查詢只會為在子查詢中傳回的區域讀取和處理分割區。這可透過讀取較少儲存區的資料和處理較少記錄來節省時間和資源。

## 扁平化純量子查詢
<a name="emr-spark-performance-flatten"></a>

此最佳化可改善在相同表格具備純量子查詢的查詢效能。使用 Amazon EMR 5.26.0，此功能預設為啟用。在 Amazon EMR 5.24.0 和 5.25.0 中，您可以透過從 Spark 設定 Spark 屬性 `spark.sql.optimizer.flattenScalarSubqueriesWithAggregates.enabled` 或在建立叢集時，來啟用此功能。當此屬性設為 true，如有可能，此查詢最佳化工具會將使用相同關係的彙總純量子查詢扁平化。純量子查詢的扁平化是透過將子查詢中存在的任何述詞推送至彙總函數，然後再使用每個關係的所有彙總函數來執行一個彙總。

以下是將受益於此最佳化的查詢範本。

```
select (select avg(age) from students                    /* Subquery 1 */
                 where age between 5 and 10) as group1,
       (select avg(age) from students                    /* Subquery 2 */
                 where age between 10 and 15) as group2,
       (select avg(age) from students                    /* Subquery 3 */
                 where age between 15 and 20) as group3
```

此最佳化會透過以下方式重寫先前的查詢：

```
select c1 as group1, c2 as group2, c3 as group3
from (select avg (if(age between 5 and 10, age, null)) as c1,
             avg (if(age between 10 and 15, age, null)) as c2,
             avg (if(age between 15 and 20, age, null)) as c3 from students);
```

請注意，重寫查詢只會讀取一次學生的表格，三個子查詢的述詞會被推送至該 `avg` 函數。

## INTERSECT 前的 DISTINCT
<a name="emr-spark-performance-distinct"></a>

使用 INTERSECT 時此最佳化會將聯結最佳化。使用 Amazon EMR 5.26.0，此功能預設為啟用。在 Amazon EMR 5.24.0 和 5.25.0 中，您可以透過從 Spark 設定 Spark 屬性 `spark.sql.optimizer.distinctBeforeIntersect.enabled` 或在建立叢集時，來啟用此功能。使用 INTERSECT 的查詢會自動轉換為使用 left-semi 聯結。此屬性設為 true 時，如果查詢最佳化工具偵測到 DISTINCT 運算子可讓 left-semi 聯結變成 BroadcastHashJoin (而不是 SortMergeJoin)，則會將 DISTINCT 運算子推送到 INTERSECT 的子項。

以下是將受益於此最佳化的查詢範本。

```
(select item.brand brand from store_sales, item
     where store_sales.item_id = item.item_id)
intersect
(select item.brand cs_brand from catalog_sales, item 
     where catalog_sales.item_id = item.item_id)
```

沒有啟用此屬性 `spark.sql.optimizer.distinctBeforeIntersect.enabled` 時，查詢的重寫方式如下。

```
select distinct brand from
  (select item.brand brand from store_sales, item
     where store_sales.item_id = item.item_id)
left semi join
   (select item.brand cs_brand from catalog_sales, item 
     where catalog_sales.item_id = item.item_id)
 on brand <=> cs_brand
```

啟用此屬性 `spark.sql.optimizer.distinctBeforeIntersect.enabled` 時，查詢的重寫方式如下。

```
select brand from
  (select distinct item.brand brand from store_sales, item
     where store_sales.item_id = item.item_id)
left semi join
   (select distinct item.brand cs_brand from catalog_sales, item 
     where catalog_sales.item_id = item.item_id)
 on brand <=> cs_brand
```

## Bloom 篩選條件聯結
<a name="emr-spark-performance-bloom"></a>

此最佳化可以使用從聯結另一側之值產生的 [Bloom 篩選條件](https://en.wikipedia.org/wiki/Bloom_filter)，預先篩選聯結的一側，進而提升某些聯結的效能。使用 Amazon EMR 5.26.0，此功能預設為啟用。在 Amazon EMR 5.25.0 中，您可以透過從 Spark 設定 Spark 屬性 `spark.sql.bloomFilterJoin.enabled` 至 `true` 或在建立叢集時，來啟用此功能。

以下是受益於 Bloom 篩選條件的範例查詢。

```
select count(*)
from sales, item
where sales.item_id = item.id
and item.category in (1, 10, 16)
```

啟用此功能時，Bloom 篩選條件是以其類別落於正接受查詢之類別集合的所有項目 ID 所建立。掃描銷售資料表時，Bloom 篩選條件用於判定哪些銷售是肯定不在 Bloom Filter 所定義之集合中的項目。因此能夠盡早篩選掉這些已識別的銷售。

## 優化的聯結重新排序
<a name="emr-spark-performance-join-reorder"></a>

此最佳化可透過篩選條件重新排序涉及資料表的聯結，以提升查詢效能。使用 Amazon EMR 5.26.0，此功能預設為啟用。在 Amazon EMR 5.25.0 中，您可以將 Spark 組態參數 `spark.sql.optimizer.sizeBasedJoinReorder.enabled` 設為 true，來啟用此功能。如在查詢中所列出，在 Spark 中的預設行為是由左至右聯結資料表。此策略會以篩選條件跳過執行較小聯結的機會，以受益於之後成本較高的聯結。

以下範例查詢回報一國內所有商店的全部退貨項目。若無最佳化的聯結重新排序功能，Spark 會先聯結兩張大型資料表 `store_sales` 和 `store_returns`，然後將這些資料表與 `store` 聯結，最後與 `item` 聯結。

```
select ss.item_value, sr.return_date, s.name, i.desc, 
from store_sales ss, store_returns sr, store s, item i
where ss.id = sr.id and ss.store_id = s.id and ss.item_id = i.id
and s.country = 'USA'
```

有了最佳化的聯結重新排序功能，由於 `store` 有篩選條件且小於 `store_returns` 和 `broadcastable`，因此 Spark 會先將 `store_sales` 與 `store` 聯結。然後，Spark 與 `store_returns` 聯結，最後與 `item` 聯結。如果 `item` 有篩選條件且是 broadcastable，它也會符合重新排序的資格，因而讓 `store_sales` 與 `store` 聯結，然後與 `item` 聯結，最後再與 `store_returns` 聯結。

# Spark 結果片段快取
<a name="emr-spark-fragment-result-caching"></a>

Amazon EMR 6.6.0 及更高版本包含選用的 Spark 結果片段快取功能，該功能會自動快取結果片段。這些結果片段是來自查詢子樹狀結構的部分結果，它們存放在您選擇的 Amazon S3 儲存貯體中。儲存的查詢結果片段會在後續的查詢執行中重複使用，進而加快查詢速度。

結果片段快取會分析您的 Spark 查詢，並在您指定的 S3 位置快取合格的結果片段。在後續的查詢執行中，系統會自動偵測並從 S3 擷取可使用的查詢結果片段。結果片段快取不同於結果集合快取，後者的後續查詢必須與原始查詢完全相符才能從快取傳回結果。當用於重複以您的資料之靜態子集為目標的查詢時，結果片段快取可大幅加快速度並提升效能。

考慮以下查詢，它會計算 2022 年前的訂單數量：

```
select
    l_returnflag,
    l_linestatus,
    count(*) as count_order
from
    lineitem
where
    l_shipdate <= current_date
    and year(l_shipdate) == '2022'
group by
    l_returnflag,
    l_linestatus
```

隨著時間推移，此查詢需要每天執行以報告該年度的總銷售額。如果沒有結果片段快取，則需要每天重新計算一年中所有日期的結果。該查詢會隨時間變得越來越慢，並在年底時最慢，因為需要重新計算所有 365 天的結果。

 當您啟用結果片段快取時，您將使用過去每天 (當年) 的快取結果。每天，該功能僅必須重新計算一天的結果。該功能對結果片段執行運算，然後快取相應片段。因此，啟用快取的查詢變得更快，它們在後續的每次查詢中保持不變。

## 啟用 Spark 結果片段快取
<a name="enable-fragment-caching"></a>

若要啟用 Spark 結果片段快取，請執行下列步驟：

1. 在 Amazon S3 中建立快取儲存貯體，並為 EMRFS 授權讀取/寫入存取。如需詳細資訊，請參閱[授權存取 Amazon S3 中的 EMRFS 資料](emr-plan-credentialsprovider.md)。

1. 設定 Amazon EMR Spark 組態以啟用該功能。

   ```
   spark.subResultCache.enabled = true
   spark.subResultCache.fs.root.path = s3://&example-s3-bucket;/cache_dir/
   ```

1. 啟用儲存貯體的 S3 生命週期管理，以自動清除快取檔案。

1. 您可以選擇性設定 reductionRationThreshold 和 maxBufferSize 屬性，以進一步微調該功能。

   ```
   spark.sql.subResultCache.reductionRatioThreshold
   spark.sql.subResultCache.maxBufferSize
   ```

## 使用結果片段快取時的考量
<a name="frag-caching-considerations"></a>

相較於重新運算，使用 Amazon S3 中原有快取結果所節約的成本會隨使用相同快取結果的次數而增加。若查詢使用大型資料表掃描，然後執行篩選或雜湊彙總以便將結果大小減至八分之一以下 (即輸入大小與結果之比至少為 8:1)，它們將從此功能獲益最多。輸入和結果之間的減少比率越大，成本效益越高。如果查詢的減少比率較小，但包含資料表掃描和篩選或彙總之間的昂貴運算步驟，也將從中獲益，只要產生結果的成本大於從 Amazon S3 擷取結果的成本。依預設，只有在偵測到減少比率至少為 8:1 時，結果片段快取才會產生影響。

當您的查詢重複使用快取結果，此功能的優勢將最大限度得到體現。滾動和增量時段查詢是非常好的範例。例如，對於已執行 29 天的 30 天滾動時段查詢，它只需從其原始輸入來源提取 30 分之一的目標資料，並使用過去 29 天的快取結果片段。增量時段查詢的獲益更多，因為時段的起點是固定的：每次調用查詢時，處理的較小百分比要求從輸入來源讀取。

以下是使用結果片段快取時的其他考量事項：
+ 不以具有相同查詢片段的相同資料為目標的查詢，其快取命中率較低，因此不會從此功能獲益。
+ 對於具有低減少比率且不含昂貴運算步驟的查詢，快取結果的讀取成本與初始處理它們的成本大致相當。
+ 由於寫入快取的成本，第一個查詢始終顯示輕微迴歸。
+ 結果片段快取功能僅適用於 Parquet 檔案。不支援其他檔案格式。
+ 結果片段快取功能緩衝區只會嘗試對 128 MB 或更大的檔案分割大小嘗試執行快取掃描。在使用預設的 Spark 組態時，如果掃描大小 (所有掃描檔案的大小總計) 除以執行器核心數量所得結果小於 128 MB，則結果片段快取將停用。當設定下列任一 Spark 組態時，檔案分割大小為：

  ```
  min(maxPartitionBytes, max(openCostInBytes, scan size / minPartitionNum))
  ```
  + spark.sql.leafNodeDefaultParallelism (預設值為 spark.default.parallelism)
  + spark.sql.files.minPartitionNum (預設值為 spark.sql.leafNodeDefaultParallelism)
  + spark.sql.files.openCostInBytes
  + spark.sql.files.maxPartitionBytes
+ 結果片段快取功能會以 RDD 分割區精細程度進行快取。針對每個 RDD 分割區，會使用前述預設為 8:1 的減少比率進行評估。每個 RDD 減少比率同時有大於和小於 8:1 之情形的工作負載，它們的效能提升不及每個 RDD 減少比率持續小於 8:1 的工作負載。
+ 結果片段快取功能預設為每個要快取的 RDD 分割區使用 16 MB 的寫入緩衝區。若每個 RDD 分割區要快取的大小超過 16 MB，判斷寫入不可行的成本可能引發效能迴歸。
+ 雖然依預設，結果片段快取不會嘗試快取減少比率小於 8:1 的 RDD 分割區結果，並且將其寫入緩衝區上限設為 16 MB，但可透過以下組態調整這兩個值。

  ```
  spark.sql.subResultCache.reductionRatioThreshold (default: 8.0)
  spark.sql.subResultCache.maxBufferSize (default: 16MB, max: 64MB)
  ```
+ 使用相同 Amazon EMR 版本的多個叢集可以共用相同的快取位置。為確定結果正確性，結果片段快取不會使用由不同 Amazon EMR 版本寫入的快取結果。
+ Spark 串流使用案例或使用 RecordServer、Apache Ranger 或 AWS Lake Formation 時，結果片段快取會自動停用。
+ 結果片段快取讀取/寫入使用 EMRFS / S3A 和 Amazon S3 儲存貯體。支援 CSE （僅適用於 EMRFS)/ SSE S3/ SSE KMS 加密。針對內容，S3A 提供 Hadoop 實作，讓叢集能夠在 Amazon S3 之間讀取和寫入資料。請注意，EMR-7.4.0 及更高版本支援 S3A。

# 使用適用於 Apache Spark 的 Nvidia RAPIDS Accelerator
<a name="emr-spark-rapids"></a>

在 Amazon EMR 6.2.0 版及更高版本中，針對採用 EC2 圖形處理單元 (GPU) 執行個體類型的 Spark，您可以使用 Nvidia [適用於 Apache Spark 的 RAPIDS Accelerator](https://docs.nvidia.com/spark-rapids/user-guide/latest/overview.html) 外掛程式來加速。RAPIDS Accelerator 將透過 GPU 加快 Apache Spark 3.0 資料科學管道而無需變更程式碼，並且加快資料處理和模型訓練，同時大幅降低基礎設施成本。

下列各章節會引導您完成 EMR 叢集設定，以使用適用於 Spark 的 Spark-RAPIDS 外掛程式。

## 選擇執行個體類型
<a name="emr-spark-rapids-instancetypes"></a>

若要使用適用於 Spark 的 Spark-RAPIDS 外掛程式，核心和任務執行個體群組必須使用符合 Spark-RAPIDS [硬體要求](https://nvidia.github.io/spark-rapids/)的 EC2 GPU 執行個體類型。若要檢視 Amazon EMR 支援的 GPU 執行個體類型的完整清單，請參閱《Amazon EMR 管理指南》**中的[支援的執行個體類型](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-supported-instance-types.html)。主要執行個體群組的執行個體類型可以是 GPU 或非 GPU 類型，但不支援 ARM 執行個體類型。

## 為您的叢集設定應用程式組態
<a name="emr-spark-rapids-appconfig"></a>

**1。啟用 Amazon EMR 以便在您的新叢集上安裝外掛程式**

若要安裝外掛程式，請在建立叢集時提供以下組態：

```
{
	"Classification":"spark",
	"Properties":{
		"enableSparkRapids":"true"
	}
}
```

**2. 設定 YARN 以使用 GPU**

如需有關如何在 YARN 上使用 GPU 的詳細資訊，請參閱 Apache Hadoop 文件中的[在 YARN 上使用 GPU](https://hadoop.apache.org/docs/r3.2.1/hadoop-yarn/hadoop-yarn-site/UsingGpus.html)。下列範例顯示 Amazon EMR 6.x 和 7.x 版的 YARN 組態範例：

------
#### [ Amazon EMR 7.x ]

**Amazon EMR 7.x 的 YARN 組態範例**

```
{
    "Classification":"yarn-site",
    "Properties":{
        "yarn.nodemanager.resource-plugins":"yarn.io/gpu",
        "yarn.resource-types":"yarn.io/gpu",
        "yarn.nodemanager.resource-plugins.gpu.allowed-gpu-devices":"auto",
        "yarn.nodemanager.resource-plugins.gpu.path-to-discovery-executables":"/usr/bin",
        "yarn.nodemanager.linux-container-executor.cgroups.mount":"true",
        "yarn.nodemanager.linux-container-executor.cgroups.mount-path":"/spark-rapids-cgroup",
        "yarn.nodemanager.linux-container-executor.cgroups.hierarchy":"yarn",
        "yarn.nodemanager.container-executor.class":"org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor"
    }
},{
    "Classification":"container-executor",
    "Properties":{
        
    },
    "Configurations":[
        {
            "Classification":"gpu",
            "Properties":{
                "module.enabled":"true"
            }
        },
        {
            "Classification":"cgroups",
            "Properties":{
                "root":"/spark-rapids-cgroup",
                "yarn-hierarchy":"yarn"
            }
        }
    ]
}
```

------
#### [ Amazon EMR 6.x ]

**Amazon EMR 6.x 的 YARN 組態範例**

```
{
    "Classification":"yarn-site",
    "Properties":{
        "yarn.nodemanager.resource-plugins":"yarn.io/gpu",
        "yarn.resource-types":"yarn.io/gpu",
        "yarn.nodemanager.resource-plugins.gpu.allowed-gpu-devices":"auto",
        "yarn.nodemanager.resource-plugins.gpu.path-to-discovery-executables":"/usr/bin",
        "yarn.nodemanager.linux-container-executor.cgroups.mount":"true",
        "yarn.nodemanager.linux-container-executor.cgroups.mount-path":"/sys/fs/cgroup",
        "yarn.nodemanager.linux-container-executor.cgroups.hierarchy":"yarn",
        "yarn.nodemanager.container-executor.class":"org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor"
    }
},{
    "Classification":"container-executor",
    "Properties":{
        
    },
    "Configurations":[
        {
            "Classification":"gpu",
            "Properties":{
                "module.enabled":"true"
            }
        },
        {
            "Classification":"cgroups",
            "Properties":{
                "root":"/sys/fs/cgroup",
                "yarn-hierarchy":"yarn"
            }
        }
    ]
}
```

------

**3. 設定 Spark 以使用 RAPIDS**

以下是啟用 Spark 以使用 RAPIDS 外掛程式所需的組態：

```
{
	"Classification":"spark-defaults",
	"Properties":{
		"spark.plugins":"com.nvidia.spark.SQLPlugin",
		"spark.executor.resource.gpu.discoveryScript":"/usr/lib/spark/scripts/gpu/getGpusResources.sh",
		"spark.executor.extraLibraryPath":"/usr/local/cuda/targets/x86_64-linux/lib:/usr/local/cuda/extras/CUPTI/lib64:/usr/local/cuda/compat/lib:/usr/local/cuda/lib:/usr/local/cuda/lib64:/usr/lib/hadoop/lib/native:/usr/lib/hadoop-lzo/lib/native:/docker/usr/lib/hadoop/lib/native:/docker/usr/lib/hadoop-lzo/lib/native"
	}
}
```

當在您的叢集上啟用 Spark RAPIDS 外掛程式時，也可使用 XGBoost 文件中的 [XGBoost4J-Spark 程式庫](https://xgboost.readthedocs.io/en/latest/jvm/xgboost4j_spark_tutorial.html)。您可以使用以下組態將 XGBoost 與您的 Spark 作業整合：

```
{
	"Classification":"spark-defaults",
	"Properties":{
		"spark.submit.pyFiles":"/usr/lib/spark/jars/xgboost4j-spark_3.0-1.4.2-0.3.0.jar"
	}
}
```

如需了解您可以用於微調 GPU 加速 EMR 叢集的更多 Spark 組態，請參閱 Nvidia.github.io 文件中的[《Rapids Accelerator for Apache Spark 調校指南》](https://docs.nvidia.com/spark-rapids/user-guide/latest/tuning-guide.html)。

**4. 設定 YARN 容量排程器**

`DominantResourceCalculator` 必須設定為啟用 GPU 排程和隔離。如需詳細資訊，請參閱 Apache Hadoop 文件中的[在 YARN 上使用 GPU](https://hadoop.apache.org/docs/r3.2.1/hadoop-yarn/hadoop-yarn-site/UsingGpus.html)。

```
{
	"Classification":"capacity-scheduler",
	"Properties":{
		"yarn.scheduler.capacity.resource-calculator":"org.apache.hadoop.yarn.util.resource.DominantResourceCalculator"
	}
}
```

**5. 建立 JSON 檔案以包含您的組態**

您可以建立 JSON 檔案，其中包含將 RAPIDS 外掛程式用於 Spark 叢集的組態。您要在稍後啟動叢集時提供該檔案。

您可以將檔案存放在本機或 S3 上。如需如何為您的叢集提供應用程式組態的詳細資訊，請參閱 [設定應用程式](emr-configure-apps.md)。

使用下列範例檔案作為範本來建立您的組態。

------
#### [ Amazon EMR 7.x ]

**Amazon EMR 7.x 的 `my-configurations.json` 檔案範例**

```
[
    {
        "Classification":"spark",
        "Properties":{
            "enableSparkRapids":"true"
        }
    },
    {
        "Classification":"yarn-site",
        "Properties":{
            "yarn.nodemanager.resource-plugins":"yarn.io/gpu",
            "yarn.resource-types":"yarn.io/gpu",
            "yarn.nodemanager.resource-plugins.gpu.allowed-gpu-devices":"auto",
            "yarn.nodemanager.resource-plugins.gpu.path-to-discovery-executables":"/usr/bin",
            "yarn.nodemanager.linux-container-executor.cgroups.mount":"true",
            "yarn.nodemanager.linux-container-executor.cgroups.mount-path":"/spark-rapids-cgroup",
            "yarn.nodemanager.linux-container-executor.cgroups.hierarchy":"yarn",
            "yarn.nodemanager.container-executor.class":"org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor"
        }
    },
    {
        "Classification":"container-executor",
        "Properties":{
            
        },
        "Configurations":[
            {
                "Classification":"gpu",
                "Properties":{
                    "module.enabled":"true"
                }
            },
            {
                "Classification":"cgroups",
                "Properties":{
                    "root":"/spark-rapids-cgroup",
                    "yarn-hierarchy":"yarn"
                }
            }
        ]
    },
    {
        "Classification":"spark-defaults",
        "Properties":{
            "spark.plugins":"com.nvidia.spark.SQLPlugin",
            "spark.executor.resource.gpu.discoveryScript":"/usr/lib/spark/scripts/gpu/getGpusResources.sh",
            "spark.executor.extraLibraryPath":"/usr/local/cuda/targets/x86_64-linux/lib:/usr/local/cuda/extras/CUPTI/lib64:/usr/local/cuda/compat/lib:/usr/local/cuda/lib:/usr/local/cuda/lib64:/usr/lib/hadoop/lib/native:/usr/lib/hadoop-lzo/lib/native:/docker/usr/lib/hadoop/lib/native:/docker/usr/lib/hadoop-lzo/lib/native",
            "spark.submit.pyFiles":"/usr/lib/spark/jars/xgboost4j-spark_3.0-1.4.2-0.3.0.jar",
            "spark.rapids.sql.concurrentGpuTasks":"1",
            "spark.executor.resource.gpu.amount":"1",
            "spark.executor.cores":"2",
            "spark.task.cpus":"1",
            "spark.task.resource.gpu.amount":"0.5",
            "spark.rapids.memory.pinnedPool.size":"0",
            "spark.executor.memoryOverhead":"2G",
            "spark.locality.wait":"0s",
            "spark.sql.shuffle.partitions":"200",
            "spark.sql.files.maxPartitionBytes":"512m"
        }
    },
    {
        "Classification":"capacity-scheduler",
        "Properties":{
            "yarn.scheduler.capacity.resource-calculator":"org.apache.hadoop.yarn.util.resource.DominantResourceCalculator"
        }
    }
]
```

------
#### [ Amazon EMR 6.x ]

**Amazon EMR 6.x 的 `my-configurations.json` 檔案範例**

```
[
    {
        "Classification":"spark",
        "Properties":{
            "enableSparkRapids":"true"
        }
    },
    {
        "Classification":"yarn-site",
        "Properties":{
            "yarn.nodemanager.resource-plugins":"yarn.io/gpu",
            "yarn.resource-types":"yarn.io/gpu",
            "yarn.nodemanager.resource-plugins.gpu.allowed-gpu-devices":"auto",
            "yarn.nodemanager.resource-plugins.gpu.path-to-discovery-executables":"/usr/bin",
            "yarn.nodemanager.linux-container-executor.cgroups.mount":"true",
            "yarn.nodemanager.linux-container-executor.cgroups.mount-path":"/sys/fs/cgroup",
            "yarn.nodemanager.linux-container-executor.cgroups.hierarchy":"yarn",
            "yarn.nodemanager.container-executor.class":"org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor"
        }
    },
    {
        "Classification":"container-executor",
        "Properties":{
            
        },
        "Configurations":[
            {
                "Classification":"gpu",
                "Properties":{
                    "module.enabled":"true"
                }
            },
            {
                "Classification":"cgroups",
                "Properties":{
                    "root":"/sys/fs/cgroup",
                    "yarn-hierarchy":"yarn"
                }
            }
        ]
    },
    {
        "Classification":"spark-defaults",
        "Properties":{
            "spark.plugins":"com.nvidia.spark.SQLPlugin",
            "spark.executor.resource.gpu.discoveryScript":"/usr/lib/spark/scripts/gpu/getGpusResources.sh",
            "spark.executor.extraLibraryPath":"/usr/local/cuda/targets/x86_64-linux/lib:/usr/local/cuda/extras/CUPTI/lib64:/usr/local/cuda/compat/lib:/usr/local/cuda/lib:/usr/local/cuda/lib64:/usr/lib/hadoop/lib/native:/usr/lib/hadoop-lzo/lib/native:/docker/usr/lib/hadoop/lib/native:/docker/usr/lib/hadoop-lzo/lib/native",
            "spark.submit.pyFiles":"/usr/lib/spark/jars/xgboost4j-spark_3.0-1.4.2-0.3.0.jar",
            "spark.rapids.sql.concurrentGpuTasks":"1",
            "spark.executor.resource.gpu.amount":"1",
            "spark.executor.cores":"2",
            "spark.task.cpus":"1",
            "spark.task.resource.gpu.amount":"0.5",
            "spark.rapids.memory.pinnedPool.size":"0",
            "spark.executor.memoryOverhead":"2G",
            "spark.locality.wait":"0s",
            "spark.sql.shuffle.partitions":"200",
            "spark.sql.files.maxPartitionBytes":"512m"
        }
    },
    {
        "Classification":"capacity-scheduler",
        "Properties":{
            "yarn.scheduler.capacity.resource-calculator":"org.apache.hadoop.yarn.util.resource.DominantResourceCalculator"
        }
    }
]
```

------

## 為您的叢集新增引導操作
<a name="emr-spark-rapids-bootstrap"></a>

如需有關如何在建立叢集時提供引導動作指令碼的詳細資訊，請參閱《Amazon EMR 管理指南》**中的[引導動作基本概念](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-bootstrap.html#bootstrapUses)。

下列範例指令碼說明如何為 Amazon EMR 6.x 和 7.x 建立引導動作檔案：

------
#### [ Amazon EMR 7.x ]

**Amazon EMR 7.x 的 `my-bootstrap-action.sh` 檔案範例**

若要使用 YARN 管理使用 Amazon EMR 7.x 版的 GPU 資源，您必須將 CGroup v1 手動掛載到叢集。如此範例所示，您可以使用引導動作指令碼來執行此操作。

```
#!/bin/bash
set -ex
 
sudo mkdir -p /spark-rapids-cgroup/devices
sudo mount -t cgroup -o devices cgroupv1-devices /spark-rapids-cgroup/devices
sudo chmod a+rwx -R /spark-rapids-cgroup
```

------
#### [ Amazon EMR 6.x ]

**Amazon EMR 6.x 的 `my-bootstrap-action.sh` 檔案範例**

對於 Amazon EMR 6.x 版，您必須在叢集上開啟 YARN 的 CGroup 許可。如此範例所示，您可以使用引導動作指令碼來執行此操作。

```
#!/bin/bash
set -ex
 
sudo chmod a+rwx -R /sys/fs/cgroup/cpu,cpuacct
sudo chmod a+rwx -R /sys/fs/cgroup/devices
```

------

## 啟動您的叢集
<a name="emr-spark-rapids-launchcluster"></a>

最後一個步驟是使用上述叢集組態來啟動您的叢集。以下是透過 Amazon EMR CLI 啟動叢集的範例命令：

```
 aws emr create-cluster \
--release-label emr-7.12.0 \
--applications Name=Hadoop Name=Spark \
--service-role EMR_DefaultRole_V2 \
--ec2-attributes KeyName=my-key-pair,InstanceProfile=EMR_EC2_DefaultRole \
--instance-groups InstanceGroupType=MASTER,InstanceCount=1,InstanceType=m4.4xlarge \                 
                  InstanceGroupType=CORE,InstanceCount=1,InstanceType=g4dn.2xlarge \    
                  InstanceGroupType=TASK,InstanceCount=1,InstanceType=g4dn.2xlarge \
--configurations file:///my-configurations.json \
--bootstrap-actions Name='My Spark Rapids Bootstrap action',Path=s3://amzn-s3-demo-bucket/my-bootstrap-action.sh
```

# 存取 Spark Shell
<a name="emr-spark-shell"></a>

Spark Shell 以 Scala REPL (Read-Eval-Print-Loop) 為基礎。這可讓您以互動的方式建立 Spark 程式，並將工作提交至架構。您可以透過使用 SSH 連接到主節點並調用 `spark-shell` 來存取 Spark Shell。有關如何連線到主節點的詳細資訊，請參閱《Amazon EMR 管理指南》**中的[使用 SSH 連線至主節點](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-connect-master-node-ssh.html)。以下範例使用在 Amazon S3 中存放的 Apache HTTP 伺服器存取日誌。

**注意**  
可存取美國東部 (維吉尼亞北部) 的用戶端可使用這些範例中的儲存貯體。

 在預設情況下，Spark shell 會建立名為 `sc` 的自己的 [SparkContext](https://spark.apache.org/docs/1.3.1/api/scala/index.html#org.apache.spark.SparkContext) 物件。如果此內容在 REPL 中為必要，則您可以使用此內容。sqlContext 在 shell 中也有提供，且其為 [HiveContext](https://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.sql.hive.HiveContext)。

**Example 使用 Spark Shell 來計算在 Amazon S3 中存放之檔案中某字串的出現次數**  
此範例使用 `sc` 讀取 Amazon S3 中存放的文字檔案。  

```
scala> sc
res0: org.apache.spark.SparkContext = org.apache.spark.SparkContext@404721db

scala> val textFile = sc.textFile("s3://elasticmapreduce/samples/hive-ads/tables/impressions/dt=2009-04-13-08-05/ec2-0-51-75-39.amazon.com.rproxy.govskope.us-2009-04-13-08-05.log")
```
Spark 會建立 textFile 且與[資料結構](https://spark.apache.org/docs/latest/programming-guide.html#resilient-distributed-datasets-rdds)建立關聯。接著，範例會計算日誌檔中含字串「cartoonnetwork.com」的行數量：  

```
scala> val linesWithCartoonNetwork = textFile.filter(line => line.contains("cartoonnetwork.com")).count()
linesWithCartoonNetwork: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[2] at filter at <console>:23
<snip>
<Spark program runs>
scala> linesWithCartoonNetwork
res2: Long = 9
```

**Example 使用 Python 型 Spark shell 來計算在 Amazon S3 中存放之檔案中某字串的出現次數**  
Spark 還包含以 Python 為基礎的 shell、`pyspark`，您可以使用該 shell 來開發以 Python 撰寫之 Spark 程式的原型。如同使用 `spark-shell`，在主節點上調用 `pyspark`；它也有相同的 [SparkContext](https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.SparkContext.html#pyspark.SparkContext) 物件。  

```
>>> sc
<pyspark.context.SparkContext object at 0x7fe7e659fa50>
>>> textfile = sc.textFile("s3://elasticmapreduce/samples/hive-ads/tables/impressions/dt=2009-04-13-08-05/ec2-0-51-75-39.amazon.com.rproxy.govskope.us-2009-04-13-08-05.log")
```
Spark 會建立 textFile 且與[資料結構](https://spark.apache.org/docs/latest/programming-guide.html#resilient-distributed-datasets-rdds)建立關聯。接著，範例會計算日誌檔中含字串「cartoonnetwork.com」的行數量。  

```
>>> linesWithCartoonNetwork = textfile.filter(lambda line: "cartoonnetwork.com" in line).count()
15/06/04 17:12:22 INFO lzo.GPLNativeCodeLoader: Loaded native gpl library from the embedded binaries
15/06/04 17:12:22 INFO lzo.LzoCodec: Successfully loaded & initialized native-lzo library [hadoop-lzo rev EXAMPLE]
15/06/04 17:12:23 INFO fs.EmrFileSystem: Consistency disabled, using com.amazon.ws.emr.hadoop.fs.s3n.S3NativeFileSystem as filesystem implementation
<snip>
<Spark program continues>
>>> linesWithCartoonNetwork
9
```

# 使用適用於機器學習的 Amazon SageMaker Spark
<a name="emr-spark-sagemaker"></a>

使用 Amazon EMR 5.11.0 版和更高版本時，會同時安裝 `aws-sagemaker-spark-sdk` 元件和 Spark。此元件會安裝 Amazon SageMaker Spark 以及讓 Spark 與 [Amazon SageMaker](https://aws.amazon.com/sagemaker/) 整合的相關依存項目建立關聯。請注意，該`aws-sagemaker-spark-sdk`元件不適用於 Amazon EMR 7.x 及更高版本。您可使用 Amazon SageMaker Spark，以 Amazon SageMaker 階段建構 Spark Machine Learning (ML) 管道。如需詳細資訊，請參閱 GitHub 上的 [Amazon SageMaker Spark 讀我檔案](https://github.com/aws/sagemaker-spark/blob/master/README.md)以及《Amazon SageMaker 開發人員指南》**中的[使用 Amazon SageMaker 搭配 Apache Spark](https://docs.aws.amazon.com/sagemaker/latest/dg/apache-spark.html)。

# 撰寫 Spark 應用程式
<a name="emr-spark-application"></a>

可以使用 Scala、Java 或 Python 來撰寫 [Spark](https://aws.amazon.com/big-data/what-is-spark/) 應用程式。在 Apache Spark 文件的 [Spark 範例](https://spark.apache.org/examples.html)主題中有幾個 Spark 應用程式的範例。估算 Pi 的範例就如在三個原生支援應用程式中所示。您也可以在 `$SPARK_HOME/examples` 並在 [GitHub](https://github.com/apache/spark/tree/master/examples/src/main) 中檢視完整的範例。如需有關如何為 Spark 建置 JAR 的詳細資訊，請參閱 Apache Spark 文件中的[快速入門](https://spark.apache.org/docs/latest/quick-start.html)主題。

## Scala
<a name="emr-spark-application-scala"></a>

為了避免出現 Scala 相容性問題，建議您在為 Amazon EMR 叢集編譯 Spark 應用程式時，對正確的 Scala 版本使用 Spark 相依性。您應該使用的 Scala 版本取決於您的叢集上安裝的 Spark 版本。例如，Amazon EMR 5.30.1 版使用 Spark 2.4.5，它是使用 Scala 2.11 建置的。如果您的叢集使用 Amazon EMR 5.30.1 版，請對 Scala 2.11 使用 Spark 相依性。如需有關 Spark 使用之 Scala 版本的詳細資訊，請參閱 [Apache Spark 文件](https://spark.apache.org/documentation.html)。

```
package org.apache.spark.examples
import scala.math.random
import org.apache.spark._

/** Computes an approximation to pi */
object SparkPi {
  def main(args: Array[String]) {
    val conf = new SparkConf().setAppName("Spark Pi")
    val spark = new SparkContext(conf)
    val slices = if (args.length > 0) args(0).toInt else 2
    val n = math.min(100000L * slices, Int.MaxValue).toInt // avoid overflow
    val count = spark.parallelize(1 until n, slices).map { i =>
      val x = random * 2 - 1
      val y = random * 2 - 1
      if (x*x + y*y < 1) 1 else 0
    }.reduce(_ + _)
    println("Pi is roughly " + 4.0 * count / n)
    spark.stop()
  }
}
```

## Java
<a name="emr-spark-application-java"></a>

```
package org.apache.spark.examples;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.api.java.function.Function2;

import java.util.ArrayList;
import java.util.List;

/** 
 * Computes an approximation to pi
 * Usage: JavaSparkPi [slices]
 */
public final class JavaSparkPi {

  public static void main(String[] args) throws Exception {
    SparkConf sparkConf = new SparkConf().setAppName("JavaSparkPi");
    JavaSparkContext jsc = new JavaSparkContext(sparkConf);

    int slices = (args.length == 1) ? Integer.parseInt(args[0]) : 2;
    int n = 100000 * slices;
    List<Integer> l = new ArrayList<Integer>(n);
    for (int i = 0; i < n; i++) {
      l.add(i);
    }

    JavaRDD<Integer> dataSet = jsc.parallelize(l, slices);

    int count = dataSet.map(new Function<Integer, Integer>() {
      @Override
      public Integer call(Integer integer) {
        double x = Math.random() * 2 - 1;
        double y = Math.random() * 2 - 1;
        return (x * x + y * y < 1) ? 1 : 0;
      }
    }).reduce(new Function2<Integer, Integer, Integer>() {
      @Override
      public Integer call(Integer integer, Integer integer2) {
        return integer + integer2;
      }
    });

    System.out.println("Pi is roughly " + 4.0 * count / n);

    jsc.stop();
  }
}
```

## Python
<a name="emr-spark-application-spark27"></a>

```
import argparse
import logging
from operator import add
from random import random

from pyspark.sql import SparkSession

logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")


def calculate_pi(partitions, output_uri):
    """
    Calculates pi by testing a large number of random numbers against a unit circle
    inscribed inside a square. The trials are partitioned so they can be run in
    parallel on cluster instances.

    :param partitions: The number of partitions to use for the calculation.
    :param output_uri: The URI where the output is written, typically an Amazon S3
                       bucket, such as 's3://example-bucket/pi-calc'.
    """

    def calculate_hit(_):
        x = random() * 2 - 1
        y = random() * 2 - 1
        return 1 if x**2 + y**2 < 1 else 0

    tries = 100000 * partitions
    logger.info(
        "Calculating pi with a total of %s tries in %s partitions.", tries, partitions
    )
    with SparkSession.builder.appName("My PyPi").getOrCreate() as spark:
        hits = (
            spark.sparkContext.parallelize(range(tries), partitions)
            .map(calculate_hit)
            .reduce(add)
        )
        pi = 4.0 * hits / tries
        logger.info("%s tries and %s hits gives pi estimate of %s.", tries, hits, pi)
        if output_uri is not None:
            df = spark.createDataFrame([(tries, hits, pi)], ["tries", "hits", "pi"])
            df.write.mode("overwrite").json(output_uri)


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--partitions",
        default=2,
        type=int,
        help="The number of parallel partitions to use when calculating pi.",
    )
    parser.add_argument(
        "--output_uri", help="The URI where output is saved, typically an S3 bucket."
    )
    args = parser.parse_args()

    calculate_pi(args.partitions, args.output_uri)
```

# 使用 Amazon S3 提升 Spark 效能
<a name="emr-spark-s3-performance"></a>

Amazon EMR 提供的功能，可在使用 Spark 查詢、讀取和寫入儲存於 Amazon S3 的資料時協助使效能優化。

[S3 Select](https://aws.amazon.com/blogs/aws/s3-glacier-select/) 可藉由將處理「下推」至 Amazon S3 改善某些應用程式中 CSV 和 JSON 檔案的查詢效能。

EMRFS S3-optimized遞交者是 [OutputCommitter](https://hadoop.apache.org/docs/current/api/org/apache/hadoop/mapreduce/OutputCommitter.html) 類別的替代方案，其使用 EMRFS 的分段上傳功能來改善使用 Spark、DataFrames 和資料集將 Parquet 檔案寫入 Amazon S3 時的效能。

**Topics**
+ [使用 S3 Select 搭配 Spark 以提升查詢效能](emr-spark-s3select.md)
+ [EMR Spark MagicCommitProtocol](emr-spark-magic-commit-protocol.md)
+ [使用 EMRFS S3 優化遞交者](emr-spark-s3-optimized-committer.md)
+ [使用 EMRFS S3 優化遞交通訊協定](emr-spark-s3-optimized-commit-protocol.md)
+ [使用 EMRFS 的重試 Amazon S3 請求](emr-spark-emrfs-retry.md)

# 使用 S3 Select 搭配 Spark 以提升查詢效能
<a name="emr-spark-s3select"></a>

**重要**  
Amazon S3 Select 不再提供給新客戶。Amazon S3 Select 的現有客戶可以繼續照常使用此功能。[進一步了解](https://aws.amazon.com/blogs/storage/how-to-optimize-querying-your-data-in-amazon-s3/) 

在 Amazon EMR 5.17.0 版及更高版本中，您可以將 [S3 Select](https://aws.amazon.com/blogs/aws/s3-glacier-select/) 與 Amazon EMR 上的 Spark 搭配使用。*S3 Select* 可讓應用程式從物件只擷取資料子集。針對 Amazon EMR，篩選大型資料集以進行處理的運算工作，會從叢集「下推」到 Amazon S3 處理，因而在某些應用程式中可改善效能，並減少 Amazon EMR 和 Amazon S3 之間傳輸的資料量。

S3 Select 支援使用 `s3selectCSV` 和 `s3selectJSON` 值指定資料格式的 CSV 和 JSON 檔案。如需詳細資訊和範例，請參閱 [在您的程式碼中指定 S3 Select](#emr-spark-s3select-specify)。

## S3 Select 是否適合我的應用程式？
<a name="emr-spark-s3select-apps"></a>

建議您在使用和不使用 S3 Select 的狀態下，對應用程式進行基準分析，以確認其是否適合您的應用程式。

利用下列的準則，來判斷您的應用程式是否可能使用 S3 Select：
+ 您的查詢會篩選掉原始資料集一半以上的資料。
+ Amazon S3 與 Amazon EMR 叢集之間的網路連線具有良好的傳輸速度和可用頻寬。Amazon S3 不會壓縮 HTTP 回應，因此所壓縮輸入檔案的回應大小可能會增加。

## 考量和限制
<a name="emr-spark-s3select-considerations"></a>
+ 不支援使用客戶所提供加密金鑰 (SSE-C) 的 Amazon S3 伺服器端加密，也不支援用戶端加密。
+ 不支援 `AllowQuotedRecordDelimiters` 屬性。如果指定此屬性，查詢會失敗。
+ 僅支援採用 UTF-8 格式的 CSV 和 JSON 檔案。不支援多行 CSV。
+ 僅支援未壓縮的檔案或 gzip 檔案。
+ 不支援 Spark CSV 和 JSON 選項 (例如 `nanValue`、`positiveInf`、`negativeInf`) 以及與損毀記錄有關的選項 (例如 failfast 和 dropmalformed 模式)。
+ 不支援在十進位使用逗號 (,)。例如，不支援 `10,000` 但支援 `10000`。
+ 不支援在最後一行的註解字元。
+ 不會處理檔案尾端的空白行。
+ 以下篩選條件不會下推至 Amazon S3：
  + 彙總函數，例如 `COUNT()` 和 `SUM()`。
  + `CAST()` 屬性的篩選條件。例如 `CAST(stringColumn as INT) = 1`。
  + 含屬性的篩選條件為物件或很複雜。例如 `intArray[1] = 1, objectColumn.objectNumber = 1`。
  + 篩選條件的值不是常值。例如 `intColumn1 = intColumn2`
  + 僅在載明限制的情況下支援 [S3 Select 支援的資料類型](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-glacier-select-sql-reference-data-types.html)。

## 在您的程式碼中指定 S3 Select
<a name="emr-spark-s3select-specify"></a>

以下範例示範如何使用 Scala、SQL、R 和 PySpark 指定適用於 CSV 的 S3 Select。您可透過相同方式使用適用於 JSON 的 S3 Select。如需了解選項清單、其預設值和限制，請參閱 [選項](#emr-spark-s3select-specify-options)。

------
#### [ PySpark ]

```
spark
  .read
  .format("s3selectCSV") // "s3selectJson" for Json
  .schema(...) // optional, but recommended
  .options(...) // optional
  .load("s3://path/to/my/datafiles")
```

------
#### [ R ]

```
read.df("s3://path/to/my/datafiles", "s3selectCSV", schema, header = "true", delimiter = "\t")
```

------
#### [ Scala ]

```
spark
  .read
  .format("s3selectCSV") // "s3selectJson" for Json
  .schema(...) // optional, but recommended
  .options(...) // optional. Examples:  
  // .options(Map("quote" -> "\'", "header" -> "true")) or
  // .option("quote", "\'").option("header", "true")
  .load("s3://path/to/my/datafiles")
```

------
#### [ SQL ]

```
CREATE TEMPORARY VIEW MyView (number INT, name STRING) USING s3selectCSV OPTIONS (path "s3://path/to/my/datafiles", header "true", delimiter "\t")
```

------

### 選項
<a name="emr-spark-s3select-specify-options"></a>

使用 `s3selectCSV` 和 `s3selectJSON` 時，有以下可用選項。若未指定，則會使用預設值。

#### S3selectCSV 的選項
<a name="emr-spark-s3select-specify-options-csv"></a>


| 選項 | 預設 | Usage | 
| --- | --- | --- | 
|  `compression`  |  `"none"`  |  指出是否使用了壓縮。`"gzip"` 是除了 `"none"` 之外唯一支援的設定。  | 
|  `delimiter`  |  ","  |  指定欄位分隔符號。  | 
|  `quote`  |  `'\"'`  |  指定引號字元。不支援指定空白字串，這會導致格式不正確的 XML 錯誤。  | 
|  `escape`  |  `'\\'`  |  指定逸出字元。  | 
|  `header`  |  `"false"`  |  `"false"` 指定沒有標頭。`"true"` 指定標頭位於第一行。僅支援標頭位於第一行，不支援在標頭前有空白行。  | 
|  comment  |  `"#"`  |  指定註解字元。註解指標無法停用。換言之，不支援 `\u0000` 的值。  | 
|  `nullValue`  |  ""  |    | 

#### S3selectJSON 的選項
<a name="emr-spark-s3select-specify-options-json"></a>


| 選項 | 預設 | Usage | 
| --- | --- | --- | 
|  `compression`  |  `"none"`  |  指出是否使用了壓縮。`"gzip"` 是除了 `"none"` 之外唯一支援的設定。  | 
|  `multiline`  |  "false"  |  `"false"` 指定 JSON 為 S3 Select `LINES` 格式，這表示輸入資料中的每一行都包含了單一 JSON 物件。`"true"` 指定 JSON 為 S3 Select `DOCUMENT` 格式，這表示一個 JSON 物件可在輸入資料中跨越多行。  | 

# EMR Spark MagicCommitProtocol
<a name="emr-spark-magic-commit-protocol"></a>

從 EMR 6.15.0 之後，使用 S3A 檔案系統時，MagicCommitProtocol 會成為 Spark 的預設 FileCommitProtocol。

## MagicCommitProtocol
<a name="magic-commit-protocol"></a>

MagicCommitProtocol 是 [FileCommitProtocol](https://dlcdn.apache.org/spark/docs/2.4.2/api/java/org/apache/spark/internal/io/FileCommitProtocol.html) 的替代實作，已針對使用 Amazon S3 S3A 進行最佳化。此通訊協定旨在透過避免在任務和任務遞交階段期間在 Amazon S3 中使用重新命名操作來改善應用程式效能。

MagicCommitProtocol 是使用 S3A 檔案系統時，在 Amazon Elastic Map Reduce (EMR) 上執行的 Spark 使用的預設 FileCommitProtocol 實作。MagicCommitProtocol 在內部使用 [MagicV2Committer ](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/s3a-magicv2-committer.html) 執行檔案寫入 Amazon S3。

對於靜態插入操作，MagicCommitProtocol 在任務遞交階段將檔案寫入任務的輸出位置。相反地，對於動態插入覆寫操作，任務嘗試寫入的檔案只會在任務遞交時出現在任務的輸出位置。這可透過在任務遞交呼叫時將遞交中繼資料匯出回 Spark 驅動程式來實現。

## 啟用 MagicCommitProtocol
<a name="enabling-magic-commit-protocol"></a>

使用 S3A 檔案系統時，在 Amazon Elastic Map Reduce (EMR) 上執行的 Spark 預設會啟用 MagicCommitProtocol。

若要使用 S3A 檔案系統，您可以：

1. 使用定義資料表、分割區或目錄`s3a://`時所用的檔案配置。

1. 在 core-site.xml `fs.s3.impl=org.apache.hadoop.fs.s3a.S3AFileSystem`中設定組態。

## 停用 MagicCommitProtocol
<a name="disabling-magic-commit-protocol"></a>

1. 您可以透過在 中對其進行硬式編碼`SparkConf`、在 Spark shell 或 `spark-submit`和 `spark-sql`工具中將其作為`--conf`參數傳遞，或在 中將其`spark.sql.execution.datasources.SQLEmrOptimizedCommitProtocol.leverageMagicCommitProtocol`設定為 false`conf/spark-defaults.conf`。如需詳細資訊，請參閱 Apache [Spark 文件中的 Spark 組態](https://spark.apache.org/docs/latest/configuration.html)。

   下列範例示範如何在執行`spark-sql`命令時停用 MagicCommitProtocol。

   ```
   spark-sql \
     --conf spark.sql.execution.datasources.SQLEmrOptimizedCommitProtocol.leverageMagicCommitProtocol=false \
   -e "INSERT OVERWRITE TABLE target_table SELECT * FROM source_table;"
   ```

1. 使用`spark-defaults`組態分類將 `spark.sql.execution.datasources.SQLEmrOptimizedCommitProtocol.leverageMagicCommitProtocol` 屬性設定為 false。如需詳細資訊，請參閱[設定應用程式](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-configure-apps.html)。

## MagicCommitProtocol 考量事項
<a name="magic-commit-considerations"></a>
+ 對於靜態分割區插入，在 Spark 執行器上，MagicCommitProtocol 會對任務嘗試寫入的每個檔案耗用少量記憶體，直到任務遞交或中止為止。在大多數任務中，記憶體的消耗量極少。Spark 驅動程式沒有額外的記憶體需求
+ 對於動態分割區插入，在 Spark 驅動程式上，MagicCommitProtocol 需要記憶體來存放每個遞交檔案的中繼資料資訊，直到任務遞交或中止為止。在大多數作業中，會忽略預設 Spark 驅動程式記憶體設定。

  對於具有寫入大量檔案之長時間執行任務的作業，遞交通訊協定耗用的記憶體量可能會很明顯，並需要調整配置給 Spark，特別是 Spark 執行器的記憶體。您可以使用 `spark.driver.memory` 屬性調整 Spark 驅動程式的記憶體，或使用 `spark.executor.memory` 屬性調整 Spark 執行器的記憶體。作為準則，撰寫 100，000 個檔案的單一任務通常需要額外的 200MB 記憶體。如需詳細資訊，請參閱 Apache Spark 組態文件中的[應用程式屬性](https://spark.apache.org/docs/latest/configuration.html#application-properties)。

# 使用 EMRFS S3 優化遞交者
<a name="emr-spark-s3-optimized-committer"></a>

EMRFS S3 優化遞交者是 [OutputCommitter](https://hadoop.apache.org/docs/current/api/org/apache/hadoop/mapreduce/OutputCommitter.html) 實作的替代方案，針對使用 EMRFS 時寫入檔案至 Amazon S3 的操作優化。EMRFS S3 優化遞交者透過避免在作業和任務遞交階段於 Amazon S3 執行清單和重新命名操作，藉此提升應用程式效能。遞交者在 Amazon EMR 5.19.0 版和更高版本中提供，並在 Amazon EMR 5.20.0 和更高版本預設為啟用。遞交者用於使用 Spark、DataFrames或資料集的 Spark 任務。從 Amazon EMR 6.4.0 開始，此遞交者可用於所有常見格式，包括 parquet、ORC 和文字類型格式 (例如 CSV 和 JSON)。對於 Amazon EMR 6.4.0 之前的版本，僅支援 Parquet 格式。在某些情況下將不會使用遞交者。如需詳細資訊，請參閱[EMRFS S3 優化遞交者要求](emr-spark-committer-reqs.md)。

**Topics**
+ [EMRFS S3 優化遞交者要求](emr-spark-committer-reqs.md)
+ [EMRFS S3 優化遞交者和分段上傳](emr-spark-committer-multipart.md)
+ [作業調校考量](emr-spark-committer-tuning.md)
+ [為 Amazon EMR 5.19.0 啟用 EMRFS S3 優化遞交者](emr-spark-committer-enable.md)

# EMRFS S3 優化遞交者要求
<a name="emr-spark-committer-reqs"></a>

符合下列條件時會使用 EMRFS S3 最交化遞交者：
+ 您可以執行使用 Spark、DataFrames或資料集將檔案寫入 Amazon S3 的 Spark 任務。從 Amazon EMR 6.4.0 開始，此遞交者可用於所有常見格式，包括 parquet、ORC 和文字類型格式 (例如 CSV 和 JSON)。對於 Amazon EMR 6.4.0 之前的版本，僅支援 Parquet 格式。
+ 分段上傳會於 Amazon EMR 中啟用。這是預設值。如需詳細資訊，請參閱[EMRFS S3 優化遞交者和分段上傳](emr-spark-committer-multipart.md)。
+ 使用 Spark 的內置檔案格式支援。在以下情況會使用內建的檔案格式支援：
  + 對於 Hive 中繼存放區資料表，當使用 Amazon EMR 6.4.0 或更高版本將 Parquet 資料表的 `spark.sql.hive.convertMetastoreParquet` 設定為 `true`，或將 Orc 資料表的 `spark.sql.hive.convertMetastoreOrc` 設定為 `true` 時。這些是預設設定。
  + 當作業寫入至檔案格式資料來源或資料表時，例如使用 `USING parquet` 子句建立目標資料表時。
  + 當任務寫入至未分割 Hive 中繼存放區 Parquet 資料表時。已知限制是 Spark 的內建 Parquet 支援並不支援已分割的 Hive 資料表。如需詳細資訊，請參閱《Apache Spark、DataFrames 和資料集指南》中的 [Hive 中繼存放區 Parquet 資料表轉換](https://spark.apache.org/docs/latest/sql-data-sources-parquet.html#hive-metastore-parquet-table-conversion)。
+ 寫入至預設分割區位置 Spark 作業操作，例如 `${table_location}/k1=v1/k2=v2/`，使用遞交者。如果作業操作寫入至自訂分割區位置，則不使用遞交者，例如使用 `ALTER TABLE SQL` 命令設定自訂分割區位置。
+ 必須使用下列用於 Spark 的值：
  + `spark.sql.parquet.fs.optimized.committer.optimization-enabled` 屬性必須設為 `true`。這是 Amazon EMR 5.20.0 和更高版本的預設設定。若使用 Amazon EMR 5.19.0，預設值為 `false`。如需如何設定此值的詳細資訊，請參閱 [為 Amazon EMR 5.19.0 啟用 EMRFS S3 優化遞交者](emr-spark-committer-enable.md)。
  + 如果寫入至非分割的 Hive 中繼存放區資料表，則僅支援 Parquet 和 Orc 檔案格式。`true`如果寫入至非分割的 Parquet Hive 中繼存放區資料表，`spark.sql.hive.convertMetastoreParquet`則必須將 設定為 。`true`如果寫入至非分割的 Orc Hive 中繼存放區資料表，`spark.sql.hive.convertMetastoreOrc`則必須將 設定為 。這些是預設設定。
  + `spark.sql.parquet.output.committer.class` 必須設定為 `com.amazon.emr.committer.EmrOptimizedSparkSqlParquetOutputCommitter`。這是預設設定。
  + `spark.sql.sources.commitProtocolClass` 必須設定為 `org.apache.spark.sql.execution.datasources.SQLEmrOptimizedCommitProtocol` 或 `org.apache.spark.sql.execution.datasources.SQLHadoopMapReduceCommitProtocol`。`org.apache.spark.sql.execution.datasources.SQLEmrOptimizedCommitProtocol` 是 Amazon EMR 5.x 系列版本 5.30.0 及更高版本和 Amazon EMR 6.x 系列版本 6.2.0 及更高版本的預設設定。先前 Amazon EMR 版本的預設設定為 `org.apache.spark.sql.execution.datasources.SQLHadoopMapReduceCommitProtocol`。
  + 如果 Spark 任務使用動態分割區欄覆寫分割的 Parquet 資料集，則 `partitionOverwriteMode` 寫入選項和 `spark.sql.sources.partitionOverwriteMode` 必須設為 `static`。這是預設設定。
**注意**  
`partitionOverwriteMode` 寫入選項已導入至 Spark 2.4.0。針對包含於 Amazon EMR 5.19.0 版的 Spark 版本 2.3.2，請設定 `spark.sql.sources.partitionOverwriteMode` 屬性。

## 不使用 EMRFS S3 優化遞交者時的場合
<a name="emr-spark-committer-reqs-anti"></a>

一般而言，EMRFS S3 優化遞交者不用於下列情形。


****  

| 情形 | 為什麼不使用遞交者 | 
| --- | --- | 
| 當您寫入到 HDFS 時 | 遞交者僅支援使用 EMRFS 寫入至 Amazon S3。 | 
| 當您使用 S3A 檔案系統時 | 遞交者僅支援 EMRFS。 | 
| 當您使用 MapReduce 或 Spark 的 RDD API 時 | 遞交者僅支援使用 SparkSQL、DataFrame 或資料集 API。 | 

下列 Scala 範例示範了某些其他情形會阻止使用整個 (第一個範例) 和部分 (第二個範例) EMRFS S3 優化遞交者。

**Example – 動態分割區覆寫模式**  
以下 Scala 範例說明 Spark 使用不同的遞交演算法，從而完全阻止使用 EMRFS S3 優化遞交者。程式碼將 `partitionOverwriteMode` 屬性設為 `dynamic`，僅覆寫您要寫入資料的分割區。然後，由 `partitionBy` 指定動態分割區資料欄，且寫入模式被設為 `overwrite`。  

```
val dataset = spark.range(0, 10)
  .withColumn("dt", expr("date_sub(current_date(), id)"))

dataset.write.mode("overwrite")
  .option("partitionOverwriteMode", "dynamic")
  .partitionBy("dt")
  .parquet("s3://amzn-s3-demo-bucket1/output")
```
您必須執行全部三項設定，以避免使用 EMRFS S3 優化遞交者。當您這樣做時，Spark 會執行在 Spark 遞交通訊協定中指定的其他遞交演算法。對於早於 5.30.0 的 Amazon EMR 5.x 版本，以及早於 6.2.0 的 Amazon EMR 6.x 版本，遞交通訊協定使用 Spark 的暫存目錄，它是以 `.spark-staging` 開頭，在輸出位置下建立的暫時目錄。該演算法會按順序重新命名分割區目錄，這可能對效能產生負面影響。如需有關 Amazon EMR 5.30.0 版及更高版本，和 6.2.0 版及更高版本的詳細資訊，請參閱 [使用 EMRFS S3 優化遞交通訊協定](emr-spark-s3-optimized-commit-protocol.md)。  
Spark 2.4.0 中的演算法遵循以下步驟：  

1. 任務會試圖將輸出寫入 Spark 暫存目錄下的分割區目錄，例如 `${outputLocation}/spark-staging-${jobID}/k1=v1/k2=v2/`。

1. 針對每個寫入的分割區，該任務會試圖保持相對分割區路徑的追蹤，例如 `k1=v1/k2=v2`。

1. 在任務成功完成後，它會將所有追蹤的相對分割區路徑提供給驅動程式。

1. 完成所有任務後，該任務遞交階段將收集在 Spark 臨時目錄下，所有成功任務嘗試寫入的分割區目錄。Spark 使用目錄樹狀圖重新命名操作，按順序將每個目錄重新命名為其最終輸出位置。

1. 在任務遞交階段完成之前刪除臨時目錄。

**Example – 自訂分割區位置**  
在此範例中，該 Scala 程式碼將插入至兩個分割區。其中一個分割區有自訂的分割區位置。另一個分割區使用預設分割區位置。EMRFS S3 最佳化遞交者僅用於寫入任務輸出至使用預設分割區位置的分割區。  

```
val table = "dataset"
val location = "s3://bucket/table"
                            
spark.sql(s"""
  CREATE TABLE $table (id bigint, dt date) 
  USING PARQUET PARTITIONED BY (dt) 
  LOCATION '$location'
""")
                            
// Add a partition using a custom location
val customPartitionLocation = "s3://bucket/custom"
spark.sql(s"""
  ALTER TABLE $table ADD PARTITION (dt='2019-01-28') 
  LOCATION '$customPartitionLocation'
""")
                            
// Add another partition using default location
spark.sql(s"ALTER TABLE $table ADD PARTITION (dt='2019-01-29')")
                            
def asDate(text: String) = lit(text).cast("date")
                            
spark.range(0, 10)
  .withColumn("dt",
    when($"id" > 4, asDate("2019-01-28")).otherwise(asDate("2019-01-29")))
  .write.insertInto(table)
```
Scala 程式碼會建立以下 Amazon S3 物件：  

```
custom/part-00001-035a2a9c-4a09-4917-8819-e77134342402.c000.snappy.parquet
custom_$folder$
table/_SUCCESS
table/dt=2019-01-29/part-00000-035a2a9c-4a09-4917-8819-e77134342402.c000.snappy.parquet
table/dt=2019-01-29_$folder$
table_$folder$
```
在寫入至自訂位置的分割區時，Spark 會使用一個和上一個範例相似的遞交演算法，如下所述。如之前的範例所示，該演算法會導致順序重新命名，這可能會對效能產生負面影響。  

1. 在將輸出寫入自訂位置的分割區時，任務會寫入至 Spark 臨時目錄下的檔案 (該目錄建立在最終輸出位置下)。該檔案名稱會包含隨機的 UUID，以防止檔案衝突。該任務會嘗試追蹤每個檔案以及最終所要的輸出路徑。

1. 在任務成功完成後，它會將檔案和其最終所要之輸出路徑提供給驅動程式。

1. 完成所有任務後，任務遞交階段會依序將所有為分割區寫入至自訂位置的檔案，重新命名為其最終輸出路徑。

1. 在任務遞交階段完成之前刪除臨時目錄。

# EMRFS S3 優化遞交者和分段上傳
<a name="emr-spark-committer-multipart"></a>

若要使用 EMRFS S3 優化遞交者，必須為 Amazon EMR 啟用分段上傳。分段上傳預設為啟用。您可以視需要重新啟用。如需詳細資訊，請參閱《Amazon EMR 管理指南》**中的[設定適用於 Amazon S3 的分段上傳](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-upload-s3.html#Config_Multipart)。

EMRFS S3 最佳化遞交器利用分段上傳類似交易的特性，確保由任務嘗試寫入的檔案只會在任務遞交時顯示於工作的輸出位置。透過此方式使用分段上傳，遞交器可提升預設 FileOutputCommitter 演算法版本 2 的任務遞交效能。使用 EMRFS S3 最佳化遞交器時，應考量傳統分段上傳行為的某些主要差異：
+ 無論檔案大小，分段上傳會一律執行。這不同於 EMRFS 的預設行為 (`fs.s3n.multipart.uploads.split.size` 屬性會控制分段上傳觸發時的檔案大小)。
+ 分段上傳會在不完整狀態維持較長的期間，直到任務遞交或中止。這不同於 EMRFS 的預設行為 (分段上傳會在任務完成寫入特定檔案時完成)。

由於這些差異，如果 Spark Executor JVM 在任務執行和寫入資料至 Amazon S3 時當機或終止，則更可能會留下不完整的分段上傳。因此，在您使用 EMRFS S3 最佳化遞交器時，請務必依照最佳實務來管理失敗的分段上傳。如需詳細資訊，請參閱《Amazon EMR 管理指南》**中有關使用 Amazon S3 儲存貯體的[最佳實務](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-upload-s3.html#emr-bucket-bestpractices)。

# 作業調校考量
<a name="emr-spark-committer-tuning"></a>

針對由任務嘗試寫入的每個檔案，EMRFS S3 最佳化遞交器會耗用少量記憶體，直到任務遞交或中止。在大多數任務中，記憶體的消耗量極少。對於具有寫入大量檔案之長期執行任務的工作，遞交器耗用的記憶體量可能會很明顯，並需要調整配置給 Spark 執行器的記憶體。您可以使用 `spark.executor.memory` 屬性調校執行器記憶體。根據準則，寫入 100,000 個檔案的單一任務通常需要額外 100 MB 的記憶體。如需詳細資訊，請參閱 Apache Spark 組態文件中的[應用程式屬性](https://spark.apache.org/docs/latest/configuration.html#application-properties)。

# 為 Amazon EMR 5.19.0 啟用 EMRFS S3 優化遞交者
<a name="emr-spark-committer-enable"></a>

如果您使用的是 Amazon EMR 5.19.0，您可以在使用 Amazon EMR 建立叢集時或從 Spark 中手動將此 `spark.sql.parquet.fs.optimized.committer.optimization-enabled` 屬性設為 `true`。

## 在建立叢集時啟用 EMRFS S3 優化遞交者
<a name="w2aac62c61c17c13b5"></a>

使用 `spark-defaults` 組態分類將 `spark.sql.parquet.fs.optimized.committer.optimization-enabled` 屬性設為 `true`。如需詳細資訊，請參閱[設定應用程式](emr-configure-apps.md)。

## 從 Spark 啟用 EMRFS S3 優化遞交者
<a name="w2aac62c61c17c13b7"></a>

您可以將 `spark.sql.parquet.fs.optimized.committer.optimization-enabled` 設為 `true`，方式是於 `SparkConf` 將其硬編碼，在 Spark shell 或 `spark-submit` 和 `spark-sql` 工具中或在 `conf/spark-defaults.conf` 將其做為 `--conf` 參數傳遞。如需詳細資訊，請參閱 Apache Spark 文件中的 [Spark 組態](https://spark.apache.org/docs/latest/configuration.html)。

以下範例示範如何在執行 spark-sql 命令時啟用遞交器。

```
spark-sql \
  --conf spark.sql.parquet.fs.optimized.committer.optimization-enabled=true \
  -e "INSERT OVERWRITE TABLE target_table SELECT * FROM source_table;"
```

# 使用 EMRFS S3 優化遞交通訊協定
<a name="emr-spark-s3-optimized-commit-protocol"></a>

EMRFS S3 優化遞交通訊協定是替代性 [FileCommitProtocol](https://spark.apache.org/docs/2.2.0//api/java/org/apache/spark/internal/io/FileCommitProtocol.html) 實作，針對使用 EMRFS 將 Spark 動態分割區覆寫檔案寫入至 Amazon S3 的操作進行過優化。該通訊協定透過在 Spark 動態分割區覆寫作業遞交階段避免 Amazon S3 中的重新命名操作，從而提升應用程式的效能。

請注意，[EMRFS S3-optimized遞交者](emr-spark-s3-optimized-committer.html)也透過避免重新命名操作來改善效能。不過，它不適用於動態分割區覆寫的案例，而遞交通訊協定的改進僅針對動態分割區覆寫案例。

遞交通訊協定在 Amazon EMR 5.30.0 版和更高版本以及 6.2.0 版和更高版本中提供，並預設為啟用。Amazon EMR 從 5.31.0 版開始新增了平行處理改進。此通訊協定用於使用 Spark、DataFrames或資料集的 Spark 任務。在某些情況下將不會使用遞交通訊協定。如需詳細資訊，請參閱[EMRFS S3 優化遞交通訊協定要求](emr-spark-committer-reqs.md)。

**Topics**
+ [EMRFS S3 優化遞交通訊協定要求](emr-spark-commit-protocol-reqs.md)
+ [EMRFS S3 優化遞交通訊協定和分段上傳](emr-spark-commit-protocol-multipart.md)
+ [作業調校考量](emr-spark-commit-protocol-tuning.md)

# EMRFS S3 優化遞交通訊協定要求
<a name="emr-spark-commit-protocol-reqs"></a>

符合下列條件時會使用 EMRFS S3 優化遞交通訊協定：
+ 您可以執行使用 Spark、DataFrames或資料集覆寫分割資料表的 Spark 任務。
+ 您將執行分割區覆寫模式為 `dynamic` 的 Spark 作業。
+ 分段上傳會於 Amazon EMR 中啟用。這是預設值。如需詳細資訊，請參閱[EMRFS S3 優化遞交通訊協定和分段上傳](emr-spark-commit-protocol-multipart.md)。
+ 適用於 EMRFS 的檔案系統快取已啟用。這是預設值。檢查設定 `fs.s3.impl.disable.cache` 是否設為 `false`。
+ 使用 Spark 的內建資料來源支援。在以下情況會使用內建資料來源支援：
  + 當作業寫入至內建的資料來源或資料表時。
  + 當作業寫入至 Hive 中繼存放區 Parquet 資料表時。當 `spark.sql.hive.convertInsertingPartitionedTable` 和 `spark.sql.hive.convertMetastoreParquet` 都設為 true 時會發生這種情況。這些是預設設定。
  + 當作業寫入至 Hive 中繼存放區 ORC 資料表時。當 `spark.sql.hive.convertInsertingPartitionedTable` 和 `spark.sql.hive.convertMetastoreOrc` 都設為 `true` 時會發生這種情況。這些是預設設定。
+ 當 Spark 作業操作寫入至預設的分割區位置時，例如 `${table_location}/k1=v1/k2=v2/`，會使用遞交通訊協定。如果作業操作寫入至自訂分割區位置，則不使用該通訊協定，例如使用 `ALTER TABLE SQL` 命令設定自訂分割區位置。
+ 必須使用下列用於 Spark 的值：
  + `spark.sql.sources.commitProtocolClass` 必須設定為 `org.apache.spark.sql.execution.datasources.SQLEmrOptimizedCommitProtocol`。這是 Amazon EMR 5.30.0 版及更高版本、6.2.0 及更高版本的預設設定。
  + `partitionOverwriteMode` 寫入選項或 `spark.sql.sources.partitionOverwriteMode` 必須設為 `dynamic`。預設設定為 `static`。
**注意**  
`partitionOverwriteMode` 寫入選項已導入至 Spark 2.4.0。針對包含於 Amazon EMR 5.19.0 版的 Spark 版本 2.3.2，請設定 `spark.sql.sources.partitionOverwriteMode` 屬性。
  + 如果 Spark 作業寫入至 Hive 中繼存放區 Parquet 資料表，則 `spark.sql.hive.convertMetastoreParquet`、`spark.sql.hive.convertInsertingPartitionedTable` 和 `spark.sql.hive.convertMetastore.partitionOverwriteMode` 必須設為 `true`。系統有預設的設定。
  + 如果 Spark 作業寫入至 Hive 中繼存放區 ORC 資料表，則 `spark.sql.hive.convertMetastoreOrc`、`spark.sql.hive.convertInsertingPartitionedTable` 和 `spark.sql.hive.convertMetastore.partitionOverwriteMode` 必須設為 `true`。系統有預設的設定。

**Example – 動態分割區覆寫模式**  
在這個 Scala 範例中，將觸發優化。首先，將 `partitionOverwriteMode` 屬性設定為 `dynamic`。這僅會覆寫您正寫入資料的分割區。然後，您要使用 `partitionBy` 指定動態分割區資料欄，並將寫入模式設為 `overwrite`。  

```
val dataset = spark.range(0, 10)
  .withColumn("dt", expr("date_sub(current_date(), id)"))

dataset.write.mode("overwrite")                 // "overwrite" instead of "insert"
  .option("partitionOverwriteMode", "dynamic")  // "dynamic" instead of "static"  
  .partitionBy("dt")                            // partitioned data instead of unpartitioned data
  .parquet("s3://amzn-s3-demo-bucket1/output")    // "s3://" to use Amazon EMR file system, instead of "s3a://" or "hdfs://"
```

## 當不使用 EMRFS S3 優化遞交通訊協定時
<a name="emr-spark-commit-protocol-reqs-anti"></a>

一般而言，EMRFS S3-optimized遞交通訊協定的運作方式與開放原始碼預設 Spark 遞交通訊協定 相同`org.apache.spark.sql.execution.datasources.SQLHadoopMapReduceCommitProtocol`。在下列情形中不會發生優化。


****  

| 情形 | 為什麼不使用遞交通訊協定 | 
| --- | --- | 
| 當您寫入到 HDFS 時 | 遞交通訊協定僅支援使用 EMRFS 寫入至 Amazon S3。 | 
| 當您使用 S3A 檔案系統時 | 遞交通訊協定僅支援 EMRFS。 | 
| 當您使用 MapReduce 或 Spark 的 RDD API 時 | 遞交通訊協定僅支援使用 SparkSQL、DataFrame 或 Dataset API。 | 
| 當未觸發動態分割區覆寫時 | 遞交通訊協定僅對動態分割區覆寫案例進行優化。如需了解其他案例，請參閱 [使用 EMRFS S3 優化遞交者](emr-spark-s3-optimized-committer.md)。 | 

下列 Scala 範例示範了 EMRFS S3 優化遞交通訊協定委派給 `SQLHadoopMapReduceCommitProtocol` 的其他一些情形。

**Example - 具有自訂分割區位置的動態分割區覆寫模式**  
在此範例中，Scala 程式會以動態分割區覆寫模式覆寫兩個分割區。其中一個分割區有自訂的分割區位置。另一個分割區使用預設分割區位置。EMRFS S3 優化遞交通訊協定僅改進使用預設分割區位置的分割區。  

```
val table = "dataset"
val inputView = "tempView"
val location = "s3://bucket/table"
                            
spark.sql(s"""
  CREATE TABLE $table (id bigint, dt date) 
  USING PARQUET PARTITIONED BY (dt) 
  LOCATION '$location'
""")

// Add a partition using a custom location
val customPartitionLocation = "s3://bucket/custom"
spark.sql(s"""
  ALTER TABLE $table ADD PARTITION (dt='2019-01-28') 
  LOCATION '$customPartitionLocation'
""")

// Add another partition using default location
spark.sql(s"ALTER TABLE $table ADD PARTITION (dt='2019-01-29')")

def asDate(text: String) = lit(text).cast("date")   
                       
spark.range(0, 10)
  .withColumn("dt",
    when($"id" > 4, asDate("2019-01-28")).otherwise(asDate("2019-01-29")))
  .createTempView(inputView)
  
// Set partition overwrite mode to 'dynamic'
spark.sql(s"SET spark.sql.sources.partitionOverwriteMode=dynamic")
  
spark.sql(s"INSERT OVERWRITE TABLE $table SELECT * FROM $inputView")
```
Scala 程式碼會建立以下 Amazon S3 物件：  

```
custom/part-00001-035a2a9c-4a09-4917-8819-e77134342402.c000.snappy.parquet
custom_$folder$
table/_SUCCESS
table/dt=2019-01-29/part-00000-035a2a9c-4a09-4917-8819-e77134342402.c000.snappy.parquet
table/dt=2019-01-29_$folder$
table_$folder$
```
早期 Spark 版本中寫入到自訂分割區位置可能導致資料遺失。在此範例中，分割區 `dt='2019-01-28'` 會遺失。如需詳細資料，請參閱 [SPARK-35106](https://issues.apache.org/jira/browse/SPARK-35106)。此問題已在 Amazon EMR 5.33.0 版及更高版本中修正，6.0.x 和 6.1.x 除外。

在寫入至自訂位置的分割區時，Spark 會使用一個和上一個範例相似的遞交演算法，如下所述。如之前的範例所示，該演算法會導致順序重新命名，這可能會對效能產生負面影響。

Spark 2.4.0 中的演算法遵循以下步驟：

1. 在將輸出寫入自訂位置的分割區時，任務會寫入至 Spark 臨時目錄下的檔案 (該目錄建立在最終輸出位置下)。該檔案名稱會包含隨機的 UUID，以防止檔案衝突。該任務會嘗試追蹤每個檔案以及最終所要的輸出路徑。

1. 在任務成功完成後，它會將檔案和其最終所要之輸出路徑提供給驅動程式。

1. 完成所有任務後，任務遞交階段會依序將所有為分割區寫入至自訂位置的檔案，重新命名為其最終輸出路徑。

1. 在任務遞交階段完成之前刪除臨時目錄。

# EMRFS S3 優化遞交通訊協定和分段上傳
<a name="emr-spark-commit-protocol-multipart"></a>

若要利用 EMRFS S3 優化遞交通訊協定中的動態分割區覆寫優化，則必須在 Amazon EMR 中啟用多段上傳。分段上傳預設為啟用。您可以視需要重新啟用。如需詳細資訊，請參閱《Amazon EMR 管理指南》**中的[設定適用於 Amazon S3 的分段上傳](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-upload-s3.html#Config_Multipart)。

動態分割區覆寫期間，EMRFS S3 優化遞交通訊協定利用分段上傳類似交易的特性，確保由任務嘗試寫入的檔案只會在作業遞交時顯示於作業的輸出位置。透過以此方式使用多段上傳，遞交通訊協定將提升作業遞交效能，讓其比預設 `SQLHadoopMapReduceCommitProtocol` 更佳。使用 EMRFS S3 優化遞交通訊協定時，應考量傳統分段上傳行為的某些主要差異：
+ 無論檔案大小，分段上傳會一律執行。這不同於 EMRFS 的預設行為 (`fs.s3n.multipart.uploads.split.size` 屬性會控制分段上傳觸發時的檔案大小)。
+ 分段上傳會在不完整狀態維持較長的期間，直到任務遞交或中止。這不同於 EMRFS 的預設行為 (分段上傳會在任務完成寫入特定檔案時完成)。

由於這些差異，如果 Spark Executor JVM 在任務執行和寫入資料至 Amazon S3 時當機或終止，或者 Spark 驅動程式 JVM 在作業執行時當機或終止，則更可能會留下不完整的分段上傳。因此，在您使用 EMRFS S3 優化遞交通訊協定時，請務必依照最佳實務來管理失敗的分段上傳。如需詳細資訊，請參閱《Amazon EMR 管理指南》**中有關使用 Amazon S3 儲存貯體的[最佳實務](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-upload-s3.html#emr-bucket-bestpractices)。

# 作業調校考量
<a name="emr-spark-commit-protocol-tuning"></a>

在執行器上，針對由任務嘗試寫入的每個檔案，EMRFS S3 優化遞交通訊協定會耗用少量記憶體，直到任務遞交或中止。在大多數任務中，記憶體的消耗量極少。

在 Spark 驅動程式上，EMRFS S3 優化遞交通訊協定需要記憶體來儲存每個遞交檔案的中繼資料資訊，直至作業被遞交或中止為止。在大多數作業中，會忽略預設 Spark 驅動程式記憶體設定。

對於具有寫入大量檔案之長時間執行任務的作業，遞交通訊協定耗用的記憶體量可能會很明顯，並需要調整配置給 Spark，特別是 Spark 執行器的記憶體。您可以使用 `spark.driver.memory` 屬性調整 Spark 驅動程式的記憶體，或使用 `spark.executor.memory` 屬性調整 Spark 執行器的記憶體。根據準則，寫入 100,000 個檔案的單一任務通常需要額外 100 MB 的記憶體。如需詳細資訊，請參閱 Apache Spark 組態文件中的[應用程式屬性](https://spark.apache.org/docs/latest/configuration.html#application-properties)。

# 使用 EMRFS 的重試 Amazon S3 請求
<a name="emr-spark-emrfs-retry"></a>

本主題提供使用 EMRFS 向 Amazon S3 發出請求時，您可以使用的重試策略相關資訊。當您的請求速率加快時，S3 嘗試擴展以支援新的速率。在此過程中，S3 可能對請求限流並傳回 `503 Slow Down` 錯誤。若要提高您的 S3 請求的成功率，您可以透過在 `emrfs-site` 組態中設定屬性，調整您的重試策略。

您可以採用下列方式調整您的重試策略。
+ 提高預設指數退避重試策略的重試上限。
+ 啟用並設定和性增長/乘性降低 (AIMD) 重試策略。Amazon EMR 6.4.0 版和更高版本支援 AIMD。

## 使用預設指數退避策略
<a name="emr-spark-emrfs-retry-exponential-backoff"></a>

依預設，EMRFS 會使用指數退避策略重試 Amazon S3 請求。預設 EMRFS 重試限制為 15。若要避免 S3 `503 Slow Down` 錯誤，您可以在建立新叢集時、執行中叢集上或應用程式執行期調高重試限制。

如果想要調高重試限制，您必須在 `emrfs-site` 組態中變更 `fs.s3.maxRetries` 的值。下列範例組態將 `fs.s3.maxRetries` 設為自訂值 30。

```
[
    {
      "Classification": "emrfs-site",
      "Properties": {
        "fs.s3.maxRetries": "30"
      }
    }
]
```

如需使用組態物件的詳細資訊，請參閱 [設定應用程式](emr-configure-apps.md)。

## 使用 AIMD 重試策略
<a name="emr-spark-emrfs-retry-aimd"></a>

在 Amazon EMR 6.4.0 版及更高版本中，EMRFS 支援依據和性增長/乘性降低 (AIMD) 模型的替代性重試策略。當您使用大型 Amazon EMR 叢集時，AIMD 重試策略變得特別有用。

AIMD 會使用有關近期成功請求的資料計算自訂請求速率。此策略會減少限流請求的數量和每個請求所需的嘗試總次數。

若要啟用 AIMD 重試策略，您必須將 `emrfs-site` 組態中的 `fs.s3.aimd.enabled` 屬性設為 `true`，如下例所示。

```
[
    {
      "Classification": "emrfs-site",
      "Properties": {
        "fs.s3.aimd.enabled": "true"
      }
    }
]
```

如需使用組態物件的詳細資訊，請參閱 [設定應用程式](emr-configure-apps.md)。

## 進階 AIMD 重試設定
<a name="emr-spark-emrfs-retry-advanced-properties"></a>

在使用 AIMD 重試策略時，您可以設定下表中所列的屬性，以完善重試行為。對於大多數使用案例，建議您使用預設值。


**進階 AIMD 重試策略屬性**  

| 屬性 | 預設值 | Description | 
| --- | --- | --- | 
| fs.s3.aimd.increaseIncrement | 0.1 | 控制當連續請求成功時，請求速率以多快速度加快。 | 
| fs.s3.aimd.reductionFactor | 2 | 控制當 Amazon S3 傳回 503 回應時，請求速率以多快速度減緩。預設係數 2 會使請求速率減半。 | 
| fs.s3.aimd.minRate | 0.1 | 當 S3 請求遇到持續限流時，設定請求速率下限。 | 
| fs.s3.aimd.initialRate | 5500 | 設定初始請求速率，然後它會依據您為 fs.s3.aimd.increaseIncrement 和 fs.s3.aimd.reductionFactor 指定的值變更。初始速率還用於 GET 請求，並且會針對 PUT 請求按比例擴展 (3500/5500)。 | 
| fs.s3.aimd.adjustWindow | 2 | 控制調整請求速率的頻率，使用回應數量進行衡量。 | 
| fs.s3.aimd.maxAttempts | 100 | 設定嘗試請求的最大次數。 | 

# 新增 Spark 步驟
<a name="emr-spark-submit-step"></a>

您可以使用 Amazon EMR 步驟來將工作提交到在 EMR 叢集上安裝的 Spark 架構。如需詳細資訊，請參閱《Amazon EMR 管理指南》中的[步驟](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-overview.html#emr-overview-data-processing)。在主控台與 CLI 中，使用 Spark 應用程式步驟 (其會代表您執行 `spark-submit` 指令碼做為步驟)，來完成此動作。您透過 API 呼叫，使用 `spark-submit` 來使用步驟以叫用 `command-runner.jar`。

如需有關將應用程式提交到 Spark 的詳細資訊，請參閱 Apache Spark 文件中的[提交應用程式](https://spark.apache.org/docs/latest/submitting-applications.html)主題。

**使用主控台來提交 Spark 步驟**

1. 開啟位於 https：//[https://console.aws.amazon.com/emr](https://console.aws.amazon.com/emr/) 的 Amazon EMR 主控台。

1. 在 **Cluster List (叢集清單)** 中，選擇您的叢集名稱。

1. 向下捲動至 **Steps (步驟)** 區段並展開，接著選擇 **Add step (新增步驟)**。

1. 在 **Add Step (新增步驟)** 對話方塊中：
   + 在 **Step type (步驟類型)**，選擇 **Spark application (Spark 應用程式)**。
   + 對於 **Name (名稱)**，接受預設名稱 (Spark 應用程式) 或輸入新名稱。
   + 使用 **Deploy mode (部署模式)** 時，請選擇 **Client (用戶端)** 或 **Cluster (叢集)** 模式。用戶端模式會啟動叢集主要執行個體上的驅動程式程式，而叢集模式則會在該叢集上啟動您的驅動程式。對於客戶端模式，驅動程式的日誌輸出會出現在步驟日誌中，而對於叢集模式，驅動程式的日誌輸出會出現在第一個 YARN 容器的日誌中。如需詳細資訊，請參閱 Apache Spark 文件中的[叢集模式概觀](https://spark.apache.org/docs/latest/cluster-overview.html)。
   + 指定所需的 **Spark-submit 選項**。如需有關 `spark-submit` 選項的詳細資訊，請參閱[透過 spark-submit 啟動應用程式](https://spark.apache.org/docs/latest/submitting-applications.html#launching-applications-with-spark-submit)。
   + 對於 **Application location (應用程式位置)**，指定應用程式本機或 S3 URI 路徑。
   + 針對 **Arguments (引數)**，將欄位保留空白。
   + 針對 **Action on failure (失敗的動作)**，接受預設選項 (**Continue (繼續)**)。

1. 選擇**新增**。該步驟會出現在主控台中，且狀態為待定。

1. 隨著步驟的執行，步驟的狀態會依序從 **Pending (待定)**、**Running (執行中)** 變成 **Completed (完成)**。若要更新狀態，您可以選擇 **Actions** (動作) 欄上的 **Refresh** (重新整理) 圖示。

1. 如果您有設定記錄，步驟結果會位於**日誌檔案**下步驟旁 Amazon EMR 主控台的「叢集詳細資訊」頁面中。您可以在啟動叢集時設定的日誌儲存貯體中選擇尋找步驟資訊。

**使用 將工作提交至 Spark AWS CLI**

當您建立叢集，或是在現有叢集中使用 `aws emr add-steps` 子指令時提交步驟。

1. 如下列範例所示，使用 `create-cluster`。
**注意**  
包含 Linux 行接續字元 (\$1) 是為了提高可讀性。它們可以在 Linux 命令中移除或使用。對於 Windows，請將其移除或取代為插入符號 (^)。

   ```
   aws emr create-cluster --name "Add Spark Step Cluster" --release-label emr-7.12.0 --applications Name=Spark \
   --ec2-attributes KeyName=myKey --instance-type m5.xlarge --instance-count 3 \
   --steps Type=Spark,Name="Spark Program",ActionOnFailure=CONTINUE,Args=[--class,org.apache.spark.examples.SparkPi,/usr/lib/spark/examples/jars/spark-examples.jar,10] --use-default-roles
   ```

   替代方案是如下列範例所示，使用 `command-runner.jar`。

   ```
   aws emr create-cluster --name "Add Spark Step Cluster" --release-label emr-7.12.0 \
   --applications Name=Spark --ec2-attributes KeyName=myKey --instance-type m5.xlarge --instance-count 3 \
   --steps Type=CUSTOM_JAR,Name="Spark Program",Jar="command-runner.jar",ActionOnFailure=CONTINUE,Args=[spark-example,SparkPi,10] --use-default-roles
   ```
**注意**  
包含 Linux 行接續字元 (\$1) 是為了提高可讀性。它們可以在 Linux 命令中移除或使用。對於 Windows，請將其移除或取代為插入符號 (^)。

1. 或者，將步驟新增至執行中的叢集。請使用 `add-steps`。

   ```
   aws emr add-steps --cluster-id j-2AXXXXXXGAPLF --steps Type=Spark,Name="Spark Program",ActionOnFailure=CONTINUE,Args=[--class,org.apache.spark.examples.SparkPi,/usr/lib/spark/examples/jars/spark-examples.jar,10]
   ```

   替代方案是如下列範例所示，使用 `command-runner.jar`。

   ```
   aws emr add-steps --cluster-id j-2AXXXXXXGAPLF --steps Type=CUSTOM_JAR,Name="Spark Program",Jar="command-runner.jar",ActionOnFailure=CONTINUE,Args=[spark-example,SparkPi,10]
   ```

**若要使用適用於 Java 的 SDK 將工作提交給 Spark**

1. 以下範例說明如何使用 Java 透過 Spark 新增叢集步驟。

   ```
   AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
   AmazonElasticMapReduce emr = new AmazonElasticMapReduceClient(credentials);
    
   StepFactory stepFactory = new StepFactory();
   AmazonElasticMapReduceClient emr = new AmazonElasticMapReduceClient(credentials);
   AddJobFlowStepsRequest req = new AddJobFlowStepsRequest();
   req.withJobFlowId("j-1K48XXXXXXHCB");
   
   List<StepConfig> stepConfigs = new ArrayList<StepConfig>();
   		
   HadoopJarStepConfig sparkStepConf = new HadoopJarStepConfig()
   			.withJar("command-runner.jar")
   			.withArgs("spark-submit","--executor-memory","1g","--class","org.apache.spark.examples.SparkPi","/usr/lib/spark/examples/jars/spark-examples.jar","10");			
   		
   StepConfig sparkStep = new StepConfig()
   			.withName("Spark Step")
   			.withActionOnFailure("CONTINUE")
   			.withHadoopJarStep(sparkStepConf);
   
   stepConfigs.add(sparkStep);
   req.withSteps(stepConfigs);
   AddJobFlowStepsResult result = emr.addJobFlowSteps(req);
   ```

1. 檢查步驟日誌以查看步驟的結果。 AWS 管理主控台 如果您已啟用記錄功能，您可以在 中執行此操作，方法是選擇**步驟**、選取步驟，然後針對**日誌檔案**選擇 `stdout`或 `stderr`。若要查看可用的日誌，請選擇 **View Logs (檢視日誌)**。

## 覆寫 Spark 預設組態設定
<a name="dynamic-configuration"></a>

您可以根據每個應用程式覆寫 Spark 預設組態值。您可以使用基本上會將選項傳遞至 `spark-submit` 的步驟來在提交應用程式時這麼做。例如，您可以想要透過變更 `spark.executor.memory` 來變更對執行器程序分配的記憶體。您可以使用如下引數提供 `--executor-memory` 參數：

```
spark-submit --executor-memory 1g --class org.apache.spark.examples.SparkPi /usr/lib/spark/examples/jars/spark-examples.jar 10
```

同樣地，您可以微調 `--executor-cores` 和 `--driver-memory`。在步驟中，您會將下列引數提供給步驟：

```
--executor-memory 1g --class org.apache.spark.examples.SparkPi /usr/lib/spark/examples/jars/spark-examples.jar 10
```

您可以使用 `--conf` 選項來微調可能沒有內建參數的設定。如需有關其他可微調設定的詳細資訊，請參閱 Apache Spark 文件中的[動態載入 Spark 屬性](https://spark.apache.org/docs/latest/configuration.html#dynamically-loading-spark-properties)主題。

# 檢視 Spark 應用程式歷史記錄
<a name="emr-spark-application-history"></a>

您可以在主控台中，使用叢集詳細資訊頁面的**應用程式使用者界面**檢視 Spark、YARN 應用程式和 Tez UI 詳細資訊。Amazon EMR 應用程式使用者界面 (UI) 可讓您更輕鬆地進行疑難排解，並分析使用中的作業和作業歷史記錄。

如需詳細資訊，請參閱《Amazon EMR 管理指南》**中的[檢視應用程式歷史記錄](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-cluster-application-history.html)。

# 存取 Spark Web UI
<a name="emr-spark-webui"></a>

您可以檢視 Spark Web UI，透過遵循《Amazon EMR 管理指南》中名為[連線至叢集](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-connect-master-node.html)一節的相關程序建立 SSH 通道或建立代理程式，然後導覽至叢集的 YARN ResourceManager。選擇應用程式之 **Tracking UI (追蹤 UI)** 下的連結。如果您的應用程式正在執行，請參閱 **ApplicationMaster (ApplicationMaster)**。這會帶您到應用程式主控 Web UI 位於連接埠 20888 的驅動程式位置。如果您是在 YARN 用戶端模式中執行，驅動程式可能位於叢集的主節點。如果您是在 YARN 叢集模式中執行應用程式，驅動程式會位於叢集上應用程式的 ApplicationMaster。如果您的應用程式已結束，請檢視**歷史記錄**，它將帶您前往 EMR 叢集主節點上在 18080 的 Spark HistoryServer UI 連接埠號碼。這是適用於已經完成的應用程式。您也可以在 http://*master-public-dns-name*:18080/ 直接導覽至 Spark HistoryServer UI。

在 Amazon EMR 5.25.0 版及更高版本中，您可以從主控台存取 Spark 歷史記錄伺服器 UI，而不需要透過 SSH 連線設定 Web 代理。如需詳細資訊，請參閱[檢視持續應用程式使用者界面](https://docs.aws.amazon.com/emr/latest/ManagementGuide/app-history-spark-UI.html)。

# 使用 Spark 結構化串流 Amazon Kinesis Data Streams 連接器
<a name="emr-spark-structured-streaming-kinesis"></a>

Amazon EMR 7.1.0 版和更新版本包括發行映像中的 Spark 結構化串流 Amazon Kinesis Data Streams 連接器。使用此連接器，您可以在 Amazon EMR 上使用 Spark 來處理存放在 Amazon Kinesis Data Streams 中的資料。連接器支援 `GetRecords`（共用輸送量） 和 `SubscribeToShard`（增強廣發） 的消費者類型。此整合是以 為基礎[https://github.com/awslabs/spark-sql-kinesis-connector](https://github.com/awslabs/spark-sql-kinesis-connector)。如需如何開始使用連接器的詳細資訊，請參閱 [README](https://github.com/awslabs/spark-sql-kinesis-connector/blob/main/README.md)。

下列範例示範如何使用 連接器透過 Amazon EMR 啟動 Spark 應用程式

```
spark-submit my_kinesis_streaming_script.py
```

# 使用 Amazon EMR 整合 Amazon Redshift 與 Apache Spark
<a name="emr-spark-redshift"></a>

使用 Amazon EMR 版本 6.4.0 及更高版本，每個版本映像都包括 [Apache Spark](https://aws.amazon.com/emr/features/spark/) 和 Amazon Redshift 之間的連接器。借助此連接器，您可以在 Amazon EMR 上使用 Spark 來處理存放在 Amazon Redshift 中的資料。對於 Amazon EMR 6.4.0 版到 6.8.0 版，整合以 [`spark-redshift` 開放原始碼連接器](https://github.com/spark-redshift-community/spark-redshift#readme)為基礎。對於 Amazon EMR 6.9.0 版及更高版本，[Amazon Redshift 與 Apache Spark 整合](https://docs.aws.amazon.com/redshift/latest/mgmt/spark-redshift-connector.html)已從社群版本遷移至原生整合。

**Topics**
+ [使用 Apache Spark 的 Amazon Redshift 整合，啟動 Spark 應用程式](emr-spark-redshift-launch.md)
+ [使用 Apache Spark 的 Amazon Redshift 整合進行身分驗證](emr-spark-redshift-auth.md)
+ [讀取和寫入 Amazon Redshift](emr-spark-redshift-readwrite.md)
+ [使用 Spark 連接器時的考量和限制](emr-spark-redshift-considerations.md)

# 使用 Apache Spark 的 Amazon Redshift 整合，啟動 Spark 應用程式
<a name="emr-spark-redshift-launch"></a>

針對 Amazon EMR 6.4 至 6.9 版，您必須使用 `--jars` 或 `--packages` 選項來指定要使用下列的哪些 JAR 檔案。`--jars` 選項指定儲存於本機、HDFS 或使用 HTTP/S 的相依性。若要了解 `--jars` 選項支援的其他檔案位置，請參閱 Spark 文件中的[進階相依性管理](https://spark.apache.org/docs/latest/submitting-applications.html#advanced-dependency-management)。`--packages` 選項指定儲存於公有 Maven 儲存庫的相依性。
+ `spark-redshift.jar`
+ `spark-avro.jar`
+ `RedshiftJDBC.jar`
+ `minimal-json.jar`

Amazon EMR 6.10.0 版及更高版本不需要 `minimal-json.jar` 相依性，並且依預設會向每個叢集自動安裝其他相依性。下列範例說明如何為 Apache Spark 啟動與 Amazon Redshift 整合的 Spark 應用程式。

------
#### [ Amazon EMR 6.10.0 \$1 ]

以下範例說明如何在 Amazon EMR 6.10 版及更高版本中，使用 `spark-redshift` 連接器啟動 Spark 應用程式。

```
spark-submit my_script.py
```

------
#### [ Amazon EMR 6.4.0 - 6.9.x ]

若要在 Amazon EMR 6.4 版到 6.9 版上使用 `spark-redshift` 連接器啟動 Spark 應用程式，您必須使用 `--jars` 或 `--packages` 選項，如以下範例所示。請注意，與 `--jars` 選項一起列出的路徑是 JAR 檔案的預設路徑。

```
spark-submit \
  --jars /usr/share/aws/redshift/jdbc/RedshiftJDBC.jar,/usr/share/aws/redshift/spark-redshift/lib/spark-redshift.jar,/usr/share/aws/redshift/spark-redshift/lib/spark-avro.jar,/usr/share/aws/redshift/spark-redshift/lib/minimal-json.jar \
  my_script.py
```

------

# 使用 Apache Spark 的 Amazon Redshift 整合進行身分驗證
<a name="emr-spark-redshift-auth"></a>

## 使用 AWS Secrets Manager 擷取登入資料並連線至 Amazon Redshift
<a name="emr-spark-redshift-secrets"></a>

下列程式碼範例示範如何使用 AWS Secrets Manager 擷取登入資料，以使用 Python 中 Apache Spark 的 PySpark 界面連線至 Amazon Redshift 叢集。

```
from pyspark.sql import SQLContext
import boto3

sc = # existing SparkContext
sql_context = SQLContext(sc)

secretsmanager_client = boto3.client('secretsmanager')
secret_manager_response = secretsmanager_client.get_secret_value(
    SecretId='string',
    VersionId='string',
    VersionStage='string'
)
username = # get username from secret_manager_response
password = # get password from secret_manager_response
url = "jdbc:redshift://redshifthost:5439/database?user=" + username + "&password=" + password

# Read data from a table
df = sql_context.read \
    .format("io.github.spark_redshift_community.spark.redshift") \
    .option("url", url) \
    .option("dbtable", "my_table") \
    .option("tempdir", "s3://path/for/temp/data") \
    .load()
```

## 使用 IAM 擷取登入資料並連線至 Amazon Redshift
<a name="emr-spark-redshift-iam"></a>

您可以使用 Amazon Redshift 提供的 JDBC 版本 2 驅動程序，透過 Spark 連接器連線到 Amazon Redshift。若要使用 AWS Identity and Access Management (IAM)，[請將 JDBC URL 設定為使用 IAM 身分驗證](https://docs.aws.amazon.com/redshift/latest/mgmt/generating-iam-credentials-configure-jdbc-odbc.html)。若要從 Amazon EMR 連線到 Redshift 叢集，您必須授予 IAM 角色許可，以便擷取暫時 IAM 登入資料。將下列許可指派給您的 IAM 角色，以便其擷取憑證，並執行 Amazon S3 操作。
+  [Redshift：GetClusterCredentials](https://docs.aws.amazon.com/redshift/latest/APIReference/API_GetClusterCredentials.html) （適用於佈建的 Amazon Redshift 叢集） 
+  [Redshift：DescribeClusters](https://docs.aws.amazon.com/redshift/latest/APIReference/API_DescribeClusters.html) （適用於佈建的 Amazon Redshift 叢集） 
+ [Redshift：GetWorkgroup](https://docs.aws.amazon.com/redshift-serverless/latest/APIReference/API_GetWorkgroup.html) （適用於 Amazon Redshift Serverless 工作群組）
+  [Redshift:GetCredentials](https://docs.aws.amazon.com/redshift-serverless/latest/APIReference/API_GetCredentials.html) (適用於 Amazon Redshift Serverless 工作群組) 
+  [s3:GetBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/API_control_GetBucket.html) 
+  [s3:GetBucketLocation](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLocation.html) 
+  [s3:GetObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) 
+  [s3:PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) 
+  [s3:GetBucketLifecycleConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycleConfiguration.html) 

如需有關 `GetClusterCredentials` 的詳細資訊，請參閱 [`GetClusterCredentials` 的資源政策](https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-iam-access-control-identity-based.html#redshift-policy-resources.getclustercredentials-resources)。

您還必須確保 Amazon Redshift 可以在 `COPY` 和 `UNLOAD` 操作期間擔任 IAM 角色。

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "sts:AssumeRole"
      ],
      "Resource": "arn:aws:iam::123456789012:role/RedshiftServiceRole",
      "Sid": "AllowSTSAssumerole"
    }
  ]
}
```

------

以下範例使用 Spark 和 Amazon Redshift 之間的 IAM 身分驗證：

```
from pyspark.sql import SQLContext
import boto3

sc = # existing SparkContext
sql_context = SQLContext(sc)

url = "jdbc:redshift:iam://redshift-host:redshift-port/db-name"
iam_role_arn = "arn:aws:iam::account-id:role/role-name"

# Read data from a table
df = sql_context.read \
    .format("io.github.spark_redshift_community.spark.redshift") \
    .option("url", url) \
    .option("aws_iam_role", iam_role_arn) \
    .option("dbtable", "my_table") \
    .option("tempdir", "s3a://path/for/temp/data") \
    .mode("error") \
    .load()
```

# 讀取和寫入 Amazon Redshift
<a name="emr-spark-redshift-readwrite"></a>

下列程式碼範例使用 PySpark，透過資料來源 API 和 SparkSQL，在 Amazon Redshift 資料庫中讀取和寫入範例資料。

------
#### [ Data source API ]

使用 PySpark，透過資料來源 API，在 Amazon Redshift 資料庫中讀取和寫入範例資料。

```
import boto3
from pyspark.sql import SQLContext

sc = # existing SparkContext
sql_context = SQLContext(sc)

url = "jdbc:redshift:iam://redshifthost:5439/database"
aws_iam_role_arn = "arn:aws:iam::accountID:role/roleName"

df = sql_context.read \
    .format("io.github.spark_redshift_community.spark.redshift") \
    .option("url", url) \
    .option("dbtable", "tableName") \
    .option("tempdir", "s3://path/for/temp/data") \
    .option("aws_iam_role", "aws_iam_role_arn") \
    .load()

df.write \
    .format("io.github.spark_redshift_community.spark.redshift") \
    .option("url", url) \
    .option("dbtable", "tableName_copy") \
    .option("tempdir", "s3://path/for/temp/data") \
    .option("aws_iam_role", "aws_iam_role_arn") \
    .mode("error") \
    .save()
```

------
#### [ SparkSQL ]

使用 PySpark，透過 SparkSQL，在 Amazon Redshift 資料庫中讀取和寫入範例資料。

```
import boto3
import json
import sys
import os
from pyspark.sql import SparkSession

spark = SparkSession \
    .builder \
    .enableHiveSupport() \
    .getOrCreate()
    
url = "jdbc:redshift:iam://redshifthost:5439/database"
aws_iam_role_arn = "arn:aws:iam::accountID:role/roleName"
    
bucket = "s3://path/for/temp/data"
tableName = "tableName" # Redshift table name

s = f"""CREATE TABLE IF NOT EXISTS {tableName} (country string, data string) 
    USING io.github.spark_redshift_community.spark.redshift 
    OPTIONS (dbtable '{tableName}', tempdir '{bucket}', url '{url}', aws_iam_role '{aws_iam_role_arn}' ); """

spark.sql(s)
         
columns = ["country" ,"data"]
data = [("test-country","test-data")]
df = spark.sparkContext.parallelize(data).toDF(columns)

# Insert data into table
df.write.insertInto(tableName, overwrite=False)
df = spark.sql(f"SELECT * FROM {tableName}")
df.show()
```

------

# 使用 Spark 連接器時的考量和限制
<a name="emr-spark-redshift-considerations"></a>
+ 建議您開啟適用於 JDBC 連接器的 SSL，從 Amazon EMR 上的 Spark 連線到 Amazon Redshift。
+ 作為最佳實務，建議您在 AWS Secrets Manager 中管理 Amazon Redshift 叢集的憑證。如需範例，請參閱[使用 AWS Secrets Manager 擷取連線至 Amazon Redshift 的登入](https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-secrets-manager-integration.html)資料。
+ 建議使用 Amazon Redshift 身分驗證參數的 `aws_iam_role` 參數傳遞 IAM 角色。
+ `tempdir` URI 指向 Amazon S3 位置。此暫時目錄不會自動清理，因此可能會增加額外的費用。
+ 請考慮下列針對 Amazon Redshift 的建議：
  + 建議您封鎖對 Amazon Redshift 叢集的公開存取。
  + 建議您開啟 [Amazon Redshift 稽核日誌](https://docs.aws.amazon.com/redshift/latest/mgmt/db-auditing.html)。
  + 建議您開啟 [Amazon Redshift 靜態加密](https://docs.aws.amazon.com/redshift/latest/mgmt/security-server-side-encryption.html)。
+ 請考慮下列針對 Amazon S3 的建議：
  + 建議您[封鎖對 Amazon S3 儲存貯體的公開存取](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html)。
  + 建議您使用 [Amazon S3 伺服器端加密](https://docs.aws.amazon.com/AmazonS3/latest/userguide/serv-side-encryption.html)來加密所用的 S3 儲存貯體。
  + 建議您使用 [Amazon S3 生命週期政策](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html)來定義 Amazon S3 儲存貯體的保留規則。
  + Amazon EMR 一律會驗證從開放原始碼匯入到映像的程式碼。出於安全考慮，我們不支援下列從 Spark 到 Amazon S3 的身分驗證方法：
    + 在`hadoop-env`組態分類中設定 AWS 存取金鑰
    + 在 `tempdir` URI 中編碼 AWS 存取金鑰

如需有關使用連接器及其支援參數的詳細資訊，請參閱下列資源：
+ 《Amazon Redshift 管理指南》**中的 [Apache Spark 的 Amazon Redshift 整合](https://docs.aws.amazon.com/redshift/latest/mgmt/spark-redshift-connector.html)
+ Github 上的 [`spark-redshift` 社群儲存庫](https://github.com/spark-redshift-community/spark-redshift#readme)

# Spark 版本歷史記錄
<a name="Spark-release-history"></a>

下表列出 Amazon EMR 的每個發行版本中包含的 Spark 版本，以及與應用程式一起搭配安裝的元件。如需每個發行版本中的元件版本，請參閱 [Amazon EMR 7.x 發行版本](emr-release-7x.md)、[Amazon EMR 6.x 發行版本](emr-release-6x.md) 或 [Amazon EMR 5.x 發行版本](emr-release-5x.md) 中適用於您發行版本的「元件版本」一節。

**重要**  
自 Amazon EMR 5.16.0 版開始提供 Apache Spark 版本 2.3.1，以因應 [CVE-2018-8024](https://nvd.nist.gov/vuln/detail/CVE-2018-8024) 和 [CVE-2018-1334](https://nvd.nist.gov/vuln/detail/CVE-2018-1334)。建議您將舊版 Spark 遷移至 Spark 版本 2.3.1 或更高版本。


**Spark 版本資訊**  

| Amazon EMR 發行標籤 | Spark 版本 | 與 Spark 一起搭配安裝的元件 | 
| --- | --- | --- | 
| emr-7.12.0 | 3.5.6-amzn-1 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-hdfs-zkfc, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.11.0 | 3.5.6-amzn-0 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-hdfs-zkfc, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.10.0 | 3.5.5-amzn-1 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.9.0 | 3.5.5-amzn-0 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.8.0 | 3.5.4-amzn-0 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.7.0 | 3.5.3-amzn-1 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.6.0 | 3.5.3-amzn-0 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.5.0 | 3.5.2-amzn-1 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.4.0 | 3.5.2-amzn-0 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.3.0 | 3.5.1-amzn-1 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.2.0 | 3.5.1-amzn-0 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.36.2 | 2.4.8-amzn-2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.1.0 | 3.5.0-amzn-1 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.0.0 | 3.5.0-amzn-0 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.15.0 | 3.4.1-amzn-2 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.14.0 | 3.4.1-amzn-1 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.13.0 | 3.4.1-amzn-0 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.12.0 | 3.4.0-amzn-0 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.11.1 | 3.3.2-amzn-0.1 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.11.0 | 3.3.2-amzn-0 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.10.1 | 3.3.1-amzn-0.1 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.10.0 | 3.3.1-amzn-0 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.9.1 | 3.3.0-amzn-1.1 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.9.0 | 3.3.0-amzn-1 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.8.1 | 3.3.0-amzn-0.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.8.0 | 3.3.0-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.7.0 | 3.2.1-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.36.1 | 2.4.8-amzn-2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.36.0 | 2.4.8-amzn-2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.6.0 | 3.2.0-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.35.0 | 2.4.8-amzn-1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.5.0 | 3.1.2-amzn-1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.4.0 | 3.1.2-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.3.1 | 3.1.1-amzn-0.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.3.0 | 3.1.1-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.2.1 | 3.0.1-amzn-0.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.2.0 | 3.0.1-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.1.1 | 3.0.0-amzn-0.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.1.0 | 3.0.0-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.0.1 | 2.4.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.0.0 | 2.4.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.34.0 | 2.4.8-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.33.1 | 2.4.7-amzn-1.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.33.0 | 2.4.7-amzn-1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.32.1 | 2.4.7-amzn-0.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.32.0 | 2.4.7-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.31.1 | 2.4.6-amzn-0.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.31.0 | 2.4.6-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.30.2 | 2.4.5-amzn-0.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.30.1 | 2.4.5-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.30.0 | 2.4.5-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-notebook-env, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.29.0 | 2.4.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.28.1 | 2.4.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.28.0 | 2.4.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.27.1 | 2.4.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.27.0 | 2.4.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.26.0 | 2.4.3 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.25.0 | 2.4.3 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.24.1 | 2.4.2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.24.0 | 2.4.2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.23.1 | 2.4.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.23.0 | 2.4.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.22.0 | 2.4.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.21.2 | 2.4.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.21.1 | 2.4.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.21.0 | 2.4.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.20.1 | 2.4.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.20.0 | 2.4.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.19.1 | 2.3.2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.19.0 | 2.3.2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.18.1 | 2.3.2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.18.0 | 2.3.2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.17.2 | 2.3.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.17.1 | 2.3.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.17.0 | 2.3.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.16.1 | 2.3.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.16.0 | 2.3.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.15.1 | 2.3.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.15.0 | 2.3.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.14.2 | 2.3.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.14.1 | 2.3.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.14.0 | 2.3.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.13.1 | 2.3.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.13.0 | 2.3.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.12.3 | 2.2.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.12.2 | 2.2.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.12.1 | 2.2.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.12.0 | 2.2.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.11.4 | 2.2.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.11.3 | 2.2.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.11.2 | 2.2.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.11.1 | 2.2.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.11.0 | 2.2.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.10.1 | 2.2.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.10.0 | 2.2.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.9.1 | 2.2.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.9.0 | 2.2.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.8.3 | 2.2.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.8.2 | 2.2.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.8.1 | 2.2.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.8.0 | 2.2.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.7.1 | 2.1.1 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.7.0 | 2.1.1 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.6.1 | 2.1.1 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.6.0 | 2.1.1 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.5.4 | 2.1.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.5.3 | 2.1.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.5.2 | 2.1.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.5.1 | 2.1.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.5.0 | 2.1.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.4.1 | 2.1.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.4.0 | 2.1.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.3.2 | 2.1.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.3.1 | 2.1.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.3.0 | 2.1.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.2.3 | 2.0.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.2.2 | 2.0.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.2.1 | 2.0.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.2.0 | 2.0.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.1.1 | 2.0.1 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.1.0 | 2.0.1 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.0.3 | 2.0.1 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.0.2 | 2.0.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.0.1 | 2.0.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.0.0 | 2.0.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.9.6 | 1.6.3 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.9.5 | 1.6.3 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.9.4 | 1.6.3 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.9.3 | 1.6.3 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.9.2 | 1.6.3 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.9.1 | 1.6.3 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.8.5 | 1.6.3 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.8.4 | 1.6.3 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.8.3 | 1.6.3 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.8.2 | 1.6.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.8.1 | 1.6.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.8.0 | 1.6.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.7.4 | 1.6.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.7.3 | 1.6.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.7.2 | 1.6.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.7.1 | 1.6.1 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.7.0 | 1.6.1 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.6.1 | 1.6.1 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.6.0 | 1.6.1 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.5.0 | 1.6.1 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.4.0 | 1.6.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.3.0 | 1.6.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.2.0 | 1.5.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.1.0 | 1.5.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.0.0 | 1.4.1 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 

# 搭配 Amazon EMR 使用具體化視觀表
<a name="emr-spark-materialized-views"></a>

Amazon EMR 7.12.0 版及更新版本支援在 Glue Data Catalog 中建立和管理 Apache Iceberg AWS 具體化視觀表。具體化檢視是受管資料表，以 Apache Iceberg 格式存放 SQL 查詢的預先計算結果，並隨著基礎來源資料表的變更逐步更新。您可以使用具體化視觀表來簡化資料轉換管道，並加速複雜分析工作負載的查詢效能。

當您在 Amazon EMR 上使用 Spark 建立具體化檢視時，檢視定義和中繼資料會存放在 AWS Glue Data Catalog 中。預先計算的結果會以 Apache Iceberg 資料表的形式儲存在 Amazon S3 Tables 儲存貯體中，或存放在您 AWS 帳戶中的 Amazon S3 一般用途儲存貯體中。Glue Data Catalog AWS 會自動監控來源資料表，並使用受管運算基礎設施重新整理具體化視觀表。

**Topics**
+ [具體化視觀表如何與 Amazon EMR 搭配使用](#emr-spark-materialized-views-how-it-works)
+ [先決條件](#emr-spark-materialized-views-prerequisites)
+ [設定 Spark 以使用具體化視觀表](#emr-spark-materialized-views-configure)
+ [建立具體化視觀表](#emr-spark-materialized-views-create)
+ [查詢具體化視觀表](#emr-spark-materialized-views-query)
+ [重新整理具體化視觀表](#emr-spark-materialized-views-refresh)
+ [管理具體化視觀表](#emr-spark-materialized-views-manage)
+ [具體化視觀表的許可](#emr-spark-materialized-views-permissions)
+ [監控具體化視觀表操作](#emr-spark-materialized-views-monitoring)
+ [範例：完成工作流程](#emr-spark-materialized-views-example)
+ [考量和限制](#emr-spark-materialized-views-limitations)

## 具體化視觀表如何與 Amazon EMR 搭配使用
<a name="emr-spark-materialized-views-how-it-works"></a>

具體化視觀表透過 Apache Spark 的 Iceberg 支援與 Amazon EMR 整合。當您將 Spark 工作階段設定為使用 AWS Glue Data Catalog 時，您可以使用標準 SQL 語法建立具體化檢視。Spark 最佳化工具可以在提供更好的效能時自動重寫查詢，以使用具體化視觀表，無需手動修改應用程式程式碼。

Glue Data Catalog AWS 會處理具體化視觀表維護的所有操作層面，包括：
+ 使用 Apache Iceberg 的中繼資料層偵測來源資料表中的變更
+ 使用受管 Spark 運算排程和執行重新整理操作
+ 根據資料變更決定是否執行完整或增量重新整理
+ 將預先計算的結果儲存為 Apache Iceberg 格式以進行多引擎存取

您可以使用用於一般資料表的相同 Spark SQL 介面，從 Amazon EMR 查詢具體化視觀表。預先計算的資料也可以從其他 服務存取，包括 Amazon Athena 和 Amazon Redshift。

## 先決條件
<a name="emr-spark-materialized-views-prerequisites"></a>

若要搭配 Amazon EMR 使用具體化視觀表，您需要：
+  AWS 帳戶
+ 執行 7.12.0 或更新版本的 Amazon EMR 叢集
+ 在 Glue Data Catalog AWS 中註冊的 Apache Iceberg 格式來源資料表
+ AWS 針對來源資料表和目標資料庫設定的 Lake Formation 許可
+ 向 Lake Formation 註冊的 AWS S3 Tables 儲存貯體或 S3 一般用途儲存貯體，用於存放具體化視觀表資料

## 設定 Spark 以使用具體化視觀表
<a name="emr-spark-materialized-views-configure"></a>

若要建立和管理具體化視觀表，請使用所需的 Iceberg 延伸模組和目錄設定來設定 Spark 工作階段。組態會根據來源資料表和具體化視觀表是否使用 S3 Tables 儲存貯體或 S3 一般用途儲存貯體而有所不同。

### 設定 S3 資料表
<a name="emr-spark-materialized-views-configure-s3-tables"></a>

將 S3 Tables 儲存貯體用於具體化視觀表時，請為來源資料表和具體化視觀表設定個別的目錄參考：

```
spark-sql \
  --conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions \
  --conf spark.sql.catalog.glue_catalog=org.apache.iceberg.spark.SparkCatalog \
  --conf spark.sql.catalog.glue_catalog.type=glue \
  --conf spark.sql.catalog.glue_catalog.warehouse=s3://amzn-s3-demo-bucket/warehouse \
  --conf spark.sql.catalog.glue_catalog.glue.region=us-east-1 \
  --conf spark.sql.catalog.glue_catalog.glue.id=111122223333 \
  --conf spark.sql.catalog.glue_catalog.glue.account-id=111122223333 \
  --conf spark.sql.catalog.glue_catalog.glue.lakeformation-enabled=true \
  --conf spark.sql.catalog.s3t_catalog=org.apache.iceberg.spark.SparkCatalog \
  --conf spark.sql.catalog.s3t_catalog.type=glue \
  --conf spark.sql.catalog.s3t_catalog.glue.id=111122223333:s3tablescatalog/my-table-bucket \
  --conf spark.sql.catalog.s3t_catalog.glue.account-id=111122223333 \
  --conf spark.sql.catalog.s3t_catalog.glue.lakeformation-enabled=true \
  --conf spark.sql.catalog.s3t_catalog.warehouse=s3://amzn-s3-demo-bucket/mv-warehouse \
  --conf spark.sql.catalog.s3t_catalog.glue.region=us-east-1 \
  --conf spark.sql.defaultCatalog=s3t_catalog \
  // turn on automatic query rewrite (optional)
  --conf spark.sql.optimizer.answerQueriesWithMVs.enabled=true
```

### 針對 S3 一般用途儲存貯體設定
<a name="emr-spark-materialized-views-configure-s3-general"></a>

使用 S3 一般用途儲存貯體時，請設定單一目錄參考：

```
spark-sql \
  --conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions \
  --conf spark.sql.catalog.glue_catalog=org.apache.iceberg.spark.SparkCatalog \
  --conf spark.sql.catalog.glue_catalog.type=glue \
  --conf spark.sql.catalog.glue_catalog.warehouse=s3://amzn-s3-demo-bucket/warehouse \
  --conf spark.sql.catalog.glue_catalog.glue.region=us-east-1 \
  --conf spark.sql.catalog.glue_catalog.glue.id=111122223333 \
  --conf spark.sql.catalog.s3t_catalog.glue.account-id=111122223333 \
  --conf spark.sql.catalog.s3t_catalog.glue.lakeformation-enabled=true \
  --conf spark.sql.defaultCatalog=glue_catalog \
  // turn on automatic query rewrite (optional)
  --conf spark.sql.optimizer.answerQueriesWithMVs.enabled=true
```

### 啟用增量重新整理
<a name="emr-spark-materialized-views-configure-incremental"></a>

若要啟用增量重新整理最佳化，請將下列組態屬性新增至 Spark 工作階段：

```
spark-sql \
  --conf spark.sql.optimizer.incrementalMVRefresh.enabled=true \
```

### 組態參數
<a name="emr-spark-materialized-views-configure-parameters"></a>

下列組態參數控制具體化視觀表行為：
+ `spark.sql.extensions` – 啟用具體化視觀表支援所需的 Iceberg Spark 工作階段延伸。
+ `spark.sql.optimizer.answerQueriesWithMVs.enabled` – 啟用自動查詢重寫以使用具體化視觀表。設為 true 以啟用此最佳化。
+ `spark.sql.optimizer.incrementalMVRefresh.enabled` – 啟用增量重新整理最佳化。設為 true 以在重新整理操作期間僅處理已變更的資料。

## 建立具體化視觀表
<a name="emr-spark-materialized-views-create"></a>

您可以使用 CREATE MATERIALIZED VIEW SQL 陳述式建立具體化視觀表。檢視定義會將轉換邏輯指定為參考一或多個來源資料表的 SQL 查詢。

### DLLs
<a name="emr-spark-materialized-views-create-dlls"></a>

**建立檢視**

```
{ CREATE OR REPLACE MATERIALIZED VIEW | CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] }
   view_identifier
  [ view_clauses ]
  [ schedule_clauses ]
  AS [ select_statement ]

view_clauses =
  { [ LOCATION location ] |
    [ PARTITIONED BY (col [, ...]) ] |
    [ COMMENT view_comment ] |
    [ SCHEDULE [ REFRESH ] schedule_clause ] }

schedule_clause =
  { EVERY number { HOUR | HOURS | DAY | DAYS | WEEK | WEEKS } }
```

**注意**  
view\$1clauses 必須出現在 select\$1statement 之前。

### 建立基本具體化視觀表
<a name="emr-spark-materialized-views-create-basic"></a>

下列範例會建立具體化檢視，依客戶彙總訂單資料，在檢視定義中使用具有三個部分命名慣例的完整資料表名稱：

```
CREATE MATERIALIZED VIEW customer_orders
AS 
SELECT 
    customer_name, 
    COUNT(*) as order_count, 
    SUM(amount) as total_amount 
FROM glue_catalog.sales.orders
GROUP BY customer_name;
```

### 使用自動重新整理建立具體化檢視
<a name="emr-spark-materialized-views-create-auto-refresh"></a>

若要設定自動重新整理，請在檢視定義中使用具有三個部分命名慣例的完整資料表名稱建立檢視時指定重新整理排程：

```
CREATE MATERIALIZED VIEW customer_orders
SCHEDULE REFRESH EVERY 1 HOUR
AS 
SELECT 
    customer_name, 
    COUNT(*) as order_count, 
    SUM(amount) as total_amount 
FROM glue_catalog.sales.orders
GROUP BY customer_name;
```

### 使用跨目錄參考建立具體化視觀表
<a name="emr-spark-materialized-views-create-cross-catalog"></a>

當您的來源資料表與具體化檢視位於不同的目錄中時，請在檢視名稱和檢視定義中使用具有三部分命名慣例的完整資料表名稱：

```
CREATE MATERIALIZED VIEW s3t_catalog.analytics.customer_summary
AS 
SELECT 
    customer_name, 
    COUNT(*) as order_count, 
    SUM(amount) as total_amount 
FROM glue_catalog.sales.orders
GROUP BY customer_name;
```

## 查詢具體化視觀表
<a name="emr-spark-materialized-views-query"></a>

建立具體化檢視後，您可以使用標準 SQL SELECT 陳述式，像任何其他資料表一樣進行查詢：

```
SELECT * FROM customer_orders;
```

### 自動查詢重寫
<a name="emr-spark-materialized-views-query-rewrite"></a>

啟用自動查詢重寫時，Spark 最佳化工具會分析您的查詢，並在可以改善效能時自動使用具體化視觀表。例如，如果您執行下列查詢：

```
SELECT 
    customer_name, 
    COUNT(*) as order_count, 
    SUM(amount) as total_amount 
FROM orders
GROUP BY customer_name;
```

Spark 最佳化工具會自動重寫此查詢，以使用 customer\$1orders 具體化檢視，而不是處理基礎訂單資料表，前提是具體化檢視是最新的。

### 驗證自動查詢重寫
<a name="emr-spark-materialized-views-query-verify"></a>

若要驗證查詢是否使用自動查詢重寫，請使用 EXPLAIN EXTENDED 命令：

```
EXPLAIN EXTENDED
SELECT customer_name, COUNT(*) as order_count, SUM(amount) as total_amount 
FROM orders
GROUP BY customer_name;
```

在執行計畫中，尋找 BatchScan 操作中的具體化檢視名稱。如果計劃顯示 BatchScan glue\$1catalog.analytics.customer\$1orders，而不是 BatchScan glue\$1catalog.sales.orders，則查詢會自動重新寫入，以使用具體化視觀表。

**注意**  
自動查詢重寫需要時間，Spark 中繼資料快取才能在建立具體化檢視之後填入。此程序通常會在 30 秒內完成。

## 重新整理具體化視觀表
<a name="emr-spark-materialized-views-refresh"></a>

您可以使用兩種方法重新整理具體化視觀表：完全重新整理或增量重新整理。完整重新整理會從所有基礎資料表資料重新計算整個具體化檢視，而增量重新整理只會處理自上次重新整理以來變更的資料。

### 手動完整重新整理
<a name="emr-spark-materialized-views-refresh-full"></a>

若要完整重新整理具體化視觀表：

```
REFRESH MATERIALIZED VIEW customer_orders FULL;
```

執行此命令後，請查詢具體化檢視以驗證更新的結果：

```
SELECT * FROM customer_orders;
```

### 手動增量重新整理
<a name="emr-spark-materialized-views-refresh-incremental"></a>

若要執行增量重新整理，請確定已在 Spark 工作階段組態中啟用增量重新整理，然後執行：

```
REFRESH MATERIALIZED VIEW customer_orders;
```

 AWS Glue Data Catalog 會根據檢視定義和變更的資料量，自動判斷增量重新整理是否適用。如果無法進行增量重新整理，操作會回到完全重新整理。

### 驗證增量重新整理執行
<a name="emr-spark-materialized-views-refresh-verify"></a>

若要確認已成功執行增量重新整理，您可以執行下列命令來檢查`lastRefreshType`資料表屬性：

```
SHOW TBLPROPERTIES <mvName>("lastRefreshType")
```

此外，您也可以透過修改 Spark 日誌組態來啟用偵錯記錄來達成此目的：

1. 開啟 Spark log4j 組態檔案：

   ```
   sudo vim /usr/lib/spark/conf/log4j2.properties
   ```

1. 新增下列記錄器組態：

   ```
   logger.spark.name = org.apache.spark.sql
   logger.spark.level = debug
   
   logger.inmemcache.name = org.apache.spark.sql.InMemMvMetadataCache
   logger.inmemcache.level = off
   ```

1. 執行重新整理操作後，請在 Spark 輸出中搜尋下列訊息：

   ```
   DEBUG RefreshMaterializedViewExec: Executed Incremental Refresh
   ```

## 管理具體化視觀表
<a name="emr-spark-materialized-views-manage"></a>

Amazon EMR 提供 SQL 命令來管理具體化視觀表的生命週期。

### 描述具體化視觀表
<a name="emr-spark-materialized-views-manage-describe"></a>

若要檢視具體化檢視的中繼資料，包括其定義、重新整理狀態和上次重新整理時間戳記：

```
DESCRIBE EXTENDED customer_orders;
```

### 變更具體化視觀表
<a name="emr-spark-materialized-views-manage-alter"></a>

若要修改現有具體化檢視的重新整理排程：

```
ALTER MATERIALIZED VIEW customer_orders 
ADD SCHEDULE REFRESH EVERY 2 HOURS;
```

若要移除自動重新整理：

```
ALTER MATERIALIZED VIEW customer_orders 
DROP SCHEDULE;
```

### 捨棄具體化視觀表
<a name="emr-spark-materialized-views-manage-drop"></a>

若要刪除具體化視觀表：

```
DROP MATERIALIZED VIEW customer_orders;
```

此命令會從 Glue Data Catalog AWS 中移除具體化檢視定義，並從 S3 儲存貯體中刪除基礎 Iceberg 資料表資料。

## 具體化視觀表的許可
<a name="emr-spark-materialized-views-permissions"></a>

若要建立和管理具體化視觀表，您必須設定 AWS Lake Formation 許可。建立具體化檢視的 IAM 角色 （定義者角色） 需要來源資料表和目標資料庫的特定許可。

### 定義者角色的必要許可
<a name="emr-spark-materialized-views-permissions-definer"></a>

定義者角色必須具有下列 Lake Formation 許可：
+ 在來源資料表上 – 沒有資料列、資料欄或儲存格篩選條件的 SELECT 或 ALL 許可
+ 在目標資料庫上 – CREATE\$1TABLE 許可
+ 在 AWS Glue Data Catalog 上 – GetTable 和 CreateTable API 許可

當您建立具體化檢視時，定義者角色的 ARN 會存放在檢視定義中。執行自動重新整理操作時， AWS Glue Data Catalog 會擔任此角色。如果定義者角色無法存取來源資料表，重新整理操作將會失敗，直到許可還原為止。

### 授予具體化視觀表的存取權
<a name="emr-spark-materialized-views-permissions-access"></a>

若要授予其他使用者查詢具體化視觀表的存取權，請使用 AWS Lake Formation 授予具體化視觀表的 SELECT 許可。使用者可以查詢具體化視觀表，而不需要直接存取基礎來源資料表。

如需設定 Lake Formation 許可的詳細資訊，請參閱 AWS Lake Formation 開發人員指南中的授予和撤銷 Data Catalog 資源的許可。

## 監控具體化視觀表操作
<a name="emr-spark-materialized-views-monitoring"></a>

 AWS Glue Data Catalog 會將具體化檢視重新整理操作的指標和日誌發佈至 Amazon CloudWatch。您可以監控透過 CloudWatch 指標處理的重新整理狀態、持續時間和資料磁碟區。

### 檢視重新整理指標
<a name="emr-spark-materialized-views-monitoring-metrics"></a>

若要檢視具體化檢視重新整理指標：

1. 開啟 CloudWatch 主控台。

1. 從導覽窗格中選擇指標。

1. 選取 Glue (Glue) 命名空間。

1. 依具體化檢視名稱篩選指標。

### 設定警示
<a name="emr-spark-materialized-views-monitoring-alarms"></a>

若要在重新整理操作失敗或超過預期持續時間時接收通知，請在具體化檢視指標上建立 CloudWatch 警示。您也可以設定 Amazon EventBridge 規則來觸發重新整理事件的自動回應。

## 範例：完成工作流程
<a name="emr-spark-materialized-views-example"></a>

下列範例示範在 Amazon EMR 上建立和使用具體化檢視的完整工作流程。

1. 使用 SSH 連線至 EMR 叢集主節點。

1. 使用範例資料建立基礎資料表：

   ```
   spark-sql \
     --conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions \
     --conf spark.sql.catalog.glue_catalog=org.apache.iceberg.spark.SparkCatalog \
     --conf spark.sql.catalog.glue_catalog.type=glue \
     --conf spark.sql.catalog.glue_catalog.warehouse=s3://amzn-s3-demo-bucket/warehouse \
     --conf spark.sql.catalog.glue_catalog.glue.region=us-east-1 \
     --conf spark.sql.catalog.glue_catalog.glue.id=111122223333 \
     --conf spark.sql.catalog.glue_catalog.glue.account-id=111122223333 \
     --conf spark.sql.catalog.glue_catalog.glue.lakeformation-enabled=true \
     --conf spark.sql.defaultCatalog=glue_catalog \
     --conf spark.sql.optimizer.answerQueriesWithMVs.enabled=true 
   
   
   CREATE DATABASE IF NOT EXISTS sales;
   
   USE sales;
   
   CREATE TABLE orders (
       id INT,
       customer_name STRING,
       amount DECIMAL(10,2),
       order_date DATE
   );
   
   INSERT INTO orders VALUES 
       (1, 'John Doe', 150.00, DATE('2024-01-15')),
       (2, 'Jane Smith', 200.50, DATE('2024-01-16')),
       (3, 'Bob Johnson', 75.25, DATE('2024-01-17'));
   ```

1. 建立具體化視觀表：

   ```
   CREATE MATERIALIZED VIEW customer_summary
   AS 
   SELECT 
       customer_name, 
       COUNT(*) as order_count, 
       SUM(amount) as total_amount 
   FROM glue_catalog.sales.orders
   GROUP BY customer_name;
   ```

1. 查詢具體化視觀表：

   ```
   SELECT * FROM customer_summary;
   ```

1. 將其他資料插入基底資料表：

   ```
   INSERT INTO orders VALUES 
       (4, 'Jane Smith', 350.00, DATE('2024-01-18')),
       (5, 'Bob Johnson', 100.25, DATE('2024-01-19'));
   ```

1. 重新整理具體化視觀表：

   ```
   REFRESH MATERIALIZED VIEW customer_summary FULL;
   ```

1. 驗證更新的結果：

   ```
   SELECT * FROM customer_summary;
   ```

## 考量和限制
<a name="emr-spark-materialized-views-limitations"></a>

搭配 Amazon EMR 使用具體化視觀表時，請考慮下列事項：
+ 具體化視觀表需要 Amazon EMR 7.12.0 或更新版本。
+ 來源資料表必須是在 Glue Data Catalog 中註冊的 Apache Iceberg AWS 資料表。啟動時不支援 Apache Hive、Apache Hudi 和 Linux Foundation Delta Lake 資料表。
+ 來源資料表必須位於與具體化視觀表相同的 AWS 區域和 AWS 帳戶中。
+ 所有來源資料表都必須受 AWS Lake Formation 管理。不支援僅限 IAM 的許可和混合存取。
+ 具體化視觀表無法參考 AWS Glue Data Catalog 檢視、多方視觀表或其他具體化視觀表作為來源資料表。
+ 檢視定義者角色必須在未套用資料列、資料欄或儲存格篩選條件的所有來源資料表上具有完整讀取存取權 (SELECT 或 ALL 許可）。
+ 具體化視觀表最終與來源資料表一致。在重新整理時段期間，查詢可能會傳回過時的資料。執行手動重新整理以立即保持一致。
+ 最短自動重新整理間隔為一小時。
+ 增量重新整理支援 SQL 操作的限制子集。檢視定義必須是單一 SELECT-FROM-WHERE-GROUP BY-HAVING 區塊，而且不能包含設定操作、子查詢、SELECT 或彙總函數中的 DISTINCT 關鍵字、視窗函數或 INNER JOIN 以外的聯結。
+ 增量重新整理不支援使用者定義的函數或特定內建函數。僅支援 Spark SQL 內建函數的子集。
+ 查詢自動重寫只會考慮具體化視觀表，其定義屬於與增量重新整理限制類似的受限 SQL 子集。
+ 完整重新整理操作會覆寫整個資料表，並使先前的快照無法使用。
+ CREATE MATERIALIZED VIEW 查詢不支援包含英數字元和底線以外的特殊字元的識別符。
+ 以 \$1\$1ivm 字首開頭的具體化檢視資料欄會保留給系統使用。 AWS 保留在未來版本中修改或移除這些資料欄的權利。
+ 具體化視觀表定義中不支援 SORT BY、LIMIT、OFFSET、CLUSTER BY 和 ORDER BY 子句。
+ 不支援跨區域和跨帳戶來源資料表。
+ 具體化視觀表定義不支援非確定性函數，例如 rand() 或 current\$1timestamp()。