

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

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

[Apache Spark](https://aws.amazon.com/emr/features/spark/) は、Amazon EMR クラスターでの機械学習、ストリーム処理、グラフ分析に役立つ分散処理フレームワークおよびプログラミングモデルです。Apache Spark は、Apache Hadoop と同様に、ビッグデータのワークロードを処理するために一般的に使用されているオープンソースの分散処理システムです。ただし、Spark には Hadoop MapReduce との大きな違いがいくつかあります。Spark は、最適化された Directed Acyclic Graph (DAG) 実行エンジンを備えており、データをインメモリにアクティブにキャッシュするため、特に特定のアルゴリズムやインタラクティブクエリの場合にパフォーマンスが向上します。

Spark アプリケーションは、Scala、Java、および Python をネイティブでサポートしています。また、SQL (「[Spark](https://spark.apache.org/sql/)」)、機械学習 (「[MLlib](https://spark.apache.org/mllib/)」)、ストリーム処理 (「[Spark Streaming](https://spark.apache.org/streaming/)」)、グラフ処理 (「[GraphX](https://spark.apache.org/graphx/)」) 用の緊密に統合されたライブラリもいくつか含まれています。これらのツールを使用すると、さまざまなユースケースで Spark フレームワークを活用しやすくなります。

Spark は、他の Hadoop アプリケーションと同時に Amazon EMR クラスターにインストールすることができ、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 Serverless 上の EMR 上の Apache Spark アプリケーションのトラブルシューティングを行うことができます。詳細については、「」を参照してください[Amazon EMR の Apache Spark トラブルシューティングエージェントとは](spark-troubleshoot.md)。

**重要**  
Apache Spark バージョン 2.3.1 は Amazon EMR リリース 5.16.0 以降で利用でき、[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 と共にインストールされるコンポーネントのバージョンについては、「[Release 5.36.2 Component Versions](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)
+ [Amazon EMR AWS で Spark で Glue データカタログカタログを使用する](emr-spark-glue.md)
+ [Amazon EMR で Spark を使用して AWS Glue Data Catalog でマルチカタログ階層を操作する](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 アクセラレータの使用](emr-spark-rapids.md)
+ [Spark シェルにアクセスする](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 ウェブ UI にアクセスする](emr-spark-webui.md)
+ [Spark 構造化ストリーミング Amazon Kinesis Data Streams コネクタの使用](emr-spark-structured-streaming-kinesis.md)
+ [Amazon EMR での Apache Spark 用の Amazon Redshift インテグレーションの使用](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/) がインストールされたクラスターを作成します。

**[Advanced Options]** (詳細オプション) を使用してクラスター設定を詳細にカスタマイズしたり、アプリケーションをプログラムでインストールするステップを送信してカスタムアプリケーションを実行したりすることもできます。どちらのクラスター作成オプションでも、Spark SQL メタストアとして AWS Glue を使用するように選択できます。詳細については「[Amazon EMR AWS で Spark で Glue データカタログカタログを使用する](emr-spark-glue.md)」を参照してください。

**Spark がインストールされたクラスターを起動するには**

1. [https://console.aws.amazon.com/emr](https://console.aws.amazon.com/emr/) で Amazon EMR コンソールを開きます。

1. **[Create cluster]** (クラスターの作成) を選択して、**[Quick Options]** (クイックオプション) を使用します。

1. **[Cluster name]** (クラスター名) を入力します。クラスター名に <、>、\$1、\$1、` (バックティック) の文字を含めることはできません。

1.  **[Software Configuration]** (ソフトウェア設定) では、**[Release]** (リリース) オプションを選択します。

1.  **[Applications]** (アプリケーション) では、**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 の場合、削除するか、キャレット (^) に置き換えてください。

**SDK for Java を使用し、Spark がインストールされたクラスターを起動するには**

`SupportedProductConfig` で使用される `RunJobFlowRequest` を使用して Spark をアプリケーションとして指定します。
+ 次の例は、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 インスタンスに依存関係をインストールする必要はありません。Docker で Spark を実行するには、まず 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 レジストリは、分類 API を使用して定義する必要があります。クラスターの起動時に `container-executor` 分類キーを使用して追加のパラメータを定義します。
  + `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 を使用します。このファイルは、イメージに含めるパッケージと設定を定義します。次に示す 2 つの 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 イメージを使用するように認証を設定する必要があります。詳細については、「[Amazon ECR](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-docker.html#emr-docker-ECR) にアクセスするための YARN の設定」を参照してください。

Amazon ECR に保存されているイメージに Amazon EMR ホストがアクセスできるようにするには、インスタンスプロファイルに関連付けられた `AmazonEC2ContainerRegistryReadOnly` ポリシーからのアクセス許可がクラスターに必要です。詳細については、「[`AmazonEC2ContainerRegistryReadOnly` ポリシー](https://docs.aws.amazon.com/AmazonECR/latest/userguide/ecr_managed_policies.html#AmazonEC2ContainerRegistryReadOnly)」を参照してください。

この例では、Amazon ECR レジストリが信頼されるように、次の追加設定を使用してクラスターを作成する必要があります。*123456789123.dkr.ecr.us-east-1.amazonaws.com* エンドポイントを、実際の Amazon ECR エンドポイントに置き換えます。

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

**Amazon ECR での PySpark の使用**

次の例では PySpark Dockerfile を使用します。このファイルは、タグ付けされて Amazon ECR にアップロードされます。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 にアップロードし、*123456789123.dkr.ecr.us-east-1.amazonaws.com* を実際の ECR エンドポイントに置き換えます。

```
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` は Amazon ECR への認証に使用する認証情報が含まれている `config.json` ファイルを参照する必要があります。

```
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]]
```

**Amazon ECR での SparkR の使用**

次の例では、SparkR Dockerfile にタグを付けて ECR にアップロードします。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 にアップロードし、*123456789123.dkr.ecr.us-east-1.amazonaws.com* を実際の Amazon ECR エンドポイントに置き換えます。

```
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` は ECR への認証に使用する認証情報が含まれている `config.json` ファイルを参照する必要があります。

```
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:
```

# Amazon EMR AWS で Spark で Glue データカタログカタログを使用する
<a name="emr-spark-glue"></a>

Amazon EMR リリース 5.8.0 以降を使用すると、Apache Hive メタストアとして AWS Glue データカタログを使用するように Spark を設定できます。永続的な Hive メタストア、または異なるクラスター、サービス、アプリケーション、または AWS アカウントによって共有される Hive メタストアが必要な場合は、この設定をお勧めします。

Amazon EMR リリース 6.5.0 以降を使用して、Apache Iceberg で AWS Glue データカタログを使用するように Spark を設定できます。

Amazon EMR リリース 7.5.0 以降を使用すると、 Glue データカタログを Iceberg REST カタログとして使用するように AWS Spark を設定できます。

AWS Glue はフルマネージド型の抽出、変換、ロード (ETL) サービスで、データの分類、クリーンアップ、強化、さまざまなデータストア間の信頼性の高い移動をシンプルかつ費用対効果の高い方法で実現します。 AWS Glue Data Catalog は、Amazon EMR、Amazon RDS、Amazon Redshift、Redshift Spectrum、Athena、および Apache Hive メタストアと互換性のある任意のアプリケーションと統合して、さまざまなデータソースとデータ形式にわたって統合されたメタデータリポジトリを提供します。 AWS Glue クローラは、Amazon S3 のソースデータからスキーマを自動的に推測し、関連するメタデータをデータカタログに保存できます。データカタログの詳細については、[AWS 「 Glue デベロッパーガイド」の「 Glue データカタログ](https://docs.aws.amazon.com/glue/latest/dg/populate-data-catalog.html)の入力」を参照してください。 *AWS *

Glue AWS には個別の料金が適用されます。データカタログにメタデータを保存してアクセスするための月額料金、Glue ETL AWS ジョブとクローラランタイムに対して 1 分あたりに課金される時間料金、プロビジョニングされた開発エンドポイントごとに 1 分あたりに課金される時間料金があります。Data Catalog では、最大 100 万個までのオブジェクトを無料で保存できます。100 万を超えるオブジェクトを保存した場合は、100,000 オブジェクトごとに 1 USD が課金されます。Data Catalog 内のオブジェクトは、テーブル、パーティション、またはデータベースです。詳細については、「[Glue 料金表](https://aws.amazon.com/glue/pricing)」を参照してください。

**重要**  
2017 年 8 月 14 日より前に Amazon Athena または Amazon Redshift Spectrum を使用してテーブルを作成した場合、データベースとテーブルは AWS Glue データカタログとは別の Athena 管理カタログに保存されます。Amazon EMR をこれらのテーブルと統合するには、 AWS Glue データカタログにアップグレードする必要があります。詳細については、[「Amazon Athena ユーザーガイド」の「 AWS Glue データカタログへのアップグレード](https://docs.aws.amazon.com/athena/latest/ug/glue-upgrade.html)」を参照してください。 *Amazon Athena *

## AWS Glue データカタログを Apache Hive メタストアとして指定する
<a name="emr-spark-glue-configure"></a>

、、または Amazon EMR API を使用して AWS マネジメントコンソール AWS CLI、 AWS Glue データカタログをメタストアとして指定できます。CLI または API を使用する場合は、Spark の設定分類を使用してデータカタログを指定します。さらに、Amazon EMR 5.16.0 以降では、設定分類を使用して別の でデータカタログを指定できます AWS アカウント。コンソールを使用する場合は、**[Advanced Options]** (詳細オプション) または **[Quick Options]** (クイックオプション) を使用して、Data Catalog を指定できます。

**注記**  
Zeppelin は Spark AWS コンポーネントと共にインストールされるため、 Glue Data Catalog を使用するオプションは Zeppelin でも使用できます。

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

**新しいコンソールで AWS Glue データカタログを Apache Hive メタストアとして指定するには**

1. にサインインし AWS マネジメントコンソール、[https://console.aws.amazon.com/emr](https://console.aws.amazon.com/emr) で Amazon EMR コンソールを開きます。

1. 左側のナビゲーションペインの **[Amazon EMR on EC2]** で、**[クラスター]** を選択し、**[クラスターの作成]** を選択します

1. **[アプリケーションバンドル]** で **[Spark]** または **[カスタム]** を選択します。クラスターをカスタマイズする場合は、必ず Zeppelin または Spark をアプリケーションの 1 つとして選択します。

1. **[AWS Glue Data Catalog 設定]** で **[Spark テーブルメタデータに使用]** チェックボックスをオンにします。

1. クラスターに適用するその他のオプションを選択します。

1. クラスターを起動するには、**[クラスターの作成]** を選択します。

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

**で AWS Glue データカタログを 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"
      }
    }
  ]
  ```

  別の AWS アカウントでデータカタログを指定するには、次の例に示すように `hive.metastore.glue.catalogid`プロパティを追加します。`acct-id` は、データカタログの AWS アカウントに置き換えます。

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

------

## AWS Glue データカタログを Apache Iceberg カタログとして指定する
<a name="emr-spark-glue-configure-iceberg"></a>

 AWS Glue データカタログは、、、Amazon EMR API、または Spark セッションランタイム設定を使用して、Apache Iceberg カタログ実装 AWS マネジメントコンソール AWS CLI、または Apache Iceberg REST カタログエンドポイントとして指定できます。CLI または API を使用する場合は、Spark の設定分類を使用してデータカタログを指定します。詳細については、[「Apache Iceberg カタログとしての AWS Glue データカタログの指定](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 アクションの AWS IAM アクセス許可が必要です。さらに、 Glue Data Catalog オブジェクト AWS の暗号化を有効にする場合、ロールには暗号化 AWS KMS key に使用される の暗号化、復号、生成も許可する必要があります。

### Glue AWS アクションのアクセス許可
<a name="emr-hive-glue-permissions-actions"></a>

Amazon EMR の デフォルトの EC2 インスタンスプロファイルを使用する場合、アクションは必要ありません。にアタッチされている `AmazonElasticMapReduceforEC2Role`マネージドポリシーは、必要なすべての Glue AWS アクション`EMR_EC2_DefaultRole`を許可します。ただし、カスタム 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 オブジェクトの暗号化を有効にします。
+  AWS Glue データカタログ AWS アカウント と同じ にあるクラスターを使用します。

それ以外の場合は、EC2 インスタンスプロファイルにアタッチされたアクセス許可ポリシーに次のステートメントを追加する必要があります。

Glue データカタログ AWS の暗号化の詳細については、*AWS 「 Glue デベロッパーガイド*[」の「データカタログの暗号化](https://docs.aws.amazon.com/glue/latest/dg/encrypt-glue-data-catalog.html)」を参照してください。

### リソースベースのアイデンティティアクセス許可
<a name="emr-hive-glue-permissions-resource"></a>

Amazon EMR で AWS Glue を Hive、Spark、または Presto と組み合わせて使用する場合、 AWS Glue は Data Catalog リソースへのアクセスを制御するためのリソースベースのポリシーをサポートします。これらのリソースには、データベース、テーブル、接続、ユーザー定義関数が含まれます。詳細については、「*AWS Glue デベロッパーガイド*」の「[AWS Glue リソースポリシー](https://docs.aws.amazon.com/glue/latest/dg/glue-resource-policies.html)」を参照してください。

リソースベースのポリシーを使用して Amazon EMR 内から AWS Glue へのアクセスを制限する場合、アクセス許可ポリシーで指定するプリンシパルは、クラスターの作成時に指定する EC2 インスタンスプロファイルに関連付けられたロール ARN である必要があります。例えば、カタログにアタッチされたリソースベースのポリシーの場合、以下の例に示されている形式を使用して、クラスター EC2 インスタンスのデフォルトサービスロールのロール ARN である *EMR\$1EC2\$1DefaultRole* を `Principal` として指定できます。

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

*acct-id* は Glue アカウント ID AWS とは異なる場合があります。これにより、さまざまなアカウントで EMR クラスターからアクセスできます。異なるアカウントから、複数のプリンシパルを指定できます。

## Glue データカタログを使用する際 AWS の考慮事項
<a name="emr-hive-glue-considerations-hive"></a>

Spark AWS で Glue データカタログを Apache Hive メタストアとして使用する場合は、次の項目を考慮してください。
+ 場所の URI が指定されていないデフォルトデータベースを使用すると、テーブルの作成時に障害が発生します。回避策として、`LOCATION` の使用時に `s3://amzn-s3-demo-bucket1` 句を使用して `CREATE TABLE` などのバケットの場所を指定します。または、デフォルトデータベース以外のデータベース内にテーブルを作成します。
+ Glue AWS 内からのテーブルの名前変更はサポートされていません。
+ `LOCATION` を指定せずに Hive テーブルを作成すると、テーブルデータは、`hive.metastore.warehouse.dir` プロパティによって指定された場所に保管されます。デフォルトでは、これは HDFS 内の場所です。別のクラスターがテーブルにアクセスする必要がある場合、テーブルを作成したクラスターに対する適切なアクセス許可がない限り、処理に失敗します。さらに、HDFS ストレージは一時的であるため、クラスターが終了すると、テーブルデータは失われ、テーブルを再作成する必要があります。Glue を使用して Hive テーブルを作成するときは、Amazon S3 AWS `LOCATION`で を指定することをお勧めします。または、`hive-site` 設定分類を使用して、`hive.metastore.warehouse.dir` の Amazon S3 で場所を指定できます。これは、すべての Hive テーブルに適用されます。テーブルが HDFS ロケーションで作成され、テーブルを作成したクラスターがまだ実行されている場合は、 Glue 内からテーブルロケーションを Amazon S3 AWS に更新できます。詳細については、「 [AWS Glue デベロッパーガイド」の「 Glue コンソールでのテーブルの操作](https://docs.aws.amazon.com/glue/latest/dg/console-tables.html)」を参照してください。 *AWS *
+ 引用符とアポストロフィを含むパーティション値はサポートされていません(例: `PARTITION (owner="Doe's").`)。
+ [列統計](https://cwiki.apache.org/confluence/display/Hive/StatsDev#StatsDev-ColumnStatistics)は、emr-5.31.0 以降でサポートされています。
+ [Hive 認可](https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Authorization)の使用はサポートされていません。代替策として、[AWS Glue リソースベースのポリシー](https://docs.aws.amazon.com/glue/latest/dg/glue-resource-policies.html)を使用することを検討してください。詳細については、「Use [Resource-Based Policies for Amazon EMR Access to AWS Glue Data Catalog](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-iam-roles-glue.html)」を参照してください。

Spark AWS で Apache Iceberg REST Catalog として Glue データカタログを使用する場合は、次の点を考慮してください。
+ 「[Iceberg SparkCatalog と SparkSessionCatalog を使用する場合の設定の違い](emr-iceberg-use-spark-cluster.md#emr-iceberg-spark-catalog)」で説明されている Iceberg で Spark セッションカタログを使用する場合は、 AWS Glue Data Catalog を Apache Iceberg REST カタログとして設定するだけでなく、 AWS Glue Data Catalog を Apache Hive メタストアとして設定する必要があります。
+  AWS Glue データカタログ IRC エンドポイントは、Amazon SigV4 認証スキームのみをサポートします。OAuth はサポートされていません。OAuth ユーザーの場合は、IAM Identity Center を使用してアクセスを設定してください。「[Connecting Lake Formation with IAM Identity Center](https://docs.aws.amazon.com/lake-formation/latest/dg/connect-lf-identity-center.html)」を参照してください。
+  AWS Glue Iceberg REST カタログは、オープンソースのすべてのオペレーションをサポートしているわけではありません。

# Amazon EMR で Spark を使用して AWS Glue Data Catalog でマルチカタログ階層を操作する
<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 Athena とその他のデータ指向サービス (Amazon EMR、Amazon Athena、Amazon Redshift など) で使用できます。

## カタログリソースの整理方法
<a name="emr-lakehouse-org"></a>

 AWS Glue データカタログでリソースを作成すると、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 ツールをサポートするようにカタログを設定します。 AWS Glue データカタログは、Hive メタストア互換性と Iceberg REST 互換 APIs。

**Hive メタストアを使用した Amazon EMR の設定**

 これを設定する方法については、「 [AWS Glue ユーザーガイド」の「Spark ジョブの Glue データカタログのサポート](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-glue-data-catalog-hive.html)」を参照してください。 AWS このトピックでは、 Glue Data Catalog AWS を Hive メタストアとして設定し、エンドポイントとして利用できるようにする方法について説明します。さらに、Spark AWS の [Apache Hive メタストアとして Glue データカタログを使用するで、Spark メタストアとして AWS Glue データカタログを指定する方法を示す Amazon EMR ドキュメントも用意されています](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 ポリシー要件について説明します。クラスターを AWS Glue データカタログに登録した後、後で作成されたデータカタログの作成と変更を検出するには、次のアクセス許可が必要です。
+ **glue:GetCatalog**
+ **glue:GetCatalog**
+ **sts:AssumeRole**
+ **sts:TagSession**
+ **sts:SetContext**
+ **sts:SetSourceIdentity**

ほとんどの場合、アクセス許可を割り当てるときは、IAM ロールを作成してアクセス許可を割り当てることをお勧めします。

加えて、カタログデータをクエリするには、まず AWS Lake Formationを使用して、データカタログに対するアクセス許可を設定する必要があります。 AWS Lake Formationでデータカタログのアクセス許可を設定する方法の詳細については、「[Granting and revoking permissions on Data Catalog resources](https://docs.aws.amazon.com/lake-formation/latest/dg/granting-catalog-permissions.html)」を参照してください。

クラスターを作成して設定し、カタログオブジェクトに対するアクセス許可を設定したら、データをクエリおよび処理するためのジョブを送信できます。

## Glue Data Catalog でマルチカタログ階層にアクセスするように Spark AWS を設定する
<a name="emr-lakehouse-using-spark-access"></a>

EMR 7.5 では、 Glue のマルチカタログ階層を使用するように Spark AWS を設定できます。マルチカタログ階層を使用することにより、以下のことが可能になります:
+ テーブル、ビュー、マテリアライズドビューなどの Redshift マネージドストレージ (RMS) データを既存の Amazon Redshift データウェアハウスから AWS Glue データカタログに取り込みます。EC2 および EMR Serverless の EMR を使用して、これらのオブジェクトをクエリできます。
+ RMS カタログを作成し、データカタログを AWS グルー化し、ZeroETL を使用して RMS にデータを保存し、Iceberg 互換クエリエンジンでデータをクエリします。
+ 圧縮、スナップショット、保持を含むフル機能のストレージ管理を使用して、 Glue Data Catalog AWS にマネージド Iceberg テーブルを作成します。

### Spark セッションを初期化する時にマルチカタログに接続する
<a name="emr-iceberg-initialize-spark-session-spark"></a>

次の例は、インタラクティブな Spark シェル、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 シェルを起動します。PySpark シェルを使用するには、`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 管理ガイド*」の「[Use EMR Notebooks magics](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 データカタログを使用して Redshift マネージドストレージへの Spark 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 Managed Storage with 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 でマルチカタログ階層を使用することにより、`SparkSessionCatalog` を使用する場合、Apache Hive メタストアへのフォールバックをサポートできません。
+ ランタイムロールを持つ 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 Configuration](https://spark.apache.org/docs/latest/configuration.html)」を参照してください。
+ **`spark-env`** - `spark-env.sh` ファイルに値を設定します。詳細については、Spark ドキュメントの「[Environment Variables](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 ドキュメントの [Metrics](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>

次の表はアプリケーションに影響する `spark-defaults` で Amazon EMR がどのようにデフォルト値を設定するか示しています。


**Amazon EMR で設定される Spark のデフォルト**  

| 設定 | 説明 | デフォルトの値 | 
| --- | --- | --- | 
| spark.executor.memory | エグゼキュタープロセスごとに使用するメモリ量。例: `1g`、`2g`。 |  この設定は、クラスター内のコアインスタンスタイプとタスクインスタンスタイプによって決まります。  | 
| spark.executor.cores | 各エグゼキュターに使用するコアの数。 | この設定は、クラスター内のコアインスタンスタイプとタスクインスタンスタイプによって決まります。 | 
| spark.dynamicAllocation.enabled | true の場合、動的なリソース割り当てを使用して、ワークロードによって、アプリケーションで登録するエグゼキュターの数を調整します。 |  `true` (Amazon EMR 4.4.0 以降を使用)  Spark Shuffle Service は Amazon EMR によって自動的に設定されます。   | 
| 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.0 とガーベッジコレクション設定で競合が生じるため、Amazon EMR 6.1 でのドライバーまたはエグゼキューター起動が失敗します。Amazon EMR 6.1.0 の場合、デフォルトのガベージコレクション設定は `spark.driver.defaultJavaOptions` および `spark.executor.defaultJavaOptions` を介して設定されます。この設定は、Amazon EMR 6.1.0 にのみ適用されます。ガーベッジコレクションに関連しない JVM オプション (ロギングの設定用のオプションなど (`-verbose:class`)) は、`extraJavaOptions` で設定できます。詳細については、「[Spark application properties](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` が有効になっている場合)**  

| 設定 | 説明 | 値 | 
| --- | --- | --- | 
| spark.default.parallelism | ユーザーによって設定されていない場合に join、reduceByKey、parallelize などの変換によって返される、RDD のデフォルトパーティション数。 |  YARN コンテナで使用可能な CPU コアの数 (2 の倍数)。  | 
| spark.driver.memory | ドライバープロセス (SparkContext が初期化されている場合) に使用するメモリの量 (例: 1g、2g) |  設定は、クラスター内のスレーブインスタンスタイプに基づいて定義されます。ただし、Spark ドライバーアプリケーションは、プライマリインスタンスまたはいずれかのコアインスタンスで (例えば、YARN クライアントモードとクラスターモードのそれぞれで) 実行されるため、この設定は、これらの 2 つのインスタンスグループ間で、小さい方のインスタンスタイプに基づいて定義されます。  | 
| 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 に拒否リストメカニズムを実装しています。これは YARN の停止メカニズムに基づいて構築されています。このメカニズムにより、停止中のノードで新しいタスクがスケジュールされないようにし、同時に、既に実行中のタスクを完了するようにします。さらに、ノードの終了時にシャッフルブロックが失われた場合に、Spark のジョブを迅速に回復するための機能があります。再計算プロセスはすぐに実行され、より少ないステージの再試行でより迅速に再計算を行うように最適化されます。シャッフルブロックが見つからないことにより発生するフェッチのエラーによるジョブの失敗を避けることができます。

**重要**  
Amazon EMR リリース 5.11.0 に `spark.decommissioning.timeout.threshold` 設定が追加され、スポットインスタンスを使用する場合の Spark の耐障害性が向上しました。これまでのリリースでは、ノードがスポットインスタンスを使用していて、インスタンスが入札価格のために終了した場合、Spark は終了を適切に処理できない場合があります。ジョブが失敗する場合があり、シャッフルの再計算に長い時間がかかる場合があります。このため、スポットインスタンスを使用する場合は、リリース 5.11.0 以降を使用することをお勧めします。


**Spark のノード停止の設定**  

| 設定 | 説明 | デフォルトの値 | 
| --- | --- | --- | 
|  `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` の指定に従って) クリーンアップします。これにより、スポットインスタンスが `yarn.resourcemager.decommissioning.timeout` の値にかかわらず 20 秒以内にタイムアウトするため、Spark がスポットインスタンスの終了をより良く処理できます。ただし、他のノードがシャッフルファイルを読み取るための時間が足りない場合があります。  |  `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 Server Port 環境変数である `HIVE_SERVER2_THRIFT_PORT` が 10001 に設定されます。

## Spark のデフォルト設定の変更
<a name="spark-change-defaults"></a>

`spark-defaults` 設定分類を使用して、`spark-defaults.conf` 内のデフォルトを変更するか、`spark` 設定分類の `maximizeResourceAllocation` 設定を使用します。

次の手順では、CLI またはコンソールを使用して設定を変更する方法を示します。

**CLI を使用して、spark.executor.memory が 2g に設定されたクラスターを作成する**
+ Amazon S3 に格納されている `myConfig.json` ファイルを参照する次のコマンドを使用して、Spark がインストールされ、`spark.executor.memory` が 2g に設定されたクラスターを作成します。

  ```
  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 コンソールに移動し、サイドナビゲーションから **[古いコンソールに切り替え]** を選択します。古いコンソールに切り替えたときの動作の詳細については、「[Using the old console](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**] を選択します。

1. [**Edit software settings**] (ソフトウェア設定の編集) で、[**Enter configuration**] (設定の入力) を選択したままにしておき、次の設定を入力します。

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

1. 他のオプションを選択し、**** を選択して、**[Create cluster]** (クラスターの作成) を選択します。

**maximizeResourceAllocation を設定するには**
+ Spark がインストールされ、Amazon S3 `myConfig.json`に保存されているファイル を参照して AWS CLI、 を使用して true に`maximizeResourceAllocation`設定されたクラスターを作成します。

  ```
  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 を設定した場合、Amazon EMR 6.8.0 以降にアップグレードする前に、従来の `spark-log4j` 設定分類を削除し、`spark-log4j2` 設定分類とキー形式に移行する必要があります。Amazon EMR リリース 6.8.0 以降では、従来の `spark-log4j` 分類によりクラスターの作成が `ValidationException` エラーで失敗します。Log4j の非互換性に関連する障害については課金されませんが、続行するには無効になっている `spark-log4j` 設定分類を削除する必要があります。

Apache Log4j 1.x から Log4j 2.x への移行に関する詳細は、Github の「[Apache Log4j Migration Guide](https://logging.apache.org/log4j/2.x/manual/migration.html)」と「[Spark Log4j 2 Template](https://github.com/apache/spark/blob/master/conf/log4j2.properties.template)」を参照してください。

**注記**  
Amazon EMR では、Apache Spark は「[Apache Log4j Migration Guide](https://logging.apache.org/log4j/2.x/manual/migration.html)」で説明されている.xml ファイルではなく `log4j2.properties` ファイルを使用します。また、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 トラブルシューティングエージェントは、Amazon EMR、 AWS Glue、Amazon SageMaker ノートブック上の Apache Spark アプリケーションのトラブルシューティングを簡素化する会話型 AI 機能です。従来の Spark のトラブルシューティングでは、根本原因とコード修正を特定するために、ログ、パフォーマンスメトリクス、エラーパターンの広範な手動分析が必要です。エージェントは、自然言語プロンプト、自動化されたワークロード分析、インテリジェントなコードレコメンデーションにより、このプロセスを簡素化します。

エージェントを使用して、PySpark および Scala アプリケーションの障害をトラブルシューティングできます。エージェントは、失敗したジョブを分析し、パフォーマンスのボトルネックを特定し、実装の決定を完全に制御しながら、実用的な推奨事項とコード修正を提供します。

**注記**  
Apache Spark トラブルシューティングエージェントは、Amazon EMR の一部として追加料金なしで利用できます。エージェントは分析とレコメンデーションのみを提供します。推奨される修正を検証するためにアプリケーションを実行するときに使用する Amazon EMR リソースに対してのみ料金が発生します。

## アーキテクチャの概要
<a name="spark-troubleshooting-agent-architecture"></a>

トラブルシューティングエージェントには 3 つの主なコンポーネントがあります。インタラクション用の開発環境の MCP 互換 AI アシスタント、クライアントと AWS サービス間の安全な通信と認証を処理する [の MCP プロキシ AWS](https://github.com/aws/mcp-proxy-for-aws)、Amazon EMR、 AWS Glue、Amazon Amazon SageMaker SageMaker ノートブック用の特殊な Spark トラブルシューティングツールを提供する Amazon SageMaker Unified Studio リモート MCP サーバーです。 `(preview)`この図は、AI Assistant を介して Amazon SageMaker Unified Studio リモート MCP サーバーを操作する方法を示しています。

![\[Spark のトラブルシューティングエージェントアーキテクチャ。\]](http://docs.aws.amazon.com/ja_jp/emr/latest/ReleaseGuide/images/spark-troubleshooting-agent-architecture.png)


AI アシスタントは、次のステップに従って MCP サーバーが提供する特殊なツールを使用してトラブルシューティングを調整します。
+ **特徴量の抽出とコンテキストの構築:** エージェントは、Spark History Server ログ、設定、エラートレースなど、Spark アプリケーションからテレメトリデータを自動的に収集して分析します。主要なパフォーマンスメトリクス、リソース使用率パターン、障害署名を抽出して、インテリジェントなトラブルシューティングのための包括的なコンテキストプロファイルを構築します。
+ **GenAI 根本原因アナライザーとレコメンデーションエンジン:** エージェントは AI モデルと Spark ナレッジベースを活用して抽出された機能を関連付け、パフォーマンスの問題や障害の根本原因を特定します。Spark アプリケーションの実行で何が問題だったかの診断インサイトと分析を提供します。
+ **GenAI Spark Code Recommendation:** 前のステップの根本原因分析に基づいて、エージェントは既存のコードパターンを分析し、アプリケーションの障害に対するコード修正を必要とする非効率的なオペレーションを特定します。具体的な例を挙げて、特定のコード変更、設定調整、アーキテクチャの改善など、実用的な推奨事項を提供します。

**Topics**
+ [序章](#spark-troubleshooting-agent-intro)
+ [アーキテクチャの概要](#spark-troubleshooting-agent-architecture)
+ [エージェントをトラブルシューティングするためのセットアップ](spark-troubleshooting-agent-setup.md)
+ [トラブルシューティングエージェントの使用](spark-troubleshooting-using-troubleshooting-agent.md)
+ [機能と機能](spark-troubleshooting-features.md)
+ [トラブルシューティングと Q&A](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 との統合のセットアッププロセスを開始する前に、ワークステーションに以下がインストールされていることを確認してください。
+  [ CLI AWS のインストール ](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) 
+  [ Python 3.10 以降をインストールする ](https://www.python.org/downloads/release/python-3100/) 
+  の [ MCP Proxy の AWS](https://github.com/aws/mcp-proxy-for-aws?tab=readme-ov-file)[`uv`パッケージマネージャーをインストールする ](https://docs.astral.sh/uv/getting-started/installation/) 
+  [ 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. MCP サーバーを呼び出すアクセス許可と、選択したプラットフォームのトラブルシューティングプロセスに必要なアクセス許可を持つ IAM ロール。

次の表に示す**起動スタック**ボタンの 1 つを選択します。これにより、各リージョンの 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)  | 
| 欧州 (パリ) |  [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)  | 

**スタックの詳細の指定**ページに進み、**スタック名**を入力します。**パラメータ**の下に追加情報を入力します。次の情報を入力し、スタックの作成に進みます。
+ **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
```

Outputs タブを開き (または上記の 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
```

これは、次のように MCP サーバー設定を含める`~/.kiro/settings/mcp.json`ように更新する必要があります。

```
{
  "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
    }
  }
}
```

Kiro、Cline、GitHub CoPilot などのさまざまな MCP クライアントの設定ガイダンス[サポートされているインターフェイス](spark-troubleshooting-using-troubleshooting-agent.md#supported-interfaces)については、「」を参照してください。

# トラブルシューティングエージェントの使用
<a name="spark-troubleshooting-using-troubleshooting-agent"></a>

## サポートされているデプロイモード
<a name="supported-deployment-modes"></a>

Amazon EMR 用 Apache Spark トラブルシューティングエージェントは、自動エラー診断、パフォーマンスのボトルネックの特定、コードの推奨事項、次の Spark デプロイモードのアプリケーションパフォーマンスを向上させるための実用的な提案など、失敗した Spark ワークロードの包括的な分析機能をサポートします。
+ EMR on EC2
+ EMR Serverless
+ AWS Glue

機能、容量、制限の詳細については、[機能と機能](spark-troubleshooting-features.md)「」を参照してください。

## サポートされているインターフェイス
<a name="supported-interfaces"></a>

### Amazon SageMaker ノートブック内のセルのトラブルシューティング
<a name="troubleshooting-sagemaker-notebooks"></a>

Amazon SageMaker Notebooks でのトラブルシューティングエクスペリエンスのデモンストレーション。ノートブックセルに障害が発生した場合は、Amazon SageMaker Notebook Agent に、分析のリクエストに失敗した場合のトラブルシューティングを依頼し、エラーがコードに起因する場合は`Fix with AI`、ボタンをクリックしてコードの修正を行うことができます。

[![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 Assistant を起動し、トラブルシューティングプロセス用にロードされたツールを確認します。

```
...
 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>

で説明されている設定は、他の MCP クライアントや IDEs でも使用して、マネージド MCP サーバーに接続[エージェントをトラブルシューティングするためのセットアップ](spark-troubleshooting-agent-setup.md)できます。
+ **Cline との統合** - Cline で MCP サーバーを使用するには、 を変更`cline_mcp_settings.json`し、上記の設定を追加します。MCP 設定の管理方法の詳細については、[Cline のドキュメント](https://docs.cline.bot/mcp/configuring-mcp-servers)を参照してください。
+ と **Claude コードの統合** MCP サーバーと Claude コードを使用するには、設定ファイルを変更して 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 Persistent 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 History Server](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 Persistent UI:** Amazon EMR-EC2 ワークロードを分析する場合、分析ツールは EMR Persistent UI に接続して主要な Spark 情報を取得しようとします。EMR Persistent UI に関する考慮事項を[以下](https://docs.aws.amazon.com/emr/latest/ManagementGuide/app-history-spark-UI.html#app-history-spark-UI-limitations)に示します。
+ **Glue Studio Spark UI**: Glue ワークロードを分析する AWS 場合、分析ツールは Amazon S3 からユーザーの Spark イベントログを解析して、主要な Spark 情報を取得しようとします。Spark イベントログの最大許容サイズは、ローリングログ用に 512 MB と 2 GB [です](https://docs.aws.amazon.com/glue/latest/dg/monitor-spark-ui-jobs.html)。
+ **コードの推奨事項:** PySpark ワークロードの Amazon EMR-EC2 および AWS Glue ワークロードでのみサポート
+ **リージョンリソース:** Spark トラブルシューティングエージェントはリージョン別であり、そのリージョンの基盤となる EMR リソースをトラブルシューティングプロセスに使用します。クロスリージョンのトラブルシューティングはサポートされていません。

# トラブルシューティングと Q&A
<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`、数秒後にツールの呼び出しを再試行してください。
+ 表示される場合は、分析 ID、ツール名、mcp ログまたはツールレスポンスから利用可能なエラーメッセージ、およびオプションのサニタイズされた会話履歴`INTERNAL SERVICE EXCEPTION`を記録し、 AWS サポートにお問い合わせください。

## Q&A
<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 データノートブック) で実行されている失敗した Spark アプリケーション識別子にアクセスする必要があります。アプリケーションには、アクセス可能なログ、Spark History Server、および設定の詳細が必要です。プラットフォームリソースとアプリケーションメタデータにアクセスするために必要なアクセス許可があることを確認します。これらの要件が確立されたら、次のようなプロンプトを送信してトラブルシューティングワークフローを開始できます。

```
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 マネージド 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 サーバーレスアプリケーション
<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 トラブルシューティングエージェントにさまざまなツールを提供します。主なツールは次のとおりです。


| ツール名 | ツールカテゴリ | 説明 | 
| --- | --- | --- | 
| 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 サブネット内の 1 つ以上の [Elastic Network Interface](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html) によって表されます。詳細については、*「Amazon* [VPC ユーザーガイド」の「インターフェイス VPC エンドポイント](https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html)」を参照してください。

## ステップ 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>

Amazon SageMaker Unified Studio MCP へのアクセスを制御するエンドポイントポリシーを VPC エンドポイントにアタッチできます。このポリシーでは、以下の情報を指定します。
+ アクションを実行できるプリンシパル。
+ 実行可能なアクション。
+ アクションを実行できるリソース。

詳細については、「*Amazon VPC ユーザーガイド*」の「[VPC エンドポイントでサービスへのアクセスを制御する](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-endpoints-access.html)」を参照してください。

### 例: 特定の IAM ロールへの MCP アクセスを許可する 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
```

**注記**  
`-k` フラグは、VPC エンドポイント DNS 名と証明書の共通名 (CN) のホスト名が一致しないため、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 オペレーションへのコード呼び出しが含まれます。証跡を作成する場合は、Amazon S3 バケットへの CloudTrail イベントの継続的な配信を有効にすることができます。 Amazon SageMaker 証跡を設定しない場合でも、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 サーバー情報
<a name="sagemaker-mcp-info-in-cloudtrail"></a>

CloudTrail は、 AWS アカウントの作成時にアカウントで有効になります。Amazon SageMaker Unified Studio MCP Server でアクティビティが発生すると、そのアクティビティはイベント**履歴**の他の AWS サービスイベントとともに CloudTrail イベントに記録されます。 AWS アカウントで最近のイベントを表示、検索、ダウンロードできます。詳細については、「[CloudTrail イベント履歴でのイベントの表示](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/view-cloudtrail-events.html)」を参照してください。

SageMaker Unified Studio MCP Server のイベントなど、 AWS アカウントのイベントの継続的な記録については、証跡を作成します。証跡により、CloudTrail はログファイルを Amazon S3 バケットに配信できます。デフォルトでは、コンソールで証跡を作成すると、証跡はすべての AWS リージョンに適用されます。証跡は、 AWS パーティション内のすべてのリージョンからのイベントをログに記録し、指定した Amazon S3 バケットにログファイルを配信します。さらに、CloudTrail ログで収集されたイベントデータをさらに分析して処理するように他の AWS サービスを設定できます。詳細については、次を参照してください:
+ [追跡を作成するための概要](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)

ツールの実行中の SageMaker Unified Studio MCP Server ツールの呼び出しと AWS サービスへの API コールはすべて、CloudTrail によってログに記録されます。例えば、さまざまなツールの呼び出しやツールから行われた 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"
}
```

次の例は、アップグレードツールの呼び出し中の Amazon SageMaker Unified Studio MCP からの`AddJobFlowSteps`アクションを示す CloudTrail ログエントリを示しています。

```
{
    "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 ノートブックのコンテキストとメタデータ
+  AWS Glue データカタログまたは他のデータソースからのデータ

データにアクセスできるのは、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 からの次のアダプティブクエリ実行最適化が Spark 2 の Apache Amazon EMR ランタイムで利用できます。
+ アダプティブ結合変換
+ シャッフルパーティションのアダプティブ結合

**アダプティブ結合変換**

アダプティブ結合変換は、クエリステージのランタイムサイズに基づいて、sort-merge-join オペレーションを broadcast-hash-joins オペレーションに変換することで、クエリのパフォーマンスを向上させます。Broadcast-hash-joins は、結合の片側がすべてのエグゼキューターに出力を効率的にブロードキャストするのに十分な程度小さい場合、交換をシャッフルして結合の両側をソートする必要がなくなるため、パフォーマンスがより高くなる傾向があります。アダプティブ結合変換では、Spark が broadcast-hash-joins を自動的に実行するときのケースの範囲が広がります。

この機能は、デフォルトでご利用になれます。これは、`spark.sql.adaptive.enabled` を `false` に設定することで無効にできます。これにより、アダプティブクエリ実行フレームワークも無効になります。Spark は、結合側のいずれかのランタイムサイズ統計が `spark.sql.autoBroadcastJoinThreshold` を超えない場合 (デフォルトで 10,485,760 バイト (10 MiB))、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 アダプティブ結合パーティションのプロパティ**  

| プロパティ | デフォルトの値 | 説明 | 
| --- | --- | --- | 
|  `spark.sql.adaptive.coalescePartitions.enabled`  |  `spark.sql.shuffle.partitions` が明示的に設定されている場合を除き、true  |  true であり、かつ、spark.sql.adaptive.enabled が true の場合、Spark はターゲットサイズ (`spark.sql.adaptive.advisoryPartitionSizeInBytes` によって指定) に従って、連続するシャッフルパーティションを結合し、小さいタスクが多くなり過ぎないようにします。  | 
|  `spark.sql.adaptive.advisoryPartitionSizeInBytes`  | 64MB |  結合時のシャッフルパーティションのアドバイザリサイズ (バイト単位)。この設定は、`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`  | 1,000 |  結合前のシャッフルパーティションの初期数。この設定は、`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 ダイナミックパーティションプルーニングのパーティションのプロパティ**  

| プロパティ | デフォルト値 | 説明 | 
| --- | --- | --- | 
|  `spark.sql.dynamicPartitionPruning.enabled`  |  `true`  |  true の場合、ダイナミックパーティションプルーニングが有効になります。  | 
|  `spark.sql.optimizer.dynamicPartitionPruning.enforceBroadcastReuse`  |  `true`  |  `true` の場合、Spark はクエリの実行前に防御チェックを行い、ダイナミックプルーニングフィルターでのブロードキャスト交換の再利用が、ユーザー定義の列指向ルールなどの後続の準備ルールによって破損していないことを確認します。再利用が壊れていて、この config が `true` の場合、Spark は影響を受けるダイナミックプルーニングフィルターを除去し、パフォーマンスと正確性に関する問題から保護します。ダイナミックプルーニングフィルターのブロードキャスト交換によって、対応する結合オペレーションのブロードキャスト交換とは異なる、整合しない結果が生じると、正確性に関する問題が発生します。この構成ではユーザー定義の列指向ルールによって再利用が破損している場合などのシナリオを回避できるため、これを `false` に設定する場合は慎重に行ってください。アダプティブクエリ実行が有効になっている場合、ブロードキャストの再利用は常に適用されます。  | 

この最適化は、予定時間に解決される固定述語のプッシュダウンにのみ対応している Spark 2.4.2 の既存の機能を改良するものです。

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` テーブルという、2 つのテーブルが含まれます。テーブルには世界中に分散しているストアに関するデータが含まれていますが、北米のデータのみをクエリします。

```
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.sql.optimizer.flattenScalarSubqueriesWithAggregates.enabled` をSpark 内で設定して有効にできます。また、クラスターの作成時に有効にすることもできます。このプロパティを true に設定すると、可能な場合に、クエリオプティマイザが同じ関係式を使用する集約スカラサブクエリを平坦化します。スカラサブクエリは、サブクエリ内に存在する述語を集約関数にプッシュし、リレーションごとにすべての集約関数を使用して 1 つの集約を実行することによって平坦化されます。

以下は、この最適化を行うメリットがあるクエリの例です。

```
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);
```

書き換えられたクエリは一度だけ student テーブルを読み取ります。また、3 つのサブクエリの述語が `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.sql.optimizer.distinctBeforeIntersect.enabled` をSpark 内で設定して有効にできます。また、クラスターの作成時に有効にすることもできます。INTERSECT を使用したクエリは、左準結合を使用するように自動変換されます。このプロパティを true に設定すると、DISTINCT 演算子が左準結合を SortMergeJoin ではなく BroadcastHashJoin にできることを検出すると、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
```

## ブルームフィルター結合
<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 から構築されます。sales テーブルのスキャン中に Bloom フィルターを使用して、Bloom フィルターで定義されたセット内に確実に含まれていないアイテムの売上を洗い出します。こうすることで、特定されたこれらの売上をできるだけ早い段階で除外できます。

## 結合順序の最適化
<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 は、大きなテーブル 2 つ (`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'
```

結合順序を最適化した場合、Spark は、まず `store_sales` を`store` と結合します。`store` にはフィルターがあり、`store_returns` および `broadcastable` よりも小さいためです。次に `store_returns`、最後に `item` と結合します。`item` にフィルターがあり、プロードキャストが可能な場合は、結合順序の変更の対象となるため、`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
```

時間の経過に従い、このクエリを毎日実行して、その年の総売上をレポートする必要があります。結果フラグメントキャッシュを使用しないと、1 年のすべての日の結果を毎日再計算する必要があります。クエリは時間が経つにつれて遅くなり、365 日分の結果をすべて再計算する必要がある年末に最も遅くなります。

 結果フラグメントキャッシュを有効にすると、キャッシュから 1 年のうちのそれ以前のすべての日の結果を使用します。毎日、この機能が再計算する必要があるのは 1 日分の結果のみです。この機能は結果フラグメントを計算した後で、フラグメントをキャッシュします。その結果、キャッシュを有効にしたクエリ時間は短く、それ以降の各クエリで一定に保たれます。

## 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 倍以上減らすことができれば (つまり、入力サイズ:結果の比率が 8:1 以上)、この機能のメリットは最も大きくなります。入力と結果の削減率が大きいほど、コスト面でのメリットも大きくなります。結果を生成するコストが Amazon S3 から結果を取得するコストよりも大きい限り、削減率は小さくても、テーブルスキャンとフィルターまたは集計の間に高価な計算ステップが含まれるクエリにもメリットがあります。デフォルトでは、結果フラグメントキャッシュは、削減率が少なくとも 8:1 になると検出された場合にのみ有効になります。

キャッシュされた結果をクエリが繰り返し再利用する場合、この機能のメリットが最も大きくなります。ローリングウィンドウクエリや増分ウィンドウクエリが良い例です。例えば、30 日間のローリングウィンドウクエリを既に 29 日間実行した場合、元の入力ソースからターゲットデータの 30 分の 1 を取得するだけで、過去 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 パーティションの詳細度でキャッシュします。前述の削減率 (デフォルトは 8:1) は、RDD パーティションごとに評価されます。RDD あたりの削減率が 8:1 より大きいワークロードと 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 Streaming のユースケース、または RecordServer、Apache Ranger、または AWS Lake Formation が使用されている場合、結果フラグメントキャッシュは自動的に無効になります。
+ 結果フラグメントキャッシュの読み取り/書き込みでは、EMRFS / S3A と Amazon S3 バケットが使用されます。CSE (EMRFS でのみ)/SSE S3/SSE KMS 暗号化がサポートされています。コンテキストとして、S3A はクラスターが Amazon S3 との間でデータを読み書きできるようにする Hadoop 実装を提供します。S3A のサポートは EMR-7.4.0 以上で利用可能であることに注意してください。

# Apache Spark 用の Nvidia RAPIDS アクセラレータの使用
<a name="emr-spark-rapids"></a>

Amazon EMR リリース 6.2.0 以降では、Nvidia による [Apache Spark プラグイン用 RAPIDS](https://docs.nvidia.com/spark-rapids/user-guide/latest/overview.html) アクセラレーターを使用し、EC2 グラフィックス処理ユニット (GPU) インスタンスタイプを使用して Spark を加速できます。RAPIDS Accelerator は、コードを変更せずに Apache Spark 3.0 データサイエンスパイプラインの GPU を加速させ、データ処理とモデルのトレーニングをスピードアップしつつ、インフラストラクチャコストを大幅に低減します。

以下のセクションでは、Spark 用 Spark-RAPIDS プラグインを使用するように EMR クラスターを構成する方法について説明します。

## インスタンスタイプの選択
<a name="emr-spark-rapids-instancetypes"></a>

Spark 用の Nvidia 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。GPU を使用するように YARN を設定する**

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. RAPIDS を使用するように Spark を設定する**

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"
	}
}
```

XGBoost ドキュメントの [XGBoost4J-Spark ライブラリ](https://xgboost.readthedocs.io/en/latest/jvm/xgboost4j_spark_tutorial.html)は、クラスターで Spark RAPIDS プラグインが有効になっている場合も使用できます。次の設定を使用して、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 tuning guide](https://docs.nvidia.com/spark-rapids/user-guide/latest/tuning-guide.html)」を参照してください。

**4. YARN キャパシティスケジューラを設定する**

`DominantResourceCalculator` は、GPU のスケジューリングと分離が有効になるように設定する必要があります。詳細については、Apache Hadoop ドキュメントの「[Using GPU on YARN](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 ファイルを作成してすべての設定を含める**

Spark クラスターに RAPIDS プラグインを使用するための設定が含まれた JSON ファイルを作成できます。このファイルは、後でクラスターの起動時に指定します。

ファイルはローカルまたは 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 管理ガイド*」の「[Bootstrap action basics](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 シェルにアクセスする
<a name="emr-spark-shell"></a>

Spark シェルは Scala REPL (Read-Eval-Print-Loop) をベースにしています。このシェルを使用すると、Spark プログラムをインタラクティブに作成し、作業をフレームワークに送信できます。Spark シェルには、SSH を使用してプライマリノードに接続し、`spark-shell` を呼び出すことでアクセスできます。プライマリノードへの接続の詳細については、「*Amazon EMR 管理ガイド*」の「[Connect to the primary node using SSH](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-connect-master-node-ssh.html)」を参照してください。次の例では、Amazon S3 に格納された Apache HTTP Server アクセスログを使用します。

**注記**  
これらの例にあるバケットは、米国東部 (バージニア北部) にアクセスできるクライアントが使用できます。

 デフォルトでは、Spark シェルによって `sc` と呼ばれる独自の [SparkContext](https://spark.apache.org/docs/1.3.1/api/scala/index.html#org.apache.spark.SparkContext) オブジェクトが作成されます。REPL 内で必要な場合は、このコンテキストを使用できます。sqlContext はシェルでも使用でき、[HiveContext](https://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.sql.hive.HiveContext) です。

**Example Spark を使用して Amazon S3 に格納されたファイルにおける文字列の出現回数をカウントする**  
この例では、Amazon S3 に保存されているテキスト ファイルを読み取るために `sc` を使用します。  

```
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.ca-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 シェル使用して Amazon S3 に格納されたファイルにおける文字列の出現回数をカウントする**  
Spark には、Python ベースのシェルである `pyspark` も用意されており、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.ca-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 機械学習 (ML) パイプラインを作成できます。詳細については、GitHub の「[Amazon SageMaker Spark README](https://github.com/aws/sagemaker-spark/blob/master/README.md)」および「[Amazon SageMaker 開発者ガイド](https://docs.aws.amazon.com/sagemaker/latest/dg/apache-spark.html)」の「*Using Apache Spark with Amazon SageMaker*」を参照してください。

# Spark アプリケーションを作成する
<a name="emr-spark-application"></a>

[Spark](https://aws.amazon.com/big-data/what-is-spark/) アプリケーションは、Scala、Java、または Python で記述できます。Apache Spark ドキュメントの「[Spark の例](https://spark.apache.org/examples.html)」には、Spark アプリケーションの例がいくつかあります。ネイティブにサポートされる以下の 3 つのアプリケーションには、Estimating 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 は Scala 2.11 でビルドされた Spark 2.4.5 を使用します。クラスターが 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 向けに最適化されたコミッターは [OutputCommitter](https://hadoop.apache.org/docs/current/api/org/apache/hadoop/mapreduce/OutputCommitter.html) クラスに代わるものであり、EMRFS のマルチパートアップロード機能を使用して、Spark、DataFrames、および Datasets で Amazon S3 に Parquet ファイルを書き込むときのパフォーマンスを向上させます。

**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 以降では、Amazon EMR での Spark を使用した [S3 Select](https://aws.amazon.com/blogs/aws/s3-glacier-select/) を使用できます。*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 を使用した場合と使用しない場合のアプリケーションのベンチマークを行うことをお勧めします。

アプリケーションが S3 Select を使用する候補となるかどうかを判断するには、次のガイドラインを使用します。
+ クエリは元のデータセットの半分以上を除外する。
+ Amazon S3 と Amazon EMR クラスター間のネットワーク接続は、転送速度と使用可能な帯域幅が良好です。Amazon S3 は、HTTP 応答を圧縮しないため、応答サイズは圧縮された入力ファイルと比較して増加する可能性があります。

## 考慮事項と制限事項
<a name="emr-spark-s3select-considerations"></a>
+ お客様が用意した暗号化キーを使用した Amazon S3 サーバー側の暗号化 (SSE-C) とクライアント側の暗号化はサポートされていません。
+ `AllowQuotedRecordDelimiters` プロパティはサポートされていません。このプロパティを指定した場合、クエリは失敗します。
+ UTF-8 形式の CSV ファイルと JSON ファイルのみがサポートされています。複数行の CSV はサポートされません。
+ 圧縮されていないファイルか gzip ファイルのみがサポートされます。
+ `nanValue`、`positiveInf`、`negativeInf` などの Spark CSV と JSON のオプションや破損した記録に関連するオプション (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>


| オプション | デフォルト | 使用方法 | 
| --- | --- | --- | 
|  `compression`  |  `"none"`  |  圧縮が使用されているかどうかを示します。`"none"` 以外にサポートされる設定は `"gzip"` のみです。  | 
|  `delimiter`  |  ","  |  フィールドの区切り記号を指定します。  | 
|  `quote`  |  `'\"'`  |  引用文字を指定します。空の文字例は指定できず、文字列を空にすると XML が不正というエラーが表示されます。  | 
|  `escape`  |  `'\\'`  |  エスケープ文字を指定します。  | 
|  `header`  |  `"false"`  |  `"false"` はヘッダーがないことを指定します。`"true"` はヘッダーが最初の行にあることを指定します。最初の行のヘッダーのみがサポートされ、ヘッダーの前の空の行はサポートされません。  | 
|  コメント  |  `"#"`  |  コメント文字を指定します。コメントインジケーターを無効にすることはできません。つまり、`\u0000` という値はサポートされません。  | 
|  `nullValue`  |  ""  |    | 

#### S3selectJSON のオプション
<a name="emr-spark-s3select-specify-options-json"></a>


| オプション | デフォルト | 使用方法 | 
| --- | --- | --- | 
|  `compression`  |  `"none"`  |  圧縮が使用されているかどうかを示します。`"none"` 以外にサポートされる設定は `"gzip"` のみです。  | 
|  `multiline`  |  "false"  |  `"false"` は JSON が S3 Select `LINES` 形式であることを指定し、入力データの各行に 1 つの 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) の代替実装であり、S3A ファイルシステムを使用する時に EMR Spark を使用して Amazon S3 にファイルを書き込むように最適化されています。このプロトコルは、ジョブおよびタスクコミットフェーズ中の 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>

MagicCommitProtocol は、S3A ファイルシステムを使用する時に Amazon Elastic Map Reduce (EMR) で実行される Spark に対してデフォルトで有効になっています。

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. `spark.sql.execution.datasources.SQLEmrOptimizedCommitProtocol.leverageMagicCommitProtocol` は、`SparkConf` でハードコーディングするか、Spark シェルまたは `spark-submit` および `spark-sql` ツールで `--conf` パラメータとして渡すか、`conf/spark-defaults.conf` で false に設定できます。詳細については、Apache Spark ドキュメントの「[Spark Configuration](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.sql.execution.datasources.SQLEmrOptimizedCommitProtocol.leverageMagicCommitProtocol` プロパティを false に設定するには、`spark-defaults` 設定分類を使用します。詳細については、「[アプリケーションの設定](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 ドライバーの `spark.driver.memory` プロパティと Spark エグゼキュターの `spark.executor.memory` プロパティを使用してメモリを調整できます。ガイドラインとして、100,000 個のファイルを書き込む 1 つのタスクでは、一般的に 200 MB のメモリを追加する必要があります。詳細については、Apache Spark Configuration ドキュメントの「[Application Properties](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、DataFrame、または Dataset を使用する 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、DataFrame、または Dataset を使用して 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 メタストアテーブルの場合、Parquet テーブルに対して `spark.sql.hive.convertMetastoreParquet` が `true` に設定される場合、または、Amazon EMR 6.4.0 以降の Orc テーブルに対して `spark.sql.hive.convertMetastoreOrc` が `true` に設定される場合。これらはデフォルトの設定です。
  + ジョブによってファイル形式のデータソースまたはテーブルに書き込まれる場合。例えば、ターゲットテーブルが `USING parquet` 句で作成される場合などです。
  + ジョブでパーティション分割されていない Hive メタストア Parquet テーブルに書き込む場合。Spark の組み込み Parquet サポートはパーティション分割された Hive テーブルをサポートしていません。これは既知の制限です。詳細については、Apache Spark, DataFrames and Datasets Guide の「[Hive metastore Parquet table conversion](https://spark.apache.org/docs/latest/sql-data-sources-parquet.html#hive-metastore-parquet-table-conversion)」を参照してください。
+ デフォルトのパーティションの場所 (`${table_location}/k1=v1/k2=v2/` など) に書き込む Spark ジョブオペレーションでコミッターが使用される。ジョブオペレーションによってカスタムのパーティション場所に書き込まれる場合、例えば、カスタムのパーティション場所が `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 のファイル形式のみがサポートされます。パーティション化されていない Parquet Hive メタストアテーブルに書き込む場合は、`spark.sql.hive.convertMetastoreParquet` は `true` に設定する必要があります。パーティション化されていない Orc Hive メタストアテーブルに書き込む場合は、`spark.sql.hive.convertMetastoreOrc` は `true` に設定する必要があります。これらはデフォルトの設定です。
  + `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` に設定する必要があります。Amazon EMR 5.x シリーズバージョン 5.30.0 以降、および Amazon EMR 6.x シリーズバージョン 6.2.0 以降の場合、`org.apache.spark.sql.execution.datasources.SQLEmrOptimizedCommitProtocol` がデフォルト設定です。それよりも前の 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 向けに最適化されたコミッターを全体に使用しないもの (最初の例) と、部分的に使用しないもの (2 番目の例) です。

**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 向けに最適化されたコミッターが使用されないようにするには、3 つの設定をすべて構成する必要があります。これを行うと、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 のステージングディレクトリに書き込まれたすべてのパーティションディレクトリが収集されます。ディレクトリツリーの名前変更オペレーションを使用して、これらの各ディレクトリの名前が最終的な出力場所に順番に変更されます。

1. ステージングディレクトリがジョブのコミットフェーズの完了前に削除されます。

**Example - カスタムのパーティション場所**  
この例では、Scala コードは 2 つのパーティションを挿入します。1 つのパーティションはカスタムのパーティション場所を使用します。もう 1 つのパーティションはデフォルトのパーティション場所を使用します。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$
```
カスタムのパーティション場所に書き込むとき、先ほどの例と同様のコミットアルゴリズムが使用されます。先ほどの例と同様、このアルゴリズムでは名前が順番に変更されるため、パフォーマンスが低下する可能性があります。  

1. カスタムのパーティション場所に出力を書き込むとき、タスクでは最終的な出力場所に作成される Spark のステージングディレクトリにファイルを書き込みます。ファイルの名前には、ファイルの競合から保護するためのランダムな UUID が含まれます。タスクの試行によって各ファイルが最終的な出力パスと共に追跡されます。

1. タスクが正常に完了すると、ドライバーにファイルとそれらの最終的な出力パスが渡されます。

1. すべてのタスクが完了した後、ジョブのコミットフェーズでは、カスタムのパーティション場所に書き込まれたすべてのファイルの名前が、最終的な出力パスに順番に変更されます。

1. ステージングディレクトリがジョブのコミットフェーズの完了前に削除されます。

# EMRFS S3 向けに最適化されたコミッターとマルチパートアップロード
<a name="emr-spark-committer-multipart"></a>

EMRFS S3 に最適化されたコミッターを使用するには、Amazon EMR のマルチパートアップロードを有効にする必要があります。マルチパートアップロードは、デフォルトで有効になっています。また、必要に応じて再度有効にすることができます。詳細については、「[Amazon EMR 管理ガイド](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-upload-s3.html#Config_Multipart)」の「*Amazon S3 用のマルチパートアップロードを設定する*」を参照してください。

EMRFS S3 向けに最適化されたコミッターは、マルチパートアップロードのトランザクションのような特性を利用して、タスクのコミット時にタスクの試行によって書き込まれたファイルのみがジョブの出力場所に表示されるようにします。この方法でマルチパートアップロードを使用することにより、コミッターはデフォルトの FileOutputCommitter アルゴリズムバージョン 2 におけるタスクコミットのパフォーマンスを向上させます。EMRFS S3 向けに最適化されたコミッターを使用するにあたっては、従来のマルチパートアップロードとのいくつかの重要な違いを考慮する必要があります。
+ マルチパートアップロードは常にファイルサイズに関係なく実行されます。これは EMRFS のデフォルトの動作とは異なり、マルチパートアップロードがトリガーされるファイルサイズは `fs.s3n.multipart.uploads.split.size` プロパティで制御されます。
+ タスクがコミットされるか中止されるまで、マルチパートアップロードは長期間不完全な状態になります。これは EMRFS のデフォルトの動作とは異なり、タスクで指定されたファイルの書き込みが終了するとマルチパートアップロードが完了します。

このような違いにより、タスクが実行されて Amazon S3 へのデータの書き込みが行われているときに Spark Executor 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-committer-tuning"></a>

EMRFS S3 向けに最適化されたコミッターは、タスクがコミットされるか中止されるまで、タスクの試行によって書き込まれた各ファイルのために少量のメモリを消費します。ほとんどのジョブで消費されるメモリの量は無視できる程度です。多数のファイルを書き込む長時間のタスクを含むジョブの場合、コミッターが消費するメモリが多くなり、Spark エグゼキュターに割り当てれたメモリの調整が必要になることがあります。エグゼキュターのメモリは、`spark.executor.memory` プロパティを使用して調整できます。ガイドラインとして、100,000 個のファイルを書き込む 1 つのタスクでは、一般的に 100 MB のメモリを追加する必要があります。詳細については、Apache Spark Configuration ドキュメントの「[Application Properties](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 を使用している場合は、クラスターの作成時、または Spark 内から (Amazon EMR を使用しているとき)、`spark.sql.parquet.fs.optimized.committer.optimization-enabled` プロパティを `true` に手動で設定できます。

## EMRFS S3 向けに最適化されたコミッターをクラスターの作成時に有効にする
<a name="w2aac62c61c17c13b5"></a>

`spark.sql.parquet.fs.optimized.committer.optimization-enabled` プロパティを `true` に設定するには、`spark-defaults` 設定分類を使用します。詳細については、「[アプリケーションの設定](emr-configure-apps.md)」を参照してください。

## EMRFS S3 向けに最適化されたコミッターを Spark から有効にする
<a name="w2aac62c61c17c13b7"></a>

`spark.sql.parquet.fs.optimized.committer.optimization-enabled` は、`SparkConf` でハードコーディングするか、Spark シェルまたは `spark-submit` および `spark-sql` ツールで `--conf` パラメータとして渡すか、`conf/spark-defaults.conf` によって `true` に設定できます。詳細については、Apache Spark ドキュメントの「[Spark Configuration](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 を使用するときの Amazon S3 への Spark の動的パーティション上書きを使用するファイル書き込みに対して最適化されています。このプロトコルは、Spark の動的パーティション上書きジョブのコミットフェーズ中の Amazon S3 での名前変更操作を回避することで、アプリケーションのパフォーマンスを向上させます。

[EMRFS S3-optimized committer](emr-spark-s3-optimized-committer.html) はまた、名前変更操作を回避することでパフォーマンスを向上させることにも注意してください。ただし、動的パーティション上書きの場合は機能しませんが、コミットプロトコルの改善は動的パーティション上書きの場合のみを対象としています。

コミットプロトコルは Amazon EMR リリース 5.30.0 以降で使用でき、6.2.0 以降ではデフォルトで有効になっています。リリース 5.31.0 以降、Amazon EMR では並列処理の改善が追加されました。プロトコルは、Spark、DataFrame、または Dataset を使用する 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、DataFrame、または Dataset によりパーティション化されたテーブルを書き込む 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` に設定されている場合に発生します。これらはデフォルトの設定です。
+ デフォルトのパーティションの場所 (`${table_location}/k1=v1/k2=v2/` など) に書き込む Spark ジョブオペレーションでコミットプロトコルが使用される。ジョブオペレーションによってカスタムのパーティション場所に書き込まれる場合、例えば、カスタムのパーティション場所が `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 向けに最適化されたコミットプロトコルは、オープンソースのデフォルトの Spark コミットプロトコル `org.apache.spark.sql.execution.datasources.SQLHadoopMapReduceCommitProtocol` と同じように機能します。次の状況では、最適化は行われません。


****  

| 状況 | コミットプロトコルが使用されない理由 | 
| --- | --- | 
| HDFS に書き込む場合 | コミットプロトコルは、EMRFS を使用した Amazon S3 への書き込みのみをサポートします。 | 
| S3A ファイルシステムを使用する場合 | コミットプロトコルは EMRFS のみをサポートします。 | 
| MapReduce または Spark の RDD API を使用する場合 | コミットプロトコルは、SparkSQL、DataFrame、またはデータセット API の使用のみをサポートします。 | 
| 動的パーティションの上書きがトリガーされない場合 | コミットプロトコルは、動的なパーティション上書きの場合のみを最適化します。その他の場合については、「[EMRFS S3 向けに最適化されたコミッターを使用する](emr-spark-s3-optimized-committer.md)」を参照してください。 | 

次の Scala の例は、EMRFS S3 向けに最適化されたコミットプロトコルが `SQLHadoopMapReduceCommitProtocol` に委任するその他の状況を示しています。

**Example - カスタムパーティションの場所を使用する動的パーティション上書きモード**  
この例では、Scala プログラムは動的パーティション上書きモードで 2 つのパーティションを上書きします。1 つのパーティションはカスタムのパーティション場所を使用します。もう 1 つのパーティションはデフォルトのパーティション場所を使用します。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 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 管理ガイド](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-upload-s3.html#Config_Multipart)」の「*Amazon S3 用のマルチパートアップロードを設定する*」を参照してください。

動的パーティション上書きの間、EMRFS S3 向けに最適化されたコミットプロトコルは、マルチパートアップロードのトランザクションのような特性を利用して、ジョブのコミット時にタスクの試行によって書き込まれたファイルのみがジョブの出力場所に表示されるようにします。このようにマルチパートアップロードを使用することにより、コミットプロトコルはジョブコミットのパフォーマンスをデフォルトの `SQLHadoopMapReduceCommitProtocol` よりも向上させます。EMRFS S3 向けに最適化されたコミットプロトコルを使用するにあたっては、従来のマルチパートアップロードとのいくつかの重要な違いを考慮する必要があります。
+ マルチパートアップロードは常にファイルサイズに関係なく実行されます。これは EMRFS のデフォルトの動作とは異なり、マルチパートアップロードがトリガーされるファイルサイズは `fs.s3n.multipart.uploads.split.size` プロパティで制御されます。
+ タスクがコミットされるか中止されるまで、マルチパートアップロードは長期間不完全な状態になります。これは EMRFS のデフォルトの動作とは異なり、タスクで指定されたファイルの書き込みが終了するとマルチパートアップロードが完了します。

このような違いにより、タスクが実行されて Amazon S3 へのデータの書き込みが行われているときに Spark Executor JVM がクラッシュしたり強制終了されたりする、またはジョブが実行しているときに Spark Driver 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>

Spark エグゼキュターで、EMRFS S3 向けに最適化されたコミットプロトコルは、タスクがコミットされるか中止されるまで、タスクの試行によって書き込まれた各ファイルのために少量のメモリを消費します。ほとんどのジョブで消費されるメモリの量は無視できる程度です。

Spark ドライバーで、EMRFS S3 向けに最適化されたコミットプロトコルには、ジョブがコミットまたは中止されるまで、コミットされた各ファイルのメタデータ情報を保存するためのメモリが必要です。ほとんどのジョブでは、Spark ドライバーのデフォルトのメモリ設定はごくわずかです。

多数のファイルを書き込む長時間のタスクを含むジョブの場合、コミットプロトコルが消費するメモリが多くなり、Spark、特に Spark エグゼキュターに割り当てられたメモリの調整が必要になることがあります。Spark ドライバーの `spark.driver.memory` プロパティと Spark エグゼキュターの `spark.executor.memory` プロパティを使用してメモリを調整できます。ガイドラインとして、100,000 個のファイルを書き込む 1 つのタスクでは、一般的に 100 MB のメモリを追加する必要があります。詳細については、Apache Spark Configuration ドキュメントの「[Application Properties](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` 設定でプロパティを設定し、再試行戦略を調整できます。

次の方法で再試行戦略を調整できます。
+ デフォルトのエクスポネンシャルバックオフ再試行戦略の再試行上限を増やします。
+ additive-increase/multiplicative-decrease (AIMD) 再試行戦略を有効にして設定します。AIMD は Amazon EMR リリース 6.4.0 以降でサポートされています。

## デフォルトのエクスポネンシャルバックオフ戦略を使用する
<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 は、additive-increase/multiplicative-decrease (AIMD) モデルに基づく代替再試行戦略をサポートします。AIMD 再試行戦略は、大規模な Amazon EMR クラスターで作業する場合に特に便利です。

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 再試行戦略のプロパティ**  

| プロパティ | デフォルトの値 | 説明 | 
| --- | --- | --- | 
| 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-submit` スクリプトをステップとして自動的に実行する Spark アプリケーションステップを使用してこれを行います。API では、ステップを使用し、`spark-submit` を使用して `command-runner.jar` を呼び出します。

Spark へのアプリケーションの送信の詳細については、Apache Spark ドキュメントの「[アプリケーションの送信](https://spark.apache.org/docs/latest/submitting-applications.html)」を参照してください。

**コンソールを使用して Spark ステップを送信する**

1. [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**] を選択します。
   + [**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. **[Add]** (追加) を選択します。ステップは、[Pending] というステータスでコンソールに表示されます。

1. ステップが実行されると、ステータスは [**Pending (保留中)**] から [**Running (実行中)**]、[Running (実行中)] から [**完了済み**] に変更されます。スタータスを更新するには、**[Actions]** (アクション) 列の上にある **[Refresh]** (更新) アイコンを選択します。

1. ステップの結果は、ロギングを設定している場合、Amazon EMR コンソールの [Cluster Details] (クラスターの詳細) ページの **[Log Files]** (ログファイル) にあるステップの横に表示されます。オプションで、クラスターを起動したときに設定したログバケットにステップの情報が記載されています。

**を使用して 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]
   ```

**SDK for Java を使用して作業を 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>

コンソールでクラスターの詳細ページの **[Application user interfaces]** (アプリケーションユーザーインターフェイス) タブを使用して、Spark、YARN アプリケーション、および Tez UI の詳細を表示できます。Amazon EMR のアプリケーションユーザーインターフェイス (UI) を使用すると、アクティブなジョブとジョブ履歴のトラブルシューティングや分析を簡単に行うことができます。

詳細については、「Amazon EMR 管理ガイド」の「[アプリケーションの履歴を表示する](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-cluster-application-history.html)」を参照してください。**

# Spark ウェブ UI にアクセスする
<a name="emr-spark-webui"></a>

Spark ウェブ UI は、「Amazon EMR 管理ガイド」の「[クラスターに接続する](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-connect-master-node.html)」セクションにある SSH トンネルの作成手順とプロキシの作成手順に従い、クラスターの YARN ResourceManager に移動することで表示できます。アプリケーションの **UI 追跡**の下のリンクを選択します。アプリケーションが実行中の場合、**ApplicationMaster** が表示されます。ドライバーがどこにあるかにかかわらず、ここからアプリケーションマスターのウェブ UI のポート 20888 に移動できます。YARN クライアントモードで実行する場合、ドライバーはクラスターのプライマリノードにあるかもしれません。YARN クラスターモードでアプリケーションを実行している場合、ドライバーは、クラスター上のアプリケーションの ApplicationMaster にあります。アプリケーションが終了すると、**履歴**が表示され、EMR クラスターのプライマリノードの、Spark HistoryServer の UI ポート番号 18080 に移動できます。これは、すでに完了したアプリケーション用です。http://*master-public-dns-name*:18080/ でも、Spark HistoryServer の UI ディレクトリに移動できます。

Amazon EMR リリース 5.25.0 以降では、SSH 接続を介してウェブプロキシを設定しなくても、コンソールから Spark 履歴サーバー UI にアクセスできます。詳細については、「[永続アプリケーションユーザーインターフェイスの表示](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 での Apache Spark 用の Amazon Redshift インテグレーションの使用
<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 以降では、[Apache Spark の Amazon Redshift インテグレーション](https://docs.aws.amazon.com/redshift/latest/mgmt/spark-redshift-connector.html)がコミュニティバージョンからネイティブインテグレーションに移行されました。

**Topics**
+ [Amazon Redshift integration for Apache Spark を使用した 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)

# Amazon Redshift integration for Apache Spark を使用した Spark アプリケーションの起動
<a name="emr-spark-redshift-launch"></a>

Amazon EMR リリース 6.4 から 6.9 では、`--jars` または `--packages` オプションを使用して、次の JAR ファイルのうちどのファイルを使用するかを指定する必要があります。`--jars` オプションは、ローカル、HDFS、または HTTP/S を使用して保存される依存関係を指定します。`--jars` オプションでサポートされている他のファイルの場所については、Spark ドキュメントの「[Advanced Dependency Management](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) を使用するには、[IAM 認証を使用するように JDBC URL を設定します](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)」を参照してください。

また、`COPY` および `UNLOAD` オペレーション中に Amazon Redshift が 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>
+ Amazon EMR 上の Spark から Amazon Redshift への JDBC 接続に対して SSL を有効にすることをお勧めします。
+ ベストプラクティスとして、 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)を使用して、使用する Amazon 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 アクセスキーの設定
    + URI `tempdir` での AWS アクセスキーのエンコード

コネクタとそのサポートされているパラメータの使用方法の詳細については、次のリソースを参照してください。
+ 「*Amazon Redshift 管理ガイド*」の「[Amazon Redshift integration for Apache Spark](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) でリリースに応じたコンポーネントバージョンのセクションを参照してください。

**重要**  
Apache Spark バージョン 2.3.1 は Amazon EMR リリース 5.16.0 以降で利用でき、[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 AWS 以降では、 Glue データカタログでの Apache Iceberg マテリアライズドビューの作成と管理がサポートされています。マテリアライズドビューは、SQL クエリの事前計算された結果を Apache Iceberg 形式で保存し、基盤となるソーステーブルが変更されると段階的に更新するマネージドテーブルです。マテリアライズドビューを使用して、データ変換パイプラインを簡素化し、複雑な分析ワークロードのクエリパフォーマンスを高速化できます。

Amazon EMR で Spark を使用してマテリアライズドビューを作成すると、ビュー定義とメタデータが AWS Glue データカタログに保存されます。事前計算された結果は、 AWS アカウント内の Amazon S3 Tables バケットまたは Amazon S3 汎用バケットに Apache Iceberg テーブルとして保存されます。 AWS Glue Data Catalog は、ソーステーブルを自動的にモニタリングし、マネージドコンピューティングインフラストラクチャを使用してマテリアライズドビューを更新します。

**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 と統合されます。Glue データカタログを使用するように Spark AWS セッションを設定すると、標準の SQL 構文を使用してマテリアライズドビューを作成できます。Spark オプティマイザは、パフォーマンスを向上させるときにマテリアライズドビューを使用するようにクエリを自動的に書き換えることができるため、アプリケーションコードを手動で変更する必要はありません。

 AWS Glue データカタログは、以下を含むマテリアライズドビューメンテナンスのすべての運用面を処理します。
+ 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 データカタログに登録された Apache Iceberg AWS 形式のソーステーブル
+ 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 ステートメントを使用してマテリアライズドビューを作成します。ビュー定義は、変換ロジックを 1 つまたは複数のソーステーブルを参照する 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>

次の例では、顧客ごとに注文データを集約するマテリアライズドビューを作成し、ビュー定義で 3 つのパートの命名規則を持つ完全修飾テーブル名を使用します。

```
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>

自動更新を設定するには、ビュー定義で 3 つのパートの命名規則を持つ完全修飾テーブル名を使用してビューを作成するときに更新スケジュールを指定します。

```
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>

ソーステーブルがマテリアライズドビューとは異なるカタログにある場合は、ビュー名とビュー定義の両方に 3 つの部分で構成される命名規則を持つ完全修飾されたテーブル名を使用します。

```
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 オプティマイザは、ベースの orders テーブルを処理する代わりに 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.sales.orders ではなく BatchScan glue\$1catalog.analytics.customer\$1orders がプランに表示される場合、マテリアライズドビューを使用するようにクエリが自動的に書き換えられています。

**注記**  
自動クエリ書き換えには、マテリアライズドビューの作成後に Spark メタデータキャッシュに入力する時間が必要です。通常、この処理は 30 秒以内に完了します。

## 「マテリアライズドビューの更新」
<a name="emr-spark-materialized-views-refresh"></a>

マテリアライズドビューは、2 つの方法 (フル更新または増分更新) で更新できます。フル更新では、すべてのベーステーブルデータからマテリアライズドビュー全体が再計算されますが、増分更新では、前回の更新以降に変更されたデータのみが処理されます。

### 手動完全更新
<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 データカタログは、ビュー定義と変更されたデータの量に基づいて、増分更新が適用されるかどうかを自動的に判断します。増分更新が不可能な場合、オペレーションはフル更新に戻ります。

### 増分更新の実行を検証する
<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;
```

このコマンドは、 AWS Glue データカタログからマテリアライズドビュー定義を削除し、基盤となる Iceberg テーブルデータを S3 バケットから削除します。

## マテリアライズドビューのアクセス許可
<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 アクセス許可
+ Glue データカタログ AWS – GetTable および CreateTable API アクセス許可

マテリアライズドビューを作成すると、定義ロールの ARN がビュー定義に保存されます。 AWS Glue データカタログは、自動更新オペレーションを実行するときにこのロールを引き受けます。定義者ロールがソーステーブルへのアクセスを失った場合、アクセス許可が復元されるまで更新オペレーションは失敗します。

### マテリアライズドビューへのアクセスを付与する
<a name="emr-spark-materialized-views-permissions-access"></a>

他のユーザーにマテリアライズドビューをクエリするためのアクセス許可を付与するには、 AWS Lake Formation を使用してマテリアライズドビューテーブルに対する SELECT アクセス許可を付与します。ユーザーは、マテリアライズドビューをクエリできます。基盤となるソーステーブルに直接アクセスする必要はありません。

Lake Formation アクセス許可の設定の詳細については、 AWS Lake Formation デベロッパーガイドの「データカタログリソースに対するアクセス許可の付与と取り消し」を参照してください。

## マテリアライズドビューオペレーションをモニタリングする
<a name="emr-spark-materialized-views-monitoring"></a>

 AWS Glue データカタログは、マテリアライズドビューの更新オペレーションのメトリクスとログを Amazon CloudWatch に発行します。更新ステータス、期間、処理されたデータボリュームを CloudWatch メトリクスからモニタリングできます。

### 更新メトリクスの表示
<a name="emr-spark-materialized-views-monitoring-metrics"></a>

マテリアライズドビューの更新メトリクスを表示するには:

1. CloudWatch コンソールを開きます。

1. ナビゲーションペインからメトリクスを選択します。

1. [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 データカタログに登録されている Apache Iceberg AWS テーブルである必要があります。ローンチの時点では、Apache Hive、Apache Hudi、Linux Foundation Delta Lake テーブルはサポートされていません。
+ ソーステーブルは、マテリアライズドビューと同じ AWS リージョンと AWS アカウントに存在する必要があります。
+ すべてのソーステーブルは AWS Lake Formation によって管理される必要があります。IAM のみのアクセス許可とハイブリッドアクセスはサポートされていません。
+ マテリアライズドビューは AWS 、 Glue データカタログビュー、マルチダイアレクトビュー、またはその他のマテリアライズドビューをソーステーブルとして参照することはできません。
+ ビュー定義ロールには、行、列、またはセルフィルターが適用されていないすべてのソーステーブルに対するフル読み取りアクセス (SELECT または ALL アクセス許可) が必要です。
+ マテリアライズドビューは、結果的にソーステーブルと整合します。更新中に、クエリが古いデータを返すことがあります。即自的な整合性が必要な場合は手動更新を実行します。
+ 自動更新の最小間隔は 1 時間です。
+ 増分更新は、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() などの非決定論的関数は、マテリアライズドビュー定義でサポートされません。