OSS Apache Spark の全体像:デプロイモード、spark-submit、Kubernetes対応

この記事について

Databricks は Spark の商用プラットフォームだが、Spark 自体は Apache License 2.0 のオープンソースである。この記事では OSS Spark のデプロイ・運用・設定を整理し、Databricks Runtime との違いを明確にする。

1. OSS Spark のデプロイモード

1-1. Cluster Manager の選択肢

Cluster Manager 特徴 用途
Standalone Spark 同梱。追加インフラ不要 開発・検証、小規模
YARN Hadoop エコシステムと統合 既存 Hadoop 環境、EMR
Kubernetes コンテナベース。クラウドネイティブ モダンなインフラ、マルチテナント
Mesos 汎用リソースマネージャ ほぼ非推奨(Spark 3.2 で deprecated)

1-2. Client Mode vs Cluster Mode

Client Mode:
  ┌──────────┐
  │ Client   │  ← Driver がここで動く(手元のマシン)
  │ (Driver) │
  └────┬─────┘
       │
  ┌────┴──────────────┐
  │ Cluster            │
  │  Executor Executor │  ← Executor だけクラスタ上
  └───────────────────┘
  用途: 対話的な開発(spark-shell, notebook)

Cluster Mode:
  ┌───────────────────┐
  │ Cluster            │
  │  Driver            │  ← Driver もクラスタ上
  │  Executor Executor │
  └───────────────────┘
  用途: 本番ジョブ(spark-submit)
Client Mode Cluster Mode
Driver の場所 投入元マシン クラスタ内
ログ確認 手元のコンソール Cluster Manager 経由
ネットワーク Driver↔︎Executor 間の通信が必要 クラスタ内で完結
用途 開発・デバッグ 本番運用

2. spark-submit

2-1. 基本構文

spark-submit \
  --master yarn \
  --deploy-mode cluster \
  --driver-memory 4g \
  --executor-memory 8g \
  --executor-cores 4 \
  --num-executors 10 \
  --conf spark.sql.shuffle.partitions=200 \
  --py-files dependencies.zip \
  my_job.py --input s3://data/raw --output s3://data/processed

2-2. 主要パラメータ

パラメータ 説明 目安
--master Cluster Manager の URL yarn, k8s://..., local[*]
--deploy-mode client or cluster 本番は cluster
--driver-memory Driver のメモリ 2〜8g(collect しなければ小さくてよい)
--executor-memory 各 Executor のメモリ 4〜16g
--executor-cores 各 Executor のコア数 4〜5(多すぎると GC 問題)
--num-executors Executor 数 データ量とコア数から算出
--conf 任意の Spark 設定 key=value 形式

2-3. リソース見積もりの考え方

例: 100GB のデータを処理、ノードは 16コア 64GB × 10台

1. Executor あたりのコア数: 5(推奨上限)
2. ノードあたりの Executor 数: 16 / 5 = 3(1コアは OS 用に残す)
3. Executor あたりのメモリ: (64 - 1) / 3 ≈ 21g
   → overhead 10% を引いて --executor-memory 19g
4. 総 Executor 数: 3 × 10 = 30
   → --num-executors 29(1つは Driver 用に残す)
5. 総コア数: 29 × 5 = 145
6. パーティション数: 145 × 2〜3 = 290〜435

3. Spark on YARN

3-1. アーキテクチャ

┌─────────────────────────────────────┐
│            YARN Cluster              │
│                                     │
│  ResourceManager                    │
│       │                             │
│  ┌────┴────┐  ┌─────────┐          │
│  │NodeMgr  │  │NodeMgr  │  ...     │
│  │         │  │         │          │
│  │Container│  │Container│          │
│  │(Driver) │  │(Executor)│          │
│  │         │  │         │          │
│  │Container│  │Container│          │
│  │(Executor)│  │(Executor)│          │
│  └─────────┘  └─────────┘          │
└─────────────────────────────────────┘
         │
         ▼
      HDFS / S3

3-2. YARN 固有の設定

設定 説明
spark.yarn.queue YARN キュー名(リソース分離)
spark.yarn.executor.memoryOverhead Executor のオフヒープメモリ
spark.yarn.am.memory Application Master のメモリ

3-3. AWS EMR での利用

EMR は YARN 上で Spark を動かすマネージドサービス。

# EMR クラスタ作成
aws emr create-cluster \
  --release-label emr-7.0.0 \
  --applications Name=Spark \
  --instance-type m5.xlarge \
  --instance-count 10

# EMR Step でジョブ投入
aws emr add-steps \
  --cluster-id j-XXXXX \
  --steps Type=Spark,Args=[--class,MyJob,s3://jars/my-job.jar]

4. Spark on Kubernetes

4-1. アーキテクチャ

┌─────────────────────────────────────┐
│          Kubernetes Cluster          │
│                                     │
│  ┌─────────┐                        │
│  │  Pod     │  ← Driver Pod         │
│  │ (Driver) │                        │
│  └────┬────┘                        │
│       │ Executor Pod を動的に生成     │
│  ┌────┴────┐  ┌─────────┐           │
│  │  Pod     │  │  Pod     │  ...    │
│  │(Executor)│  │(Executor)│          │
│  └─────────┘  └─────────┘          │
└─────────────────────────────────────┘

4-2. spark-submit for K8s

spark-submit \
  --master k8s://https://k8s-api-server:6443 \
  --deploy-mode cluster \
  --conf spark.kubernetes.container.image=my-spark:3.5.0 \
  --conf spark.kubernetes.namespace=spark-jobs \
  --conf spark.kubernetes.executor.request.cores=2 \
  --conf spark.kubernetes.executor.limit.cores=4 \
  --conf spark.kubernetes.driver.pod.name=my-job-driver \
  local:///opt/spark/my_job.py

4-3. K8s の利点と課題

利点 課題
コンテナイメージで環境を固定 Shuffle データの永続化(Pod 再起動で消える)
動的な Executor 生成・破棄 ネットワーク性能(Pod 間通信)
マルチテナント(Namespace 分離) ストレージ(ローカルディスクが限定的)
クラウドネイティブ(EKS, GKE, AKS) 運用の複雑さ(K8s の知識が必要)

4-4. Volcano / Yunikorn

K8s 標準のスケジューラはバッチジョブに最適化されていない。Spark on K8s では以下のバッチスケジューラが使われることが多い。

スケジューラ 特徴
Volcano Gang Scheduling(全 Executor が揃ってから開始)
Apache YuniKorn キューベースのリソース管理、Fair Scheduling

5. Spark の設定チューニング

5-1. 重要な設定項目

カテゴリ 設定 デフォルト 説明
メモリ spark.executor.memory 1g Executor のヒープメモリ
メモリ spark.memory.fraction 0.6 Unified Memory の割合
メモリ spark.memory.storageFraction 0.5 Storage の初期割合
並列度 spark.sql.shuffle.partitions 200 シャッフル後のパーティション数
並列度 spark.default.parallelism 全コア数 RDD のデフォルトパーティション数
シャッフル spark.sql.autoBroadcastJoinThreshold 10MB Broadcast Join の閾値
AQE spark.sql.adaptive.enabled true (3.2+) Adaptive Query Execution
シリアライズ spark.serializer Java Kryo を推奨
圧縮 spark.io.compression.codec lz4 シャッフルデータの圧縮

5-2. GC チューニング

--conf spark.executor.extraJavaOptions="-XX:+UseG1GC -XX:G1HeapRegionSize=16m"
症状 対策
Full GC が頻発 Executor メモリを増やす / パーティション数を増やす
GC 時間が長い G1GC を使用 / Executor あたりのコア数を減らす
OOM spark.memory.fraction を下げる / オフヒープを有効化

6. OSS Spark vs Databricks Runtime

観点 OSS Spark Databricks Runtime
エンジン Spark Core Spark Core + Photon(C++)
最適化 Catalyst + AQE Catalyst + AQE + Databricks 独自最適化
Delta Lake 別途追加が必要 ネイティブ統合
Auto Scaling Cluster Manager 依存 組み込み(自動スケール)
クラスタ管理 手動(YARN/K8s 設定) UI/API で簡単
ノートブック Jupyter / Zeppelin Databricks Notebook(協調編集)
ジョブ管理 spark-submit / Airflow Workflows
性能 ベースライン OSS 比 2〜5倍高速(公称)
コスト インフラ費用のみ インフラ + DBU
サポート コミュニティ 商用サポート

Databricks Runtime の独自最適化

最適化 説明
Photon C++ ネイティブ実行エンジン。JVM オーバーヘッドなし
Delta Engine Delta Lake に特化したクエリ最適化
Disk Cache ローカル SSD にリモートデータを自動キャッシュ
Dynamic File Pruning Join 時に不要なファイルを動的にスキップ
Optimized Writes 書き込み時のファイルサイズを自動最適化
Auto Compaction 小さなファイルを自動的に結合

7. Spark のバージョン履歴

バージョン 主な新機能
1.0 2014 初の安定版。RDD API
1.3 2015 DataFrame API
1.6 2016 Dataset API
2.0 2016 Structured Streaming、Tungsten Phase 2
2.3 2018 Kubernetes サポート(実験的)
2.4 2019 Barrier Execution Mode(ML向け)
3.0 2020 AQE、Dynamic Partition Pruning、K8s GA
3.2 2022 AQE デフォルト有効、Mesos deprecated
3.3 2022 ANSI モード改善
3.4 2023 Spark Connect(クライアント・サーバー分離)
3.5 2023 Arrow-based Python UDF、English SDK
4.0 2024 Spark Connect デフォルト、Variant 型、Collation

Spark Connect(3.4+)

クライアントとサーバーを分離するアーキテクチャ。

従来:
  PySpark → JVM (同一プロセス) → Executor
  → Driver のメモリ・依存関係がクライアントに影響

Spark Connect:
  PySpark Client → gRPC → Spark Connect Server → Executor
  → クライアントは軽量。サーバーを共有可能

Databricks の Serverless Compute はこの仕組みを活用している。

8. まとめ

テーマ 要点
デプロイ YARN(Hadoop環境)、K8s(モダン)、Standalone(開発)
spark-submit 本番は cluster mode。リソースはコア数から逆算
K8s コンテナベースで環境固定。Gang Scheduling が重要
チューニング メモリ、パーティション数、シリアライザ、GC
vs Databricks OSS は自由度高いがインフラ管理が必要。Databricks は性能・運用で優位

参考文献

  • Apache Spark. “Spark Documentation.” https://spark.apache.org/docs/latest/
  • Apache Spark. “Running Spark on Kubernetes.” https://spark.apache.org/docs/latest/running-on-kubernetes.html
  • Jules S. Damji et al. “Learning Spark.” 2nd Edition, O’Reilly Media, 2020.
  • Databricks. “Databricks Runtime Release Notes.” https://docs.databricks.com/en/release-notes/runtime/

コメントする