この記事について
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/