Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction to MapReduce with Apache Spark

Introduction to MapReduce with Apache Spark

首都大学東京で2014年12月に開催された「分散処理実践セミナー Apache Spark による MapReduce の基礎」の講義部分のスライドです。Jimmy Lin, Large-Scale Data Processing with MapReduce. AAAI Tutorial, 2011. の抄訳なので、基本的にはオリジナルをご参照ください。

http://www.umiacs.umd.edu/~jimmylin/cloud-computing/AAAI-2011/AAAI2011-tutorial-slides.pptx

※Apache Spark の演習部分は別スライドで、この中には入っていません。

Mamoru Komachi

December 23, 2014
Tweet

More Decks by Mamoru Komachi

Other Decks in Technology

Transcript

  1. Apache Spark による MapReduce の基礎 分散処理実践セミナー 小町守 首都大学東京システムデザイン学部 情報通信システムコース 2014年12月12日(金)

    このスライドは Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States ライセンスによって公開されています。詳しくは http://creativecommons.org/licenses/by-nc-sa/3.0/ Jimmy Lin, Large-Scale Data Processing with MapReduce. AAAI Tutorial, 2011. の抄訳です
  2. 本セミナーに関して ¢ スケーラブルな処理に焦点を当てます ¢ MapReduce の「デザインパターン」を学びます ¢ 基本的なアイデアを話します ¢ Hadoop

    プログラミングのチュートリアルではありません ¢ GPGPU とも関係ありません ¢ 右の本の入門版(PDF が GitHub で無料 公開されています)です ¢ Jimmy Lin, Large-Scale Data Processing with MapReduce. AAAI Tutorial, 2011 のスライドをベースにしています
  3. どれくらいデータがある? 6.5 PB のユーザデー タ + 50 TB/日 (2009/5) の処理するデータ量=20

    PB/日 (2008) 36 PB のユーザデータ + 500 TB/日 (2012) Wayback Machine: 3 PB + 100 TB/月 (2009/3) 12 TB/日 (2011) 640K あれば十分だよ !(ビル・ゲイツ)
  4. データ量に上限はない! (Banko and Brill, ACL 2001) (Brants et al., EMNLP

    2007) s/知識/データ/g; Google にいない我々はどうやったら こんな規模のデータを使うことができる?
  5. 並列コンピューティングはたいへん! メッセージパッシング P1 P2 P3 P4 P5 共有メモリ P1 P2

    P3 P4 P5 メモリ いろいろなプログラミングモデル いろいろなプログラミングのコンポーネント mutex、バリア、… master/slave、producer/consumer、ワークキュー、… 原理的な問題 スケジューリング、データ分散、同期、プロセ ス間通信、頑健性、フォールトトレランス、… 共有に関する問題 デッドロック、飢餓状態、 優先順位の逆転、… 食事する哲学者、居眠り床屋、… アーキテクチャの問題 SIMD、MIMD、… ネットワークの構造、帯域幅 UMA vs. NUMA、キャッシュコヒーレ ンス 現実: プログラマが平行性の管理の責任を負う。。。 (競合状態のデバッグに苦しむか、新しいアルゴリズムを考案するために時間を使うか) master slave producer consumer producer consumer ワーク キュー
  6. 「ビッグデータ」の理想現実と現実 ¢ 並列処理は難しい l データセンターのスケールだと特に。(データセンターをまたぐ ことすら) l 故障が存在する l 複数の相互に連携するサービスが存在する

    ¢ 現実は? l その場限りの対処ばかり。カスタマイズされたソースコード。 l 特化したライブラリを書いて、それを使ってプログラミング。 l 全てを明示的に管理するようプログラマが気をつけなければなら ない。。。
  7. 何が問題??? ¢ どのように抽象化するか、の問題 ¢ エンジニアからシステムレベルの詳細を隠蔽する l リソースの競合、ロック、などなど。。。 ¢ 対象と手法を分離する l

    エンジニアは処理すべき計算を書くだけでよい l 処理フレームワーク(ランタイム)が実際の処理を担当する データセンターこそがコンピ ュータ
  8. 大規模データ処理の「哲学」 ¢ スケール「アウト」する。(スケール「アップ」ではなく ) l マルチプロセッサ(SMP)と大規模共有メモリマシンの限界 ¢ データ中心の処理を行う l クラスタは限られた帯域しかない

    ¢ データを順番に処理する。ランダムアクセスしない。 l データのシークは高コスト。ディスクのスループットは常識的な 速度。 ¢ シームレスなスケーラビリティ
  9. 典型的な大規模データ処理 ¢ 多数のレコードに対して反復する ¢ それぞれに対してなにか抽出する ¢ 中間結果をシャッフルし、ソートする ¢ 中間結果を集約する ¢

    最終出力を生成する ポイント: これら2つの操作に対する 機能的な抽象化を提供する Map Reduce (Dean and Ghemawat, OSDI 2004)
  10. g g g g g f f f f f

    Map Fold (Reduce) 関数型プログラミングの基本
  11. MapReduce ¢ プログラマは2つの関数を指定する。 map (k, v) → <k’, v’>* reduce

    (k’, v’) → <k’, v’>* l 同じキーを持つ値は全て同じ reducer に送られる ¢ 処理フレームワークが残り全部やってくれる。
  12. map map map map シャッフルとソート: キーで値を集約 reduce reduce reduce k1

    k2 k3 k4 k5 k6 v1 v2 v3 v4 v5 v6 b a 1 2 c c 3 6 a c 5 2 b c 7 8 a 1 5 b 2 7 c 2 3 6 8 r1 s1 r2 s2 r3 s3
  13. MapReduce ¢ プログラマは2つの関数を指定する。 map (k, v) → <k’, v’>* reduce

    (k’, v’) → <k’, v’>* l 同じキーを持つ値は全て同じ reducer に送られる ¢ 処理フレームワークが残り全部やってくれる。 「残り全部」って何?
  14. MapReduce の実行時の動作 ¢ スケジューリング l worker に map と reduce

    タスクを割り当てる ¢ データの分配 l プロセスをデータに移動する ¢ 処理の同期 l 中間結果を集め、シャッフルし、ソートする ¢ エラー処理 l worker の失敗を検出し、リスタートする ¢ 分散ファイルシステムの管理
  15. MapReduce ホントのところ ¢ プログラマは2つの関数を指定する。 map (k, v) → <k’, v’>*

    reduce (k’, v’) → <k’, v’>* l 同じキーを持つ値は全て同じ reducer に送られる ¢ 処理フレームワークが残り全部やってくれる。 ¢ 実際は、プログラマは他にもいくつか指定しなければなら ない。 partition (k’, 分割数) → k’ のパーティション l キーのハッシュが用いられることが多い e.g., hash(k’) mod n l キーの空間を並列 reduce 操作のために分割する combine (k’, v’) → <k’, v’>* l map フェーズのあとにインメモリで実行される mini-reducer l reduce のネットワーク通信の最適化に使われる
  16. combine combine combine combine b a 1 2 c 9

    a c 5 2 b c 7 8 partition partition partition partition map map map map k1 k2 k3 k4 k5 k6 v1 v2 v3 v4 v5 v6 b a 1 2 c c 3 6 a c 5 2 b c 7 8 シャッフルとソート: キーによる値の集約 reduce reduce reduce a 1 5 b 2 7 c 2 9 8 r1 s1 r2 s2 r3 s3 c 2 3 6 8
  17. MapReduce に関する補足2点 ¢ map と reduce のフェーズの間の障壁 l 事前に中間データをコピーするところから始められる ¢

    各 reducer にやってくるキーはソートされている l reducer をまたぐと順番には何の制約もない
  18. MapReduce の実装 ¢ Google は C++ によるプロプライエタリな実装がある l Java と

    Python のバインディングがある ¢ Hadoop は Java によるオープンソースの MapReduce 実 装 l 初期は Yahoo が開発を主導 l 現在は Apache オープンソースプロジェクト l ビッグデータ処理業界におけるデファクトスタンダード l ソフトウェアの「生態系」が急速に拡大 ¢ Spark は Scala による MapReduce 実装 l UC Berkeley で開発されていたが、現在は Apache OSS l インメモリでの処理に特化し高速化 l Scala と Python のバインディングがある 今回のセミナーでは Apache Spark を使用
  19. split 0 split 1 split 2 split 3 split 4

    worker worker worker worker worker Master User Program output file 0 output file 1 (1) submit (2) schedule map (2) schedule reduce (3) read (4) local write (5) remote read (6) write 入力 ファイル Map フェーズ 中間結果 (ローカルディスク) Reduce フェーズ 出力 ファイル Adapted from (Dean and Ghemawat, OSDI 2004)
  20. 分散ファイルシステム ¢ データを worker に移動するのではなく、worker をデータ に移動させる l クラスタのノードのローカルディスクにデータを保持 l

    ローカルにデータを持っているノードで worker を開始 ¢ 分散ファイルシステムで解決! l GFS (Google File System): Google の MapReduce l HDFS (Hadoop Distributed File System): Hadoop
  21. GFS: 仮定 ¢ 高価な(特注の)ハードウェアではなく、安価な(コモデ ィティ化された)ハードウェア l スケール「アップ」ではなくスケール「アウト」 ¢ ハードウェア故障の率が高い l

    安価なコモディティのハードウェアは常に壊れる ¢ そこそこの数の巨大なファイル l 数 GB のファイルは普通 ¢ ファイルは1回書き込むだけで、大部分は追記 l 同時に書き込み・追記されることも ¢ ランダムアクセスではなく大規模なストリーム処理 l レイテンシは低いがスループットは高い GFS slides adapted from material by (Ghemawat et al., SOSP 2003)
  22. GFS: デザインのポリシー ¢ ファイルをチャンクとして保存 l 固定長 (64MB) ¢ 複製することにより信頼性の確保 l

    各チャンクは3台以上の chunkserver をまたいで複製される ¢ アクセス制御には1つの master を置き、メタデータを保 l 単純な集中管理 ¢ データのキャッシュはしない l 巨大なデータ集合をストリーム処理で読むなら、キャッシュして もあまり意味がない ¢ API を単純化 l 問題のいくつかはクライアントに丸投げ(例: データのレイアウト ) HDFS = GFS クローン(基本アイデアは同じ)
  23. GFS から HDFS へ ¢ 用語の違い: l GFS master =

    Hadoop namenode l GFS chunkserver = Hadoop datanode ¢ 機能の違い: l HDFS におけるファイルの追記は比較的新しくサポートされた機 能 l HDFS の性能は遅い(ことが多い) 以降のスライドでは Hadoop の用語を使用
  24. Adapted from (Ghemawat et al., SOSP 2003) (file name, block

    id) (block id, block location) instructions to datanode datanode state (block id, byte range) block data HDFS namenode HDFS datanode Linux ファイルシステ ム … HDFS datanode Linux ファイルシステ ム … ファイル名前空間 /foo/bar block 3df2 アプリケーション HDFS クライアン ト HDFS のアーキテクチャ
  25. Namenode の役割 ¢ ファイルシステムの名前空間を管理 l ファイル/ディレクトリ構造、メタデータ、ファイルからブロック への対応表、アクセス権限などを保持 ¢ ファイル操作を管理 l

    クライアントが datanode を介して読み書きするよう指示 l namenode を通じたデータの移動はない ¢ 全体の整合性を管理 l datanode と定期的に通信 l ブロックの再複製と再バランシング l ガベージコレクション
  26. HDFS の全体像 datanode デーモン Linux ファイルシステ ム … tasktracker slave

    ノード datanode デーモン Linux ファイルシステ ム … tasktracker slave ノード datanode デーモン Linux ファイルシステ ム … tasktracker slave ノード namenode namenode デーモン job submission node jobtracker
  27. MapReduce の復習 ¢ プログラマは2つの関数を指定する。 map (k, v) → <k’, v’>*

    reduce (k’, v’) → <k’, v’>* l 同じキーを持つ値は全て同じ reducer に送られる ¢ 以下も指定することがある。 partition (k’, 分割数) → k’ のパーティション l キーのハッシュが用いられることが多い e.g., hash(k’) mod n l キーの空間を並列 reduce 操作のために分割する combine (k’, v’) → <k’, v’>* l map フェーズのあとにインメモリで実行される mini-reducer l reduce のネットワーク通信の最適化に使われる ¢ 処理フレームワークが残り全部やってくれる。
  28. combine combine combine combine b a 1 2 c 9

    a c 5 2 b c 7 8 partition partition partition partition map map map map k1 k2 k3 k4 k5 k6 v1 v2 v3 v4 v5 v6 b a 1 2 c c 3 6 a c 5 2 b c 7 8 シャッフルとソート: キーによる値の集約 reduce reduce reduce a 1 5 b 2 7 c 2 9 8 r1 s1 r2 s2 r3 s3 c 2 3 6 8
  29. 「残り全部」 ¢ 処理フレームワークが残り全部やってくれる↓ l スケジューリング: worker に map と reduce

    タスクを割り当てる l データの分配: プロセスをデータに移動する l 処理の同期: 中間結果を集め、シャッフルし、ソートする l エラー処理: worker の失敗を検出し、リスタートする ¢ データと実行フローに関する制御は限られている l アルゴリズムは map, reduce, combine, partition で記述されなけれ ばならない ¢ まだ説明していないこと: l どこで mapper と reducer が実行されるか l いつ mapper あるいは reducer が開始・終了するか l 特定の mapper が処理する入力はどれか l 特定の reducer が処理する中間結果はどれか
  30. 同期するための MapReduce の仕組み ¢ 賢く構築されたデータ構造 l 部分的な結果をまとめる ¢ 中間キーの順番をソートする l

    reducer がキーを処理する順番をコントロールする ¢ partitioner l どの reducer がどのキーを処理するかコントロールする ¢ mapper と reducer に状態を保存する l 複数のキーと値をまたいだ依存関係を捉える
  31. 状態を保存する Mapper オブジェクト 設定 map 終了処理 状態 1タスク1オブジェクト Reducer オブジェクト

    設定 reduce 終了処理 状態 キー=バリューの入力ペア に対し1回実行される 中間キー に対し1回実行される API 初期化フック API クリーンアップフック
  32. スケーラブルな Hadoop アルゴリズム: 課題 ¢ オブジェクトを極力作らない l そもそも高コストな操作 l ガベージコレクションされる

    ¢ バッファリングしない l ヒープサイズが限られている l 小さなデータに対しては役に立つが、スケールしない!
  33. ローカル集約の重要性 ¢ スケールするシステムの理想的な特徴: l データが2倍になれば処理時間が2倍 l リソースが2倍になれば処理時間は半分 ¢ どうしてそんなシステムが作れないの? l

    同期するために通信が必要 l 通信によって性能がガタ落ち ¢ つまり、通信を避ける。 l ローカルに集約することで中間データを reduce する l combiner が役に立つ
  34. シャッフルとソート Mapper Reducer 他の mapper 他の reducer リングバッフ ァ (インメモリ

    ) データ (オンディスク) マージされたデータ (オンディスク) 中間ファイル (オンディスク) Combiner Combiner
  35. ローカル集約のデザインパターン ¢ mapper の中で combine する l 複数の map 呼び出しをまたいで状態を保存することで、combiner

    の機能を mapper に埋め込む ¢ 利点 l 速度 l combiner より速い理由? ¢ 欠点 l 明示的にメモリ管理をしなければならない l 処理の順番に依存するバグを埋め込んでしまうことも
  36. Combiner の設計 ¢ combiner と reducer は同じメソッドシグネチャ(メソッ ド名、引数の数・順序・型、返り値の型、…)を共有 l reducer

    が combiner の役割を果たすこともある ¢ combiner は最適化のために用いられるオプション l アルゴリズムの正しさに影響を与えてはいけない l 0回、1回、複数回走らせてもよい ¢ 例: 同じキーに関連付けられた全ての整数の平均を求める
  37. アルゴリズムデザイン: 実例 ¢ テキスト集合の単語共起行列 l M = N x N

    行列(N = 語彙数) l Mij : i と j がある文脈で共起した数 (具体的にはたとえば文脈=文) ¢ 何に使うの? l 意味的な距離を測るために分布類似度を用いる l 意味的な距離は多くの言語処理タスクで役に立つ
  38. MapReduce: 巨大な数え上げ問題 ¢ テキスト集合の単語共起行列 = 巨大数え上げ問題のひとつ l 巨大な事象空間(語彙の数) l たくさんの観測(数え上げそのもの)

    l ゴール: 調べたい事象の統計量を保持する ¢ 基本的なアプローチ l Mapper が部分頻度を生成 l Reducer が部分頻度を集約 効率的に部分頻度を集約するためにはどのようにすれば?
  39. とりあえず: 「ペア」 ¢ 各 mapper は文を引数に取る。 l 共起する単語ペアを全て生成する l 全ペアに対し、emit

    (a, b) → count ¢ reducer はペアにひも付けられた頻度を合計する ¢ combiner を使おう!
  40. 「ペア」分析 ¢ 利点 l 実装が簡単 l 理解しやすい ¢ 欠点 l

    たくさんのペアをソート・シャッフルしなければならない(上限 値?) l combiner を使う機会があまりない
  41. 「ペア」から「ストライプ」へ ¢ アイデア: ペアを連想配列にグループ化する ¢ 各 mapper は文を引数に取る。 l 共起する単語ペアを全て生成する

    l 各単語に対し、emit a → { b: countb , c: countc , d: countd … } ¢ reducer は連想配列の要素ごとの合計を計算 (a, b) → 1 (a, c) → 2 (a, d) → 5 (a, e) → 3 (a, f) → 2 a → { b: 1, c: 2, d: 5, e: 3, f: 2 } a → { b: 1, d: 5, e: 3 } a → { b: 1, c: 2, d: 2, f: 2 } a → { b: 2, c: 2, d: 7, e: 3, f: 2 } + ポイント: 賢く構築されたデータ構造 と部分的な結果を組み合わせる
  42. 「ストライプ」分析 ¢ 利点 l キー=バリューペアのソートとシャッフルの回数を激減 l combiner を効果的に使える ¢ 欠点

    l 実装が難しい l 裏で用いられるオブジェクトがもっと重たくなる l 事象空間のサイズという観点で、原理的な制約がある
  43. クラスタサイズ: 38 コア データ: English Gigaword Corpus (v3) の Associated

    Press Worldstream (APW) から、 227 万文書(1.8 GB compressed, 5.7 GB uncompressed) 単語共起行列計算の「ペア」と「ストライプ」の比
  44. f(B|A) の計算: 「ストライプ」を使えば簡単 ! ¢ 簡単! l 1パス目で (a, *)

    を計算 l 2バス目で直接 f(B|A) を計算 a → {b1 :3, b2 :12, b3 :7, b4 :1, … }
  45. f(B|A) の計算: 「ペア」でも可能 ¢ このようにするためには: l mapper で各 bn のたびに余分に

    (a, *) を emit l 全ての a を同じ reducer に送る(partitioner を使う) l (a, *) が最初に来るように(ソートの順番を定義する) l 異なるキー=バリューペアをまたいで reducer 内で状態を保持 することが必要 (a, b1 ) → 3 (a, b2 ) → 12 (a, b3 ) → 7 (a, b4 ) → 1 … (a, *) → 32 (a, b1 ) → 3 / 32 (a, b2 ) → 12 / 32 (a, b3 ) → 7 / 32 (a, b4 ) → 1 / 32 … Reduce がメモリ上にこの値を保持
  46. 順番を逆転させて考える ¢ 共通するデザインパターン l 相対頻度の計算には周辺化された頻度が必要 l しかし周辺化の計算には全ての頻度を知らなければならない l バッファリングしたくない l

    コツ: 周辺化された頻度が同時頻度の前に reducer に来るようにす る ¢ 最適化 l 周辺化された頻度を集約するために、インメモリで combine する パターンを適用する l combiner を使うべき?
  47. 同期: ペア対ストライプ ¢ アプローチ 1: 同期を順序問題に落とし込む l キーをソートして正しい計算順序にしておく l キー空間を分割して各

    reducer が適切な結果の部分集合を受け取 るようにしておく l 計算するために複数のキー=バリューペアをまたいで reducer に 状態を保持する l 「ペア」アプローチで見た ¢ アプローチ 2: 部分的な結果を統合するデータ構造を構築 l 各 reducer が計算を完成させるために必要な全データを受け取る l 「ストライプ」アプローチで見た
  48. 抽象的な情報検索のアーキテクチャ 文書 クエリ (検索語) 適合文書 表現(特徴量抽出) 関数 表現(特徴量抽出) 関数 クエリ(特徴量)表現

    文書(特徴量)表現 比較関数 インデックス (索引) オフライン オンライン 文書獲得 (例: ウェブクローリング)
  49. MapReduce したい? ¢ インデクシング問題 l スケーラビリティが重要 l 比較的速くないといけないが、リアルタイルである必要はない l 本質的にバッチ操作

    l 差分をインクリメンタルに更新するのは重要かもしれないし、重 要じゃないかもしれない l ウェブに関しては、クローリング自体が大きなテーマ ¢ 検索問題 l 秒以下の応答時間でなければならない l ウェブに関しては、いくつかの結果さえあればよい MapReduce でバッチリ! あまり嬉しくない。。。
  50. 2 1 1 2 1 1 1 1 1 1

    1 転置インデックス(ストップワードは除去) 2 1 2 1 1 1 1 2 3 1 1 1 4 1 1 1 1 1 1 2 1 tf df blue cat egg fish green ham hat one 1 1 1 1 1 1 2 1 blue cat egg fish green ham hat one 1 1 red 1 1 two 1 red 1 two one fish, two fish Doc 1 red fish, blue fish Doc 2 cat in the hat Doc 3 green eggs and ham Doc 4 3 4 1 4 4 3 2 1 2 2 1
  51. [2,4] [3] [2,4] [2] [1] [1] [3] [2] [1] [1]

    [3] 2 1 1 2 1 1 1 1 1 1 1 転置インデックス: 位置情報つき 2 1 2 1 1 1 1 2 3 1 1 1 4 1 1 1 1 1 1 2 1 tf df blue cat egg fish green ham hat one 1 1 1 1 1 1 2 1 blue cat egg fish green ham hat one 1 1 red 1 1 two 1 red 1 two one fish, two fish Doc 1 red fish, blue fish Doc 2 cat in the hat Doc 3 green eggs and ham Doc 4 3 4 1 4 4 3 2 1 2 2 1
  52. MapReduce によるインデックス作成 ¢ 全文書で map する l term をキーとして、(文書番号, 単語頻度=tf)

    を値として emit l 必要な情報(例: 単語の位置)があれば emit ¢ ソートとシャッフル: 単語で位置(ポスティング)をグル ープ化 ¢ reduce l ポスティングを集めてソート(例: 文書番号あるいは tf) l ポスティングをディスクに書く ¢ MapReduce が重たい処理を全部面倒見てくれる!
  53. 1 1 2 1 1 2 2 1 1 1

    1 1 1 1 1 2 MapReduce による転置インデックスの作成 1 one 1 two 1 fish one fish, two fish Doc 1 2 red 2 blue 2 fish red fish, blue fish Doc 2 3 cat 3 hat cat in the hat Doc 3 1 fish 2 1 one 1 two 2 red 3 cat 2 blue 3 hat シャッフルとソート: キーで値を集約 Map Reduce
  54. MapReduce のホットトピック ¢ 他のプログラミングモデルの探求 l バッチ vs. リアルタイムデータ処理 ¢ さまざまな実装(例:

    Microsoft DryadLINQ) ¢ MapReduce 自身がツールでもある ¢ Hadoop 生態系の拡大 ¢ MapReduce と分散データベースの進化
  55. 高水準言語の要求 ¢ Hadoop は大規模データ処理には適している l ただ、なにをするにも Java プログラムを書かないといけないの は冗長だし、遅い。。。 l

    アナリストは Java を書きたくない(書けないことも) ¢ 解決策: 高水準のデータ処理用の言語を開発する l Hive: HQL は SQL のような言語 l Pig: Pig Latin がデータフロー言語
  56. Hive と Pig ¢ Hive: Hadoop のデータウェアハウス構築環境 l クエリ言語は SQL

    の一種の HQL l テープルはフラットファイルの形で HDFS に記憶 l Facebook が開発し、現在はオープンソース ¢ Pig: 大規模データ処理システム l データフロー言語の Pig Latin でスクリプトを書く l Yahoo! が開発し、現在はオープンソース l Yahoo! 内部のジョブのだいたい 1/3 は Pig ¢ 共通するアイデア: l 大規模データ処理を行うための高水準言語を提供する l 高水準言語は Hadoop ジョブに「コンパイル」される