Amazon EMR で実行する Apache Spark - ビッグデータ処理のクラスタ設計とコスト最適化

EMR による Spark クラスタの構築、EMR Serverless との使い分け、スポットインスタンス活用によるコスト最適化を解説します。

EMR の概要

EMR は Apache Spark、Hive、Presto、Flink など 20 以上のビッグデータフレームワークをマネージドクラスタで実行するサービスです。クラスタはマスターノード、コアノード、タスクノードで構成され、EMR がプロビジョニング、設定、パッチ適用を自動管理します。EMR Serverless は 2022 年に GA となったモードで、クラスタの管理が完全に不要です。Spark ジョブを投入するだけで、必要なリソースが自動的にプロビジョニングされます。S3 をストレージとして使用する「コンピュートとストレージの分離」アーキテクチャが標準で、HDFS に依存せずにクラスタを停止・再作成できるため、柔軟なライフサイクル管理が可能です。

コスト最適化

EMR のコスト最適化はインスタンス構成の設計が鍵です。マスターノードとコアノードはオンデマンドインスタンスで安定性を確保し、タスクノードにスポットインスタンスを使用します。タスクノードはデータを保持しないため、スポットの中断時にデータ損失のリスクがありません。インスタンスフリートで複数のインスタンスタイプを指定し、スポットの可用性を向上させます。EMR Serverless は断続的なジョブに適しており、ジョブ実行中のみ課金されます。EMR on EC2 の料金は EC2 インスタンス料金に加えて EMR の管理料金 (EC2 料金の約 25%) が上乗せされるため、長時間稼働クラスタには Savings Plans の適用が効果的です。

Spark チューニングとデータフォーマット

Spark ジョブのパフォーマンスはパーティション数、エグゼキューター設定、データフォーマットの選択に大きく依存します。spark.sql.shuffle.partitions をデータ量に応じて調整し、デフォルトの 200 から適切な値に変更します。Parquet 形式はカラムナーストレージで、必要なカラムのみを読み込むため、CSV と比較してスキャン量と処理時間を大幅に削減します。Adaptive Query Execution (AQE) を有効にすると、実行時の統計に基づいてシャッフルパーティション数やジョイン戦略を自動最適化します。Delta Lake や Apache Iceberg のテーブルフォーマットを使うと、ACID トランザクション、タイムトラベル、スキーマ進化をデータレイク上で実現できます。Spark 3.x 以降では Dynamic Partition Pruning (DPP) がパーティションテーブルの結合を自動最適化し、不要なパーティションの読み込みを排除します。 EMR に関する実践的なノウハウはAmazon の関連書籍でも確認できます。

EMR クラスターのコスト管理

インスタンスフリートを使うと、複数のインスタンスタイプを指定してスポットの可用性を最大化できます。オンデマンドとスポットの混合比率を設定し、ベースラインをオンデマンドで確保しつつ追加キャパシティをスポットで賄います。EMR Serverless はクラスター管理が不要で、ジョブ実行時間分のみの課金のため、散発的なバッチ処理に最適です。長時間稼働するクラスターには Savings Plans を適用し、コミットメント割引を活用します。CloudWatch メトリクスで YARN のリソース使用率を監視し、過剰なクラスターサイズを検出して適正化します。Managed Scaling を有効にすると、YARN のメトリクスに基づいてタスクノードを自動スケールし、ピーク時のみリソースを追加してアイドル時に縮小できます。

EMR on EC2、EMR Serverless、EMR on EKS の使い分け

EMR には 3 つのデプロイメントオプションがあり、ワークロードの特性に応じて選択します。EMR on EC2 は従来型のクラスタモードで、Spark の設定を細かくカスタマイズしたい場合や、ライブラリのインストール、HDFS が必要なワークロードに適しています。EMR Serverless はクラスタのプロビジョニングが不要で、日次バッチや散発的な ETL ジョブなど「投入して待つだけ」のワークロードに最適です。起動のオーバーヘッドが数十秒あるため、低レイテンシが求められるインタラクティブクエリには不向きです。EMR on EKS は Kubernetes クラスタ上で Spark ジョブを実行するオプションで、既に EKS を運用しているチームがインフラを統合したい場合や、他のコンテナワークロードとリソースを共有したい場合に選択します。コスト面では、EMR Serverless は短時間ジョブでは EC2 よりも GB 単価が割安になる一方、長時間ジョブでは EC2 クラスタの方がスポット + Savings Plans により低コストになる傾向があります。

設計の落とし穴と運用上の注意点

EMR で Spark を運用する際に陥りやすい問題がいくつかあります。まず、小さなファイルの大量発生 (Small File Problem) はメタデータ処理のオーバーヘッドを増大させ、S3 の GET リクエスト料金も膨らみます。Spark の coalesce や repartition で出力ファイル数を制御するか、Iceberg の compaction 機能で定期的に小ファイルをマージします。次に、スポットインスタンスの中断対策として、Spark の spark.speculation を有効にして遅延タスクを投機実行し、中断されたタスクのリカバリ時間を短縮します。データスキューも頻出する問題で、特定のパーティションキーにデータが偏るとシャッフル時にメモリ不足やタスク処理時間の偏りが発生します。AQE の skew join 最適化や、salting 手法 (キーにランダムなサフィックスを付与して分散) で対処します。最後に、EMR の EMRFS を通じた S3 アクセスでは、S3 の結果整合性は 2020 年 12 月以降強い整合性に変更されたため、過去の整合性問題を心配する必要はなくなりました。

まとめ

EMR はビッグデータフレームワークをマネージドに実行するサービスです。Adaptive Query Execution で Spark ジョブのパフォーマンスを自動最適化し、Parquet 形式と適切なパーティション設計でクエリ効率を向上させます。インスタンスフリートでスポットの可用性を最大化し、EMR Serverless で散発的なバッチ処理のコスト効率を高めます。3 つのデプロイオプション (EC2、Serverless、EKS) をワークロード特性に応じて使い分け、Small File Problem やデータスキューなどの運用上の落とし穴を事前に設計で回避することが、安定した大規模データ処理の鍵です。