■ はじめに
最近、EMRに対して悪戦苦闘していて 開き直って、チュートリアルを行ったら 少し道が開いた感じになったので、 EMRのチュートリアルに関する有用性も含めてメモる。
目次
【1】EMRのチュートリアルの有用性 1)ハマりポイントの回避 【2】チュートリアル 0)前提条件 ステップ 1: Amazon EMR クラスターを計画して設定する ステップ 2: Amazon EMR クラスターを管理する ステップ 3: Amazon EMR リソースをクリーンアップする 【3】トラブル エラー「AmazonS3Exception: Access Denied Status Code: 403」が発生する
【1】EMRのチュートリアルの有用性
1)ハマりポイントの回避
EMRには、以下の点でハマりポイントが(個人的には)多い ~~~~~~~~~~~ * IAMロール * Security Group(Master/Slave/ServiceAccessなど) など ~~~~~~~~~~~ また、エラーになった場合、起動前だとログすらでなく エラーメッセージだけで判断しなくてはならず滅茶苦茶しんどい。 それらを事前に簡単な例でStepByStepでき、 次に自分のやりたい構成でやるのに、 動いていた実績のあるIAMロールやSecurity Groupを使って 構築できるので、もし、エラーが出ても変更した部分に 絞り込めるので、トラフィックルーティングも比較的に楽。
【2】チュートリアル
以下の公式ドキュメント
https://docs.aws.amazon.com/ja_jp/emr/latest/ManagementGuide/emr-gs.html
のチュートリアルは、分かりやすくて、シンプルでいい。
0)前提条件
* 以下を作成しておくこと + EMR用のS3バケット
補足:SG/IAMロールについて
* 本当は、以下を作成しておいた方がいいが、初めは、デフォルトで身を任せるのが吉、、、 + Master/Slave/ServiceAccess 用のセキュリティグループ(Security Group) + IAMロール Service-linkedロール/EMR ロール/EC2 インスタンスプロファイル => 以下の関連記事を参照。
Amazon EMR ~ ネットワーク周り ~
https://dk521123.hatenablog.com/entry/2022/05/13/155755
Amazon EMR ~ IAM Role周り ~
https://dk521123.hatenablog.com/entry/2023/07/24/160124
ステップ 1: Amazon EMR クラスターを計画して設定する
[a] EMR PySpark 用のサンプルスクリプトを準備するには
[1] 以下「health_violations.py」をS3バケット内に保存 => e.g. s3://your-s3-bucket/emr/health_violations.py
health_violations.py
import argparse from pyspark.sql import SparkSession def calculate_red_violations(data_source, output_uri): """ Processes sample food establishment inspection data and queries the data to find the top 10 establishments with the most Red violations from 2006 to 2020. :param data_source: The URI of your food establishment data CSV, such as 's3://DOC-EXAMPLE-BUCKET/food-establishment-data.csv'. :param output_uri: The URI where output is written, such as 's3://DOC-EXAMPLE-BUCKET/restaurant_violation_results'. """ with SparkSession.builder.appName("Calculate Red Health Violations").getOrCreate() as spark: # Load the restaurant violation CSV data if data_source is not None: restaurants_df = spark.read.option("header", "true").csv(data_source) # Create an in-memory DataFrame to query restaurants_df.createOrReplaceTempView("restaurant_violations") # Create a DataFrame of the top 10 restaurants with the most Red violations top_red_violation_restaurants = spark.sql("""SELECT name, count(*) AS total_red_violations FROM restaurant_violations WHERE violation_type = 'RED' GROUP BY name ORDER BY total_red_violations DESC LIMIT 10""") # Write the results to the specified output URI top_red_violation_restaurants.write.option("header", "true").mode("overwrite").csv(output_uri) if __name__ == "__main__": print("Starting!!") parser = argparse.ArgumentParser() parser.add_argument( '--data_source', help="The URI for you CSV restaurant data, like an S3 bucket location.") parser.add_argument( '--output_uri', help="The URI where output is saved, like an S3 bucket location.") args = parser.parse_args() print("* Args start ***************") print(args) print("* Args end ***************") calculate_red_violations(args.data_source, args.output_uri) print("Done...")
[b] EMR 用のサンプル入力データを準備するには
[1] 以下からサンプルデータをダウンロードし、ZIPを解凍する
https://docs.aws.amazon.com/ja_jp/emr/latest/ManagementGuide/samples/food_establishment_data.zip
[2] 解凍したフォルダをS3バケットに置く => e.g. s3://your-s3-bucket/emr/food_establishment_data/food_establishment_data.csv
ステップ 2: Amazon EMR クラスターを管理する
[a] Spark アプリケーションを新しいコンソールでステップとして送信するには
[1] AWS Management Console にサインインして、Amazon EMR 画面を表示する
https://console.aws.amazon.com/emr
[2] 左側のナビゲーションペインの [EMR on EC2]-[Clusters] を選択し、 作業を送信するクラスターを選択 => クラスターの状態は [待機中(Waiting)] である必要がある [3] [ステップ(Step)] タブを選択し、[ステップの追加(Add Step)] を選択 [4] 次のガイドラインに従ってステップを設定します。 * 「タイプ」で「Spark アプリケーション」を選択 Deploy モード、アプリケーションの場所、Spark 送信オプションのフィールドが追加 * [名前] に新しい名前を入力 * [アプリケーションの場所] には、Amazon S3 health_violations.py 内のスクリプトの場所 (s3://DOC-EXAMPLE-BUCKET/health_violations.py など) を入力 * Spark 送信オプションフィールドは空のまま * [引数] フィールドに、次の引数と値を入力 ~~~~ --data_source s3://DOC-EXAMPLE-BUCKET/food_establishment_data.csv --output_uri s3://DOC-EXAMPLE-BUCKET/myOutputFolder ~~~~ * 「ステップが失敗した場合のアクション」では、デフォルトのオプション「続行(Continue)」をそのまま [5] [追加] を選択して、ステップを送信 ステップが、[保留中] というステータスでコンソールに表示 [6] [保留中] から [実行中]、[完了] に変わるはず コンソールのステータスを更新するには、フィルターの右側にある更新アイコンを選択 ステータスが「完了」に変わると、ステップは正常に完了
[b] 動作確認
[1] 成功していれば、S3内に以下のようなファイルが出力されているはず => health_violations.py 結果の例を次に示します。 ~~~~~~~~~~ name, total_red_violations SUBWAY, 322 T-MOBILE PARK, 315 WHOLE FOODS MARKET, 299 PCC COMMUNITY MARKETS, 251 TACO TIME, 240 MCDONALD'S, 177 THAI GINGER, 153 SAFEWAY INC #1508, 143 TAQUERIA EL RINCONSITO, 134 HIMITSU TERIYAKI, 128 ~~~~~~~~~~
ステップ 3: Amazon EMR リソースをクリーンアップする
[a] クラスターを終了する
[1] [Clusters] を選択し、終了するクラスターを選択 [2] 「アクション」ドロップダウンメニューで、「クラスターの終了」を選択 [3] ダイアログボックスで「終了」を選択 => クラスター設定によっては、終了に 5~10 分間かかる場合がある
[b] S3 リソースを削除する
[1] S3バケット内の以下のファイルを削除する * PySparkスクリプト * 入力データセット * 出力結果フォルダ * ログファイルフォルダ
【3】トラブル
1)エラー「AmazonS3Exception: Access Denied Status Code: 403」が発生する
エラー内容
Caused by: com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: REQUEST_ID; S3 Extended Request ID: S3_EXTENDED_REQUEST_ID
確認点
https://repost.aws/ja/knowledge-center/emr-s3-403-access-denied
[1] Amazon EC2 インスタンスプロファイルロールのポリシーを確認する [2] Amazon S3 VPC エンドポイントポリシーを確認する
https://youtu.be/hI64CFAjmig?t=485
[3] S3 のレプリケート元およびレプリケート先バケットポリシーを確認
原因
* Slave(EC2インスタンスプロファイル)のIAMロールに S3アクセス権限がなかったため。 => EMR作成時に 「Amazon EMRのEC2インスタンスプロファイル」の 「インスタンスプロファイル作成」で「S3バケット」の「 アカウント内の特定のS3バケットまたはプレフィックス」を選んでしまうと 発生する可能がある
解決案
* Slave(EC2インスタンスプロファイル)のIAMロールにS3アクセス権限を追加する => まずは、切り分けのためにアクションで「"Action": ["s3:*"]」とかしてみるのもありかも。
参考文献
https://docs.aws.amazon.com/ja_jp/emr/latest/ManagementGuide/emr-troubleshoot-error-vpc.html
https://www.youtube.com/watch?v=3nRd9NUfZ14
https://www.youtube.com/watch?v=hI64CFAjmig
https://karukichi-blog.netlify.app/blogs/resolve-403-error-in-s3
関連記事
Amazon EMR ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2020/02/20/230519
Amazon EMR ~ 基本編 ~
https://dk521123.hatenablog.com/entry/2020/05/27/175610
Amazon EMR ~ boto3 編 ~
https://dk521123.hatenablog.com/entry/2020/06/24/173334
Amazon EMR ~ ネットワーク周り ~
https://dk521123.hatenablog.com/entry/2022/05/13/155755
Amazon EMR ~ IAM Role周り ~
https://dk521123.hatenablog.com/entry/2023/07/24/160124
Amazon VPC ~ 基本編 / VPCエンドポイント ~
https://dk521123.hatenablog.com/entry/2022/03/20/000000
SSHクライアント
https://dk521123.hatenablog.com/entry/2019/10/18/233543
ssh コマンド / scp コマンド
https://dk521123.hatenablog.com/entry/2017/12/09/231200
sshポートフォワーディングを使って、Webサーバにアクセスする
https://dk521123.hatenablog.com/entry/2018/02/08/001413