43
1 Hadoop 本本本本 6 本 MapReduce 本本本 本本 本本

Hadoop輪読会第6章

Embed Size (px)

Citation preview

Page 1: Hadoop輪読会第6章

1

Hadoop 本輪読会6 章 MapReduce の動作

   桑野 章弘

Page 2: Hadoop輪読会第6章

2

自己紹介桑野 章弘 (id:akuwano, twitter:kuwa_tw)渋谷で働く IT会社インフラエンジニア

Page 3: Hadoop輪読会第6章

3

6 章  MapReduce の動作

Page 4: Hadoop輪読会第6章

4

はじめにHadoop の MapReduce がどのように動作するのか ?

Page 5: Hadoop輪読会第6章

5

6.1 MapReduce ジョブの実行の内幕MapReduce の実行

やることは、 JobClient.runJob(conf) だけ!だけどその裏では様々なプロセスが動いている

P169

Page 6: Hadoop輪読会第6章

6

6.1 MapReduce ジョブの実行の内幕裏で動いている登場人物

jobClientjobtracker

ジョブの実行管理。 JobTracker をメインクラスに持つ Java アプリケーション

tasktrackerジョブを分割して出来たタスク実行。 TaskTracker をメインクラスに持つ Java アプリケーション

分散 FS ( HDFS など)各プロセス間でのジョブのファイルを共有する為に使用する

どのように実行されるか、ステップ毎に説明していきます。

Page 7: Hadoop輪読会第6章

7

MapReduce ジョブの実行遷移図

MapReduceプログラム JobClient JobTracker

TaskTracker

Mapタスクあるいは

Reduleタスク

共有ファイルシステム

( HDFS等)

1. ジョブの実行 2. 新規ジョブの取得

4. ジョブの投入

3. ジョブのリソースのコピー

5. ジョブの初期化

6. 入力スピリットの取得

8. ジョブのリソースの取得

9. 起動

10. 実行

7. ハートビート(タスクの返却)

クライアント JVM

クライアントノード Jobtrackerノード

tasktrackerノード

子 JVM

Page 8: Hadoop輪読会第6章

8

6.1.1  ジョブの投入 [ ステップ1 ]JobClient で runJob() メソッドの実行

JobClient のインスタンス生成し、 submitJob() メソッド呼び出し

その後 runJob は定期的(毎秒)にジョブの進行状況を監視

Page 9: Hadoop輪読会第6章

9

6.1.1  ジョブの投入 [ ステップ 2 ~ 4]submitJob() メソッド

JobTracker で getNewJobId() メソッドに新しいジョブ ID の要求

ジョブの出力条件が正しいのかチェック入力スプリットの計算ジョブ実行に必要なリソースを共有ファイルシステムへコピー

するJobTracker の submitJob() メソッドを呼び出す

Page 10: Hadoop輪読会第6章

10

6.1.2  ジョブの初期化 [ ステップ 5 ~ 6]JobTracker の submitJob() メソッド

submitJob() を呼び出したジョブをキューに保存ジョブスケジューラは定期的にキューからジョブを取り出し初

期化しオブジェクトを作成共有ファイルシステムから入力スプリットを取得取得したスプリットごとに map タスクを作成Reduce タスクも作成される。

作成数は mapred.reduce.tasks プロパティで決定される

Page 11: Hadoop輪読会第6章

11

6.1.3  タスクの割り当て [ ステップ 7]tasktraker 郡からのハートビート

定期的な死活監視とメッセージの送出タスク実行可否の通知タスクが実行可能であればタスクを割り振る複数ジョブの jobtracker でのスケジューリング

スケジューリングアルゴリズム( 6.3 で後述)tasktracker のスロット( tasktracker のリソースによる)

Page 12: Hadoop輪読会第6章

12

6.1.4  タスクの実行tasktracker によるタスクの実行

ジョブに必要なリソースをローカルへコピーローカル作業用ディレクトリに JAR を展開JVM 起動し、タスク実行開始子プロセス( JVM )と親タスク (tasktracker) は常にタスク

の進行状況のやりとりを行う

Page 13: Hadoop輪読会第6章

13

ストリーミングとパイプmap タスク、または reduce タスクから

ユーザが実行可能な実行ファイルを起動して処理させる為の仕組み

ストリーミングは標準入出力経由でやりとりするパイプはソケット通信でやりとりする

Page 14: Hadoop輪読会第6章

14

ストリーミングとパイプストリーミング

TaskTracker

Mapタスクあるいは

Reduleタスク

9. 起動

実行

tasktrackerノード

子 JVM

ストリーミングタスク

起動 出力キー/ 値

入力キー/ 値

標準入力 標準出力

TaskTracker

Mapタスクあるいは

Reduleタスク

9. 起動

実行

tasktrackerノード

子 JVM

C++mapあるいは

Reduceタスク

ソケット

起動 出力キー/ 値

パイプ

Page 15: Hadoop輪読会第6章

15

6.1.5 進行状況とステータスの更新ジョブ進行状況のクライアントへの通知

タスクは tasktracker へと定期的( 3 秒程度)に情報を通知する

tasktracker は jobtracker へのハートビートにそのtasktracker の全タスクの状態を入れて送る

jobtracker は tasktracker 郡から送られた統計情報を集約jobClient は jobtracker に毎秒問い合わせを行う

Page 16: Hadoop輪読会第6章

16

6.1.5 進行状況とステータスの更新

MapReduceプログラム JobClient JobTracker

TaskTracker

Mapタスクあるいは

Reduleタスク

共有ファイルシステム

( HDFS等)

getJob getJobStatus

9. 起動

ハートビート

クライアント JVM

クライアントノード Jobtrackerノード

tasktrackerノード

子 JVM

進行状況あるいはカウンターの更新statusUpdate

Page 17: Hadoop輪読会第6章

17

6.1.6  ジョブの完了ジョブの最後のタスクが完了した

ジョブのステータスを successfulrunJob() メソッドから戻る

Page 18: Hadoop輪読会第6章

18

6.2  障害Hadoop の障害検知

タスクtasktrackerjobtracker

P176

Page 19: Hadoop輪読会第6章

19

6.2.1  タスクの障害タスクのコードがエラーを投げた場合

tasktracker に異常終了を通知し、スロットを空けるストリーミングの場合もタスク失敗となる

この場合の振る舞いは stream.non.zero.exit.is.failure プロパティで管理

Page 20: Hadoop輪読会第6章

20

6.2.1  タスクの障害タスク実行中の JVM が突然死した場合

tasktracker が JVM プロセス終了を検知タスク失敗

Page 21: Hadoop輪読会第6章

21

6.2.1  タスクの障害タスク実行中の JVM がハングした場合

tasktracker が一定期間実行状況の通知を受けない場合タスク失敗+ JVM プロセスを killただしストリーミングで実行中のプロセスは残る

Page 22: Hadoop輪読会第6章

22

6.2.1  タスクの障害失敗したタスクの再スケジュール

前回失敗した tasktracker にはタスクを割り振らない失敗回数が一定を越えたタスクは再スケジュール不可

失敗してもタスク再スケジュール可にもできるタスク試行は失敗回数には入らない

Page 23: Hadoop輪読会第6章

23

6.2.2 tasktracker の障害tasktracker のハートビートが途絶えた場合

jobtraker は該当 tasktracker をブラックリストへ登録する結果タスクを他 tasktracker へと振り分けタスク失敗率が高い場合にもブラックリストに入る

Page 24: Hadoop輪読会第6章

24

6.2.3 jobtracker の障害現在 jobtracker は SPOF将来的には ZooKeeper で冗長化するかもしれない

Page 25: Hadoop輪読会第6章

25

6.3  ジョブのスケジューリングデフォルトでは FIFO スケジューラ優先度付けは可能だがプリエンプション無プラガブルになっているので、複数のスケジューラが存在する

キャパシティスケジューラフェアスケジューラなど

P178

Page 26: Hadoop輪読会第6章

26

6.3  ジョブのスケジューリングフェアスケジューラ

各ジョブに対して公平にリソースが割り振るジョブ優先度プリエンプション有default では有効ではない

P178

Page 27: Hadoop輪読会第6章

27

6.4  シャッフルとソートMapReduce の肝の処理

mapreduce では reduce側への入力はキーでソートされている前提

シャッフルとは、レコードのソートを行い map の出力を reduce へと入力する処理

P179

Page 28: Hadoop輪読会第6章

28

6.4  シャッフルとソート

mapタスク reduceタスク

map reduce

入力スプリット

メモリ内バッファ

コピーフェーズ

ディスク上でのマージ

パーティション

取得

他の reduce へ 他の map から

メモリとディスク上にデータが混在

マージ

出力

ソートフェーズ reduce フェーズ

Page 29: Hadoop輪読会第6章

29

6.4.1  シャッフルとソート [map側 ]出力は単純にディスクに書き出されない循環メモリバッファ

出力が最初に読み込まれる

スピルファイルバッファがある程度溜まった段階でファイルへと書き出す、複数ファイル

単一ファイルへのマージスピルファイルの出力を単一ファイルへマージする

Page 30: Hadoop輪読会第6章

30

6.4.2  シャッフルとソート [reduce側 ]map側の出力を集めて reduce 処理を行う

コピーフェーズ各 map から並列で出力をコピー

ソートフェーズ各 map の出力をソート順を保ちつつマージ

Reduce フェーズマージした入力を reduce 処理へ渡す

Page 31: Hadoop輪読会第6章

31

6.4.3 設定のチューニングチューニング項目

可能な限りのメモリをシャッフルに当てるreduce の中間ファイルをメモリ内に保持バッファサイズの拡張

Page 32: Hadoop輪読会第6章

32

6.4.3 設定のチューニング [map]

プロパティ名

型 デフォルト値

説明

io.sort.mb int 100 map 出力のソートに使われるメモリバッファの量(単位はメガバイト)

io.soft.record.percent fload 0.05 io.sort.mb の中で、 map の出力のレコード境界を保存するために予約される比率。残りの領域は map の出力レコードのために使われる。

io.sort.spill.percent int 10 map 出力のメモリバッファと、レコード境界インデックスの両方に適用される。ディスクにスピルを書き出し始めるかどうかの判定をするための利用率の閾値。

min.num.spills.for.bombine int 3 combiner を実行する( combiner が指定されている場合)のに必要な最小限のスピルファイル数。

mapred.map.outupt.compression.codec

クラス名 org.apache.hadoop.io.compress.DefaultCodec

map の出力に使われる圧縮コーデック。

tasktracker.http.threads int 40 map の出力を reducer に提供するために使われる、 tasktracker ごとのワーカースレッド数。これはクラスタ単位の設定であり、ジョブ単位には設定することは出来ない。

Page 33: Hadoop輪読会第6章

33

6.4.3 設定のチューニング [reduce]

プロパティ名

型 デフォルト値

説明

maprd.reduce.parallel.copies int 5 map の出力を reduce にコピーするために使われるスレッド数。

mapred.reduce.copy.backoff int 300 1 つの map の出力を reduce が取得する際に、失敗したと判定するまでの時間(秒)。 reducer は、この時間内であれば、何回取得に失敗しても繰り返し転送をしてみることができる(その際には、指数関数的に間隔をあけていく)

io.sort.factor int 10 このファイルをソートする際に同時にマージされる最大のストリーム数。このプロパティは map でも使われる。

mapred.job.shuffle.input.burffer.percent

float 0.70 総ヒープサイズに対する、シャッフルのコピーフェーズ間の map の出力バッファへの割り当て比率

mapred.job.shuffle.merge.percent float 0.66 map の出力バッファ( mapred.job.shuffle.input.buffer.percent で指定)に対する使用率の閾値。この値を超えると出力のディスクへのスピルへの書き出しが開始される。

mapred.inmem.merge.threshold int 1000 map の出力をマージし、スピルとしてディスクに書き出すプロセスが開始される、 map 出力数の閾値。 0以下の値を指定した場合、閾値がない物と見なされ、スピルの動作はmapred.job.shuffle.merge.percent でのみ管理される。

mapred.job.reduce.input.buffer.percent

float 0.0 reduce の過程で、 map の出力を保持するために使われるバッファの、総ヒープサイズに対する比率。 reduce フェーズが開始されるためには、メモリ内にある map の出力サイズがこのサイズよりも大きくなければならない。デフォルトでは、 reduce の処理が出来る限りのメモリを使えるようにするため、すべての map の出力は reduce が開始される前にディスク上にマージされている。しかし reducer がそれほどメモリを使わない場合、この値を増やすことでディスクとのやりとりを最小限に抑えられることがある。

Page 34: Hadoop輪読会第6章

34

6.5  タスクの実行MapReduce ユーザがタスク実行時に制御できる事

投機的実行タスク JVM の再使用不良レコードのスキップタスクの実行環境

P184

Page 35: Hadoop輪読会第6章

35

6.5.1  投機的実行タスクのバックアップ実行低速なタスクが存在する場合にそのタスクを複製、実行先に終了したタスクの結果を使用し、終わらなかったタスクは

kill最適化の為の処理であり、ジョブ実行の信頼性は変わらない投機的実行の為にリソースを食い過ぎる様だと逆効果

Page 36: Hadoop輪読会第6章

36

6.5.2  タスク JVM の再利用タスクを毎回初期化しないで再利用する短い時間に大量に生成されるタスクの場合に有効長時間実行する事で HotSpotJVM の最適化の恩恵も受けられ

るその代わり同じ JVM をシリアルに使用するため、並列度は下

がる

Page 37: Hadoop輪読会第6章

37

6.5.3  不良レコードのスキップ大量データには不良データは存在する事がある

不良レコードは例外処理を行うmapper, reducer 内の例外処理スキッピングモード

Page 38: Hadoop輪読会第6章

38

6.5.4  タスクの実行環境現在実行している mapper, reducer の情報を知る

Page 39: Hadoop輪読会第6章

39

6.5.4  タスクの実行環境

プロパティ名

型 説明 例

mapred.job.id String ジョブ ID (フォーマットの説明は「 5.5.2  ジョブの起動」のコラム「ジョブ、タスク、タスク試行 ID」を参照)

job_200811201130_0004

mapred.tip.id String タスク ID task_200811201130_0004_m_000003

mapred.task.id String タスク試行 ID (タスク ID とは別) attempt_200811201130_0004_m_000003_0

mapred.task.partition int ジョブ内でのタスク ID 3

mapred.task.is.map boolean このタスクが map タスクかどうか true

Page 40: Hadoop輪読会第6章

40

ストリーミングの環境変数ストリーミングのプログラムに環境変数を渡す事が可能

ただし、アルファベットでも、数字でもない文字はアンダースコアに置き換わる

mapred.job.id -> os.environ{“mapred_job_id”}

Page 41: Hadoop輪読会第6章

41

タスクの副作用ファイル通常のキー /バリュー以外の複雑な出力結果がほしい場合タスク毎に別々に作業用ディレクトリを作成する

投機的実行等でも影響が無い

Page 42: Hadoop輪読会第6章

42

まとめHadoop の MapReduce がどのように動作するのか

各プロセス間の連携(メソッド呼び出しや、ハートビート)MapReduce の障害時の動作

各タスク、 tasktracker の障害は冗長取れているjobtracker は SPOF なので注意

各種設定とチューニングスケジューラは適切な物を選択( FIFO は殆どの場合悪手)シャッフルの最適化が重要

Page 43: Hadoop輪読会第6章

43

ご清聴ありがとうございました。