

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

# Amazon EMR on EKS での Amazon Redshift integration for Apache Spark の使用
<a name="emr-spark-redshift"></a>

Amazon EMR リリース 6.9.0 以降、リリースイメージには常に [Apache Spark](https://aws.amazon.com/emr/features/spark/) と Amazon Redshift をつなぐコネクタが含まれます。そのため、Amazon EMR on EKS で Spark を使用すると、Amazon Redshift に保存されているデータを処理できます。このインテグレーションは、[`spark-redshift` オープンソースコネクタ](https://github.com/spark-redshift-community/spark-redshift#readme)をベースにしています。Amazon EMR on EKS では、[Amazon Redshift integration for Apache Spark](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)
+ [Amazon Redshift integration for Apache Spark による認証](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>

このインテグレーションを使用するには、Spark ジョブで必要な Spark Redshift の依存関係を渡す必要があります。`--jars` を使用して、Redshift コネクタ関連のライブラリを含める必要があります。ファイルの保存先として `--jars` オプションでサポートされている他の場所を確認するには、Apache Spark ドキュメントの「[Advanced Dependency Management](https://spark.apache.org/docs/latest/submitting-applications.html#advanced-dependency-management)」セクションを参照してください。
+ `spark-redshift.jar`
+ `spark-avro.jar`
+ `RedshiftJDBC.jar`
+ `minimal-json.jar`

Amazon EMR on EKS リリース 6.9.0 以降で Amazon Redshift integration for Apache Spark を使用して Spark アプリケーションを起動するには、次のようなコマンドを使用します。なお、`--conf spark.jars` オプションに指定されているパスは JAR ファイルのデフォルトのパスであることに注意してください。

```
aws emr-containers start-job-run \

--virtual-cluster-id cluster_id \
--execution-role-arn arn \
--release-label emr-6.9.0-latest\
--job-driver '{
    "sparkSubmitJobDriver": {
        "entryPoint": "s3://script_path", 
            "sparkSubmitParameters":
            "--conf spark.kubernetes.file.upload.path=s3://upload_path 
             --conf spark.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"
                            }
            }'
```

# Amazon Redshift integration for Apache Spark による認証
<a name="emr-spark-redshift-auth"></a>

以下の各セクションでは、Apache Spark と統合する場合の Amazon Redshift での認証オプションを示します。これらのセクションでは、ログイン認証情報を取得する方法と、IAM 認証での JDBC ドライバーの使用に関する詳細を示します。

## AWS Secrets Manager を使用して認証情報を取得し、Amazon Redshift に接続する
<a name="emr-spark-redshift-secrets"></a>

Secrets Manager に認証情報を保存すると、Amazon Redshift に対して安全に認証できます。Spark ジョブを使用すると、`GetSecretValue` API を呼び出して認証情報を取得できます。

```
from pyspark.sql import SQLContextimport boto3

sc = # existing SparkContext
sql_context = SQLContext(sc)

secretsmanager_client = boto3.client('secretsmanager', region_name=os.getenv('AWS_REGION'))
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

# Access to Redshift cluster using Spark
```

## Amazon EMR on EKS ジョブ実行ロールでの IAM ベースの認証の使用
<a name="emr-spark-redshift-iam"></a>

Amazon EMR on EKS リリース 6.9.0 以降、Amazon Redshift JDBC ドライバーバージョン 2.1 以降が環境にパッケージ化されます。JDBC ドライバー 2.1 以降では、JDBC URL を指定できます。未加工のユーザー名とパスワードを含めることはできません。代わりに、`jdbc:redshift:iam://` スキームを指定できます。このコマンドは、Amazon EMR on EKS ジョブ実行ロールを使用して認証情報を自動的に取得するように JDBC ドライバーに指示しています。

詳細については、「Amazon Redshift 管理ガイド」の「[Configure a JDBC or ODBC connection to use IAM credentials](https://docs.aws.amazon.com/redshift/latest/mgmt/generating-iam-credentials-configure-jdbc-odbc.html)」を参照してください。

次の URL 例では、`jdbc:redshift:iam://` スキームを使用しています。

```
jdbc:redshift:iam://examplecluster.abc123xyz789.us-west-2.redshift.amazonaws.com:5439/dev
```

指定された条件をジョブ実行ロールが満たすためには、次の権限が必要です。


| アクセス許可 | ジョブ実行ロールで必要になる条件 | 
| --- | --- | 
|  redshift:GetClusterCredentials  | JDBC ドライバーが Amazon Redshift から認証情報を取得するために必要 | 
|  redshift:DescribeCluster  | JDBC URL に Amazon Redshift クラスターのほか、エンドポイントではなく AWS リージョン を指定する場合に必要 | 
|  redshift-serverless:GetCredentials  | JDBC ドライバーが Amazon Redshift Serverless から認証情報を取得するために必要 | 
|  redshift-serverless:GetWorkgroup  | Amazon Redshift Serverless を使用していて、URL にワークグループ名とリージョンを含めて指定する場合に必要 | 

ジョブ実行ロールポリシーには、次の権限が必要です。

```
{
            "Effect": "Allow",
            "Action": [
                "redshift:GetClusterCredentials",
                "redshift:DescribeCluster",
                "redshift-serverless:GetCredentials",
                "redshift-serverless:GetWorkgroup"
            ],
            "Resource": [
                "arn:aws:redshift:AWS_REGION:ACCOUNT_ID:dbname:CLUSTER_NAME/DATABASE_NAME",
                "arn:aws:redshift:AWS_REGION:ACCOUNT_ID:dbuser:DATABASE_NAME/USER_NAME"
            ]
        }
```

## JDBC ドライバーによる Amazon Redshift の認証
<a name="emr-spark-redshift-jdbc"></a>

**JDBC URL 内にユーザー名とパスワードを設定する**

Amazon Redshift クラスターに対して Spark ジョブを認証する場合は、JDBC URL に Amazon Redshift データベース名とパスワードを指定できます。

**注記**  
URL にデータベース認証情報を渡すと、その URL にアクセスできるユーザーなら誰でもその認証情報にアクセスできます。この方法は、安全な方法ではないため、一般的にはお勧めしません。

ご使用のアプリケーションでセキュリティが問題にならない場合は、JDBC URL に次の形式を使用してユーザー名とパスワードを設定できます。

```
jdbc:redshift://redshifthost:5439/database?user=username&password=password
```

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

Spark コネクタは、認証情報の管理、セキュリティの設定、他の AWS サービスとの接続を行うさまざまな方法をサポートしています。機能的で回復力のある接続を設定するには、このリストの推奨事項について習熟してください。
+ Amazon EMR 上の Spark から Amazon Redshift への JDBC 接続に対して SSL をアクティブ化することをお勧めします。
+ ベストプラクティスとして、 AWS Secrets Manager で Amazon Redshift クラスターの認証情報を管理することをお勧めします。例については[AWS Secrets Manager 、「 を使用して Amazon Redshift に接続するための認証情報を取得する](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-spark-redshift-secrets.html)」を参照してください。
+ Amazon Redshift 認証パラメータのパラメータ `aws_iam_role` を使用して IAM ロールを渡すことをお勧めします。
+ 現在、パラメータ `tempformat` は Parquet 形式をサポートしていません。
+ `tempdir` URI は Amazon S3 の場所を指します。この一時ディレクトリは、自動的にはクリーンアップされないため、追加コストが発生する可能性があります。
+ Amazon Redshift については、次の推奨事項を検討してください。
  + Amazon Redshift クラスターにパブリックにアクセスできないようにすることをお勧めします。
  + [Amazon Redshift 監査ログ作成](https://docs.aws.amazon.com/redshift/latest/mgmt/db-auditing.html)を有効にすることをお勧めします。
  + [Amazon Redshift 保管時の暗号化](https://docs.aws.amazon.com/redshift/latest/mgmt/security-server-side-encryption.html)を有効にすることをお勧めします。
+ Amazon S3 については、次の推奨事項を検討してください。
  + [Amazon S3 バケットへのパブリックアクセスをブロックする](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html)ことをお勧めします。
  + [Amazon S3 サーバー側の暗号化](https://docs.aws.amazon.com/AmazonS3/latest/userguide/serv-side-encryption.html)を使用して、使用する S3 バケットを暗号化することをお勧めします。
  + [Amazon S3 ライフサイクルポリシー](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html)を使用して、S3 バケットの保持ルールを定義することをお勧めします。
  + Amazon EMR は、常にオープンソースからイメージにインポートされるコードを検証します。セキュリティのため、Spark から Amazon S3 `tempdir` への認証方法として URI の 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)