STEP 25:クラスター管理とコスト最適化

💰 STEP 25: クラスター管理とコスト最適化

スポットインスタンスと自動スケーリングで、コストを50%以上削減しよう

📋 このステップで学ぶこと

  • クラスターサイジングの考え方
  • スポットインスタンス(Preemptible VM)の活用
  • 自動スケーリングの設定
  • コスト見積もりと予算管理
  • モニタリングとログ分析
💡 このステップのゴール

適切なコスト最適化を行うことで、同じ処理を50〜70%安く実行できます。
実務で必須のスキルを身につけましょう!

📊 1. クラスターサイジングの考え方

1-1. クラスターサイズの決め方

クラスターサイズは、処理するデータ量必要な処理時間から決定します。
大きすぎるとコストが無駄になり、小さすぎると処理が遅くなります。

データサイズ 推奨ワーカー数 推奨インスタンス 用途
〜10GB 2台 m5.xlarge / n1-standard-4 開発・テスト
10〜100GB 4〜8台 m5.2xlarge / n1-standard-8 中規模バッチ
100GB〜1TB 10〜20台 r5.4xlarge / n1-highmem-16 大規模処理
1TB以上 20台以上 r5.8xlarge / n1-highmem-32 超大規模

1-2. 目安の計算式

📐 クラスターサイズの目安

必要メモリ = データサイズ × 2〜3倍
(Sparkは中間結果にメモリを使用するため)

例:100GBのデータを処理
・必要メモリ:100GB × 2.5 = 250GB
・n1-standard-8(30GB)の場合:250 ÷ 30 ≒ 9台
・余裕を持って10台で構成

1-3. CPU vs メモリ、どちらを重視?

処理タイプ 重視するリソース 推奨インスタンス
ETL、集計 バランス型 m5系 / n1-standard系
JOIN、ソート メモリ重視 r5系 / n1-highmem系
機械学習 CPU重視 c5系 / n1-highcpu系

⚡ 2. スポットインスタンスの活用

2-1. スポットインスタンスとは?

スポットインスタンス(GCPではPreemptible VM)は、
クラウドプロバイダーの余剰リソースを大幅割引価格で利用できるサービスです。

💰 スポットインスタンスのメリット

・オンデマンド価格の50〜90% OFF
・同じ処理が半額以下で実行可能
・バッチ処理に最適

⚠️ スポットインスタンスの注意点

中断される可能性がある(需要増加時に回収される)
・GCP Preemptible VMは最大24時間で強制終了
マスターノードには使わない(中断で全体が止まる)

2-2. AWS EMRでのスポットインスタンス設定

# EMRクラスター作成時にスポットインスタンスを指定

aws emr create-cluster \
    --name "spark-spot-cluster" \
    --release-label emr-7.0.0 \
    --applications Name=Spark \
    --instance-groups \
        InstanceGroupType=MASTER,InstanceType=m5.xlarge,InstanceCount=1 \
        InstanceGroupType=CORE,InstanceType=m5.xlarge,InstanceCount=2,BidPrice=0.10 \
    --region ap-northeast-1

# BidPrice: 支払う最大価格(オンデマンド価格より低く設定)

2-3. GCP DataprocでのPreemptible VM設定

# Dataprocクラスター作成時にPreemptible VMを指定

gcloud dataproc clusters create my-spark-cluster \
    --region=asia-northeast1 \
    --master-machine-type=n1-standard-4 \
    --worker-machine-type=n1-standard-4 \
    --num-workers=2 \
    --num-secondary-workers=3 \
    --secondary-worker-type=preemptible

# secondary-workers: 追加のワーカー(Preemptible)
# 通常ワーカー2台 + Preemptible 3台 = 合計5台のワーカー

2-4. コスト比較の実例

構成 オンデマンド スポット利用 削減率
m5.xlarge × 5台 × 2時間 $2.00 $0.60 70% OFF
r5.4xlarge × 10台 × 4時間 $40.00 $16.00 60% OFF
💡 スポットインスタンス活用のベストプラクティス

マスター:オンデマンド(安定性重視)
コアワーカー:オンデマンド or スポット混在
タスクワーカー:スポット(中断されてもOK)
チェックポイントを設定して中間結果を保存

📈 3. 自動スケーリング

3-1. 自動スケーリングとは?

自動スケーリングは、処理負荷に応じて自動でノード数を増減する機能です。
処理が集中する時だけノードを増やし、アイドル時は減らすことでコストを最適化します。

📊 自動スケーリングの効果

【固定クラスター】
━━━━━━━━━━━━━━━ 10台常時稼働
    ↓ 処理がない時間も10台分の課金

【自動スケーリング】
━━━┓    ┏━━━━━ 負荷高い時:10台
  ┗━━━━━┛     負荷低い時:2台
    ↓ 必要な時だけ増加、コスト削減

3-2. EMRの自動スケーリング設定

# EMR自動スケーリングポリシー(JSON)

{
  "Constraints": {
    "MinCapacity": 2,    // 最小ワーカー数
    "MaxCapacity": 10    // 最大ワーカー数
  },
  "Rules": [
    {
      "Name": "ScaleOut",
      "Action": {
        "SimpleScalingPolicyConfiguration": {
          "AdjustmentType": "CHANGE_IN_CAPACITY",
          "ScalingAdjustment": 2,      // 2台追加
          "CoolDown": 300              // 5分間隔
        }
      },
      "Trigger": {
        "CloudWatchAlarmDefinition": {
          "MetricName": "YARNMemoryAvailablePercentage",
          "ComparisonOperator": "LESS_THAN",
          "Threshold": 20              // メモリ20%以下で発動
        }
      }
    },
    {
      "Name": "ScaleIn",
      "Action": {
        "SimpleScalingPolicyConfiguration": {
          "AdjustmentType": "CHANGE_IN_CAPACITY",
          "ScalingAdjustment": -1,     // 1台削減
          "CoolDown": 300
        }
      },
      "Trigger": {
        "CloudWatchAlarmDefinition": {
          "MetricName": "YARNMemoryAvailablePercentage",
          "ComparisonOperator": "GREATER_THAN",
          "Threshold": 75              // メモリ75%以上で発動
        }
      }
    }
  ]
}

3-3. Dataprocの自動スケーリング設定

# Dataprocクラスター作成時に自動スケーリングを有効化

gcloud dataproc clusters create my-spark-cluster \
    --region=asia-northeast1 \
    --num-workers=2 \
    --enable-autoscaling \
    --autoscaling-policy=my-policy

# 自動スケーリングポリシーを事前に作成
gcloud dataproc autoscaling-policies create my-policy \
    --region=asia-northeast1 \
    --min-workers=2 \
    --max-workers=10 \
    --scale-up-factor=0.5 \
    --scale-down-factor=0.5 \
    --cooldown-period=120s
✅ 自動スケーリングのベストプラクティス

最小台数:処理に最低限必要な台数を設定
最大台数:予算上限を考慮して設定
クールダウン:頻繁なスケールを防ぐため5分以上
トリガー:メモリ使用率が一般的

📋 4. コスト見積もりと予算管理

4-1. コスト計算の要素

コスト要素 説明 目安
インスタンス料金 EC2/GCEの時間課金 全体の70〜80%
EMR/Dataproc料金 マネージドサービス料金 インスタンスの20〜25%
ストレージ料金 S3/GCS保存料金 月$0.023/GB〜
データ転送料金 リージョン外への転送 $0.09/GB〜

4-2. コスト計算の例

📐 コスト計算例:毎日2時間のバッチ処理

構成:m5.xlarge(マスター1台 + ワーカー4台)

【オンデマンドの場合】
・EC2: $0.192/時間 × 5台 × 2時間 = $1.92/日
・EMR: $0.048/時間 × 5台 × 2時間 = $0.48/日
・合計: $2.40/日 × 30日 = $72/月

【スポット利用の場合】
・EC2: $0.058/時間 × 5台 × 2時間 = $0.58/日
・EMR: $0.048/時間 × 5台 × 2時間 = $0.48/日
・合計: $1.06/日 × 30日 = $32/月

削減額:$72 – $32 = $40/月(56% OFF)

4-3. 予算アラートの設定

# AWS Budget アラート(CLI)

aws budgets create-budget \
    --account-id 123456789012 \
    --budget '{
        "BudgetName": "EMR-Monthly",
        "BudgetLimit": {"Amount": "100", "Unit": "USD"},
        "BudgetType": "COST",
        "TimeUnit": "MONTHLY"
    }' \
    --notifications-with-subscribers '[{
        "Notification": {
            "NotificationType": "ACTUAL",
            "ComparisonOperator": "GREATER_THAN",
            "Threshold": 80
        },
        "Subscribers": [{"SubscriptionType": "EMAIL", "Address": "alert@example.com"}]
    }]'

# 予算の80%を超えたらメール通知
# GCP Budget アラート(CLI)

gcloud billing budgets create \
    --billing-account=BILLING_ACCOUNT_ID \
    --display-name="Dataproc Monthly Budget" \
    --budget-amount=100USD \
    --threshold-rule=percent=0.8,basis=current-spend \
    --all-updates-rule.pubsub-topic=projects/PROJECT_ID/topics/budget-alerts
⚠️ 予算管理の重要性

予算アラートは必ず設定してください
・クラスターの終了忘れで高額請求になるケースが多い
・80%、100%の2段階でアラートを設定すると安心

📊 5. モニタリングとログ分析

5-1. Spark Web UI

Spark Web UIは、ジョブの実行状況をリアルタイムで確認できるダッシュボードです。

🖥️ Spark Web UIで確認できること

Jobs:ジョブの実行状況と所要時間
Stages:各ステージの詳細(タスク数、シャッフル量)
Storage:キャッシュされたデータの状態
Executors:各Executorのリソース使用状況
SQL:SQLクエリの実行計画

5-2. EMR/Dataprocのモニタリング

# EMR: CloudWatchでメトリクス確認

aws cloudwatch get-metric-statistics \
    --namespace AWS/ElasticMapReduce \
    --metric-name YARNMemoryAvailablePercentage \
    --dimensions Name=ClusterId,Value=j-XXXXX \
    --start-time 2024-01-01T00:00:00Z \
    --end-time 2024-01-01T23:59:59Z \
    --period 300 \
    --statistics Average

# Dataproc: Cloud Monitoringでメトリクス確認
# GCPコンソール → Monitoring → ダッシュボードで確認

5-3. 重要なメトリクス

メトリクス 意味 目安
YARN Memory % 利用可能メモリの割合 20〜70%が適正
CPU Utilization CPU使用率 60〜80%が適正
Apps Running 実行中のアプリ数 用途による
HDFS Utilization HDFSストレージ使用率 80%以下
💡 パフォーマンス改善のヒント

メモリ不足:インスタンスサイズを上げる or ノード追加
CPU不足:CPUコア数の多いインスタンスに変更
シャッフル多い:パーティション設計を見直し(STEP 21参照)
遅いステージ特定:Spark Web UIで確認

📝 練習問題

問題 1 基礎

クラスターサイズの決定

50GBのデータを処理する場合、必要なメモリはおおよそ何GBですか?また、n1-standard-8(30GBメモリ)を使う場合、何台のワーカーが必要ですか?

【解答】

・必要メモリ:50GB × 2.5 = 125GB
・n1-standard-8の場合:125 ÷ 30 ≒ 4.2 → 5台(余裕を持って)

問題 2 応用

スポットインスタンスの設定

GCP Dataprocで、通常ワーカー2台 + Preemptible VM 4台のクラスターを作成するコマンドを書いてください。

【解答】
gcloud dataproc clusters create my-cluster \
    --region=asia-northeast1 \
    --num-workers=2 \
    --num-secondary-workers=4 \
    --secondary-worker-type=preemptible
問題 3 応用

コスト計算

m5.xlarge($0.192/時間)× 5台で毎日3時間、30日間処理する場合のオンデマンド月額コストを計算してください。

【解答】

$0.192 × 5台 × 3時間 × 30日 = $86.40/月

問題 4 実践

コスト最適化戦略

以下の条件で、最もコスト効率の良いクラスター構成を提案してください。
・処理データ:100GB
・許容処理時間:4時間以内
・バッチ処理(中断されても再実行可能)

【解答例】

構成:
・マスター:n1-standard-4 × 1台(オンデマンド)
・ワーカー:n1-standard-8 × 2台(オンデマンド)
・追加ワーカー:n1-standard-8 × 4台(Preemptible)

理由:
・100GB × 2.5 = 250GB必要
・n1-standard-8(30GB)× 6台 = 180GB(マスター除く)
・Preemptibleで約60%コスト削減
・中断されても再実行可能なので、スポット利用に適している
・4時間以内に収まる十分なリソース

❓ よくある質問

Q1: スポットインスタンスが中断されたらどうなる?
処理中のタスクが失敗しますが、Sparkは自動で再試行します。チェックポイントを設定しておくと、中断されても続きから再開できます。
Q2: 自動スケーリングで最小台数を0にできる?
通常は0にできません。最小1〜2台のワーカーが必要です。完全にゼロにしたい場合は、クラスターを終了して必要な時に再作成する方式にします。
Q3: コストを抑えるために一番効果的なことは?
①使用後のクラスター終了②スポットインスタンス活用③適切なサイジングの3つです。特に終了忘れが最も高額請求の原因になります。
Q4: リザーブドインスタンスは使うべき?
常時稼働するクラスター(24時間365日)の場合は、リザーブドインスタンスで30〜60%節約できます。バッチ処理のみの場合は、スポットインスタンスの方が効果的です。

📝 STEP 25 のまとめ

✅ このステップで学んだこと

クラスターサイジング:データサイズ × 2〜3倍のメモリが目安
スポットインスタンス:50〜90% OFF、ワーカーに活用
自動スケーリング:負荷に応じてノード数を自動調整
予算アラート:必ず設定して課金事故を防止
モニタリング:Spark Web UIとクラウドのメトリクスで監視

💰 コスト最適化のまとめ

スポットインスタンスで50〜70%削減
自動スケーリングで無駄なリソースを削減
適切なサイジングで過剰リソースを防止
クラスター終了を忘れない!

🎯 次のステップの予告

次のSTEP 26では、「実践的なSparkジョブ設計」を学びます。
本番環境を想定したエラーハンドリングとログ設計を習得しましょう!

📝

学習メモ

ビッグデータ処理(Apache Spark) - Step 25

📋 過去のメモ一覧
#artnasekai #学習メモ
LINE