「Hadoop 徹底入門 第2版」を有志で読み進めているので、そのメモを貼ります。
今回は第1部、4章〜5章、コア技術である HDFS, MapReduce の説明です。
[toc]
Chapter 4 "HDFS”
HDFS の特徴
- 巨大なデータを汎用サーバーのみで扱える
- 容量にスケーラビリティがある
- シーケンシャルアクセスで高いスループットを出せる
- “Write Once, Read Many” 方式
- データの一部のみ更新することはできない
- ランダムアクセスは想定していない
- ブロックサイズを大きくすることで(デフォルトで64MB)、一度にまとめて大量データを扱える
- 上記性質から、特に大量のログファイルなどの格納に向いている
- “Write Once, Read Many” 方式
- スレーブノードの一部が故障しても、データの損失を回避できる
HDFS の仕組み
- マスターサーバ(NameNode)、スレーブノード(DataNode)のマスタースレーブ構成
- DataNode は、ファイルのデータブロックを管理する
- NameNode は HDFS の全体的な管理を行う。また、NameNode 上で扱うファイルシステムのメタデータのメンテナンスを担うのが SecondaryNameNode である
DataNode について(4.2.2節)
- HDFS は Java で実装されたミドルウェアであり、OS よりも上位のレイヤーで提供されるファイルシステム
- HDFS 上に格納したファイルの実体は、各 DataNode 上のローカルファイルシステム(ext4など)上のファイルとして存在
- HDFS 上のデータは「ブロック」と呼ばれるチャンクに分割される
NameNode について(4.2.3節)
メタデータの管理
- NameNode はデータではなく、メタデータを管理する。「どのブロックがどのファイルのどの部分であるか」
- メタデータはメモリ上で管理される
- メタデータには以下の情報が含まれる:ファイル名、親ディレクトリ、サイズ、所有者・所有グループ、属性、ブロックIDとDataNodeのペア(4.4節)
- ブロックID と DataNode のペアは、DataNode からの申告をもとに動的に構築される
- DataNode はハートビートパケットの送信タイミングで、自身が保持しているブロックを NameNode に伝える
- その他の情報は、メモリからディスクへ同期が行われる(逆に言うと、ブロック情報は永続的には保持されない)
- 下記情報を用いて、クラスタ起動時に初期化が行われる(Write-Ahead Log と同じ仕組み)
- fsimage をより最新の状態に保つ SecondaryNameNode を利用することも可能
- NameNode から定期的に fsimage と edits を受け取り、最新の fsimage を作成して NameNode へ戻す
- NameNode 以外に fsimage を保持することで、メタデータの完全消失も防ぐ
HDFS の使用状況の確認
- HDFS 全体の使用状況
- 各 DataNode における HDFS 用領域の使用状況
- 逼迫している場合には、レプリカを別 DataNode に移す
- 各ブロックのレプリカ数の管理
- 足りていなかったり余分であれば、調整(作成 or 破棄)を行う
http://192.168.33.10:50070/dfshealth.jsp
上記 URL で、NameNode から HDFS の使用状況が確認できる
クライアントからのHDFSの操作の受付
- クライアントは NameNode に読みたいファイルを問い合わせる
- NameNode は、どのブロックがどの DataNode に存在するかを応答
- クライアントは、DataNode に直接アクセスしてデータ(ブロック)を読みにいく
DataNode の死活監視
- DataNode からハートビートのパケットが一定時間受信されないと、その DataNode を故障と見なす
- ハートビートパケットは、デフォルトでは3秒ごとに送信される
HDFS のファイル読み書きの流れ
- 書き込み:図4.4(P.69)
- フロー
- クライアント -> NameNode: ファイルオープン要求
- NameNode -> クライアント: ストリーム返却(?)
- クライアント : ブロックサイズに分けたファイル(パケット)を、データ送信キューに追加
- クライアント : NameNode に、DataNode のブロック割当を要求
- NameNode -> クライアント: DataNode パイプラインを返却
- クライアント : ack 待ちキューに全パケットを保存
- クライアント -> DataNode: DataNode パイプラインの先頭 DataNode にデータを書き込む
- 先頭DataNode -> 後続DataNode: パケット伝搬。全 DataNode に書き込めたら、ack 待ちキューから該当パケットを削除
- 書き込み障害時
- ack キューに残っているパケットを、データ送信キューに戻し、障害が発生した DataNode を切り離してパイプラインを形成する
- フロー
- 読み込み:図4.5(P.71)
- 書き込み手順と同様、NameNode に問い合わせ、帰ってきた DataNode にクライアントが問い合わせに行く
- 読み込みの手間を省くため、クライアントはそれぞれの DataNode が持つ対象データのブロックを、DataNode ごとに一度に読み込む
Chapter 5 "MapReduce フレームワーク"
個々のフェーズの動き
Map 処理(図5.2)
- 入力単位は「スプリット」
- 通常は、HDFS のファイルのブロックが割り当たる
- 1レコードずつ読み込み、Map 処理を行う
- (?) キーバリュー解釈
- Map 処理後の中間ファイルは、ローカルディスクを利用する
Shuffle & Sort 処理(図5.3)
- 中間ファイルはキーごとにソートされており、Partitioner が対象の Reducer を決める
- Partitioner はデフォルトではキーのハッシュ値の剰余で定まる
- Mapper と Reducer が同じ場合はノード間のデータ通信が発生しない
- ノード数が多いと、必然的にノード間のデータ通信量が増え、処理全体の性能問題になりやすい
- Reducer に集まった中間ファイル群はマージソートされ、それぞれの Key ごとに集められる(パーティション)
Reduce 処理(図5.4)
アーキテクチャ
JobTracker の役割
MapReduce フレームワークが提供する分散処理を制御するためのマスターとして動作する Java プロセス。
単一障害点のなり得るが、HA クラスタ構成を取ることも可能(15章「可用性の向上」)。
- ジョブの管理
- Map タスクの割り当て制御
- Map 処理結果把握
- ジョブ進捗通知
- リソース管理
- 処理の割り当て
- 処理の投機的実行
- 処理再割り当て
- ブラックリスト化
- TaskTracker 死活監視
- TaskTracker 追加/切り離し
- ジョブ実行履歴の管理
TaskTracker の役割
Map 処理、Reduce 処理を実行するスレーブノード。
実行においては、「Child プロセス」と呼ばれる Java プロセスを生成する。Child プロセスが処理を終えると、TaskTracker は JobTracker に処理の完了通知を行う。
- Child プロセスの生成と処理実行
- Child プロセスの状況確認
- 処理停止の通知
- ハートビート通信
- Map 処理数と Reduce 処理数の把握
JobClient の役割
ユーザーが定義した MapReduce 処理を JobTracker に依頼するためのクライアント。
- 入力データの分割方針の決定
- ジョブの依頼
- アプリケーションの配布
- データではなく、アプリケーション自体を配布し、通信量を削減する(データローカリティ)
- 進捗状況の受信
- ジョブの管理
動作確認
JobTracker 管理画面
http://localhost:50030/jobtracker.jsp
- 上記画面で、JobTracker のステータスが確認できる
- 404 Not Found となる場合は、JobTracker を再インストールするのがよい…と Web 上では散見される(未試行)
Tips
サンプルの実行ユーザーについて
5.5.3 節の動作確認は適切なユーザーでコマンドを実行する必要がある。特に root ユーザーは HDFS 上での特権ユーザーとならないため、注意が必要である(HDFS 上の特権ユーザーは、NameNode 実行ユーザー)
[誤] [root@vagrant]# hadoop jar hadoop-examples.jar ... [正1] [sampleuser@vagrant]$ hadoop jar hadoop-examples.jar ... [正2] [hoge@vagrant]$ sudo -u sampleuser hadoop jar hadoop-examples.jar ...
また、実行権限などが付与されていない場合は、hdfs dfs -chown
コマンドなどで随時調整する。