Mímisbrunnr知恵の泉

← データエンジニアリング 一覧

🎓 レベル:標準 | 重要度:A(必須)

📎 前提:MapReduceの考え方 | 関連:シャッフルとパーティショニングSQLの基礎(結合・集約・サブクエリ)

要点(BLUF)

概念 ── 分散コレクションを操作する

Sparkでは、巨大なデータを「多数のパーティションに分割された1つのコレクション」として扱い、map/filter/groupBy/joinをあたかも手元のリスト操作のように書きます。実体は各パーティションが別マシンで並列処理されます。

flowchart LR
    DF["DataFrame(論理的には1つの表)"] --> P1["partition 1(マシンA)"]
    DF --> P2["partition 2(マシンB)"]
    DF --> P3["partition 3(マシンC)"]

DataFrameは行と名前付き列を持つ表(→ SQLの基礎(結合・集約・サブクエリ) のテーブルと同じ感覚)で、実際 Spark SQL としてSQLでも書けます。

仕組み ── 遅延評価とDAG

変換は「何をするかの記録」を積むだけで、すぐには動きません。アクションが呼ばれた瞬間、Sparkは積まれた変換を**DAG(有向非巡回グラフ)**として最適化し、まとめて実行します。

# 変換(transformation):ここではまだ実行されない(記録するだけ)
df2 = (df.filter(df.amount > 1000)     # 行を絞る
         .select("region", "amount")   # 列を絞る
         .groupBy("region").sum())     # 集約
# アクション(action):ここで初めてDAGが最適化され実行される
df2.show()
flowchart LR
    T1["filter"] --> T2["select"] --> T3["groupBy/sum"] --> A["show(アクション)"]
    A -.トリガー.-> EX["DAGを最適化して一括実行"]

遅延にする利点は最適化の余地。「あとでgroupByするなら、先にfilter/selectして読む量を減らそう」といった述語/射影プッシュダウンをSparkが自動で行えます。ラボでこの効果(全2000行→必要1000行だけ評価)を数で確認しました。

実行結果(実機・純Pythonで効果を再現):

全行数: 2000
素朴: 全2000行スキャン後に絞る -> 1000行
プッシュダウン: 必要な1000行だけ評価(無駄スキャン削減)

設計の勘所 ── 変換とアクション・耐障害

種類性質
変換(lazy)filter, select, groupBy, join記録のみ・即実行しない
アクションcount, collect, show, writeDAGをトリガーし実行

なぜそうするか ── メモリと最適化

なぜMapReduceでなくSparkなのか。(1) インメモリ:MapReduceは段ごとに中間結果をディスクに書くため、反復(機械学習・グラフ処理)で遅い。Sparkはメモリ保持で反復が速い。(2) 遅延評価+最適化:処理全体を見てから実行計画を立てられるので、読む量・移動量を自動で削れる。手続きを1つずつ即実行する素朴な方式では、この全体最適ができません。「全部の手順を見てから、一番無駄のない順で動く」——これが速さと書きやすさの源です。

⚠️ よくある落とし穴

対応ラボ

data-engineering-study/labs/06_distributed.pyPYTHONIOENCODING=utf-8 で実行・プッシュダウン効果を確認済み。Spark APIは本文に言語明示で例示)。

関連

第6章 分散処理 目次