レポート縁あってサイバーエージェント内で水曜隔週で行われているHadoop本輪読会なるマニアックなイベントに参加しています。ちなみに第1回で1章2章をやったのだけれど、その日は仕事の打ち合わせが長引いてしまいほとんど終わりかけの参加であったというわけで割と何も覚えていません。第2回はそういった第1回での自分と同様で、仕事の都合で来られない人も何人かいたようで。FileSystem)Hadoopのパワーを生かすための分散ファイルシステムのお話ですね。大きなファイルストリーミング型のデータアクセスコモディティハードウェア基本的にたくさんのマシンで構成したクラスタに大量のデータをどんどん蓄積していくイメージ。ブロックサイズがデフォルト64MBと非常に大きく、実際にはこれより大きいサイズで運用されるらしい。高スループットのデータアクセスが可能な仕組みで、データをクラスタ内のマシンに分散して保存することによりスケーラビリティと耐障害性に優れている。低レイテンシが求められるデータアクセス大量の小さなファイル複数のライターからの書き込みや、任意のファイルの修正これら不得意な使い方は基本的にするなということなんだと思う。低レイテンシはダメなのに高スループットってどういうこと?って質問が出てきてたけど、今読んだら「データセット全体を読むのに要する時間は、最初のレコードを読み出すレイテンシよりも重要」って書いてある。トータルの処理時間を縮めるために初動のレスポンスは重視していないということのようだ。クラスタの構成マスター/ワーカーパターンというやつだ。知らないがそういうパターンだ。ネームノード(マスター)はデータのある場所を知っていて、実際のデータはデータノード(ワーカー)にある。クライアントから問い合わせを受けたネームノードは、その対象データを持っているデータノードをご案内する。(通常はレプリケーションされているので複数ご案内する)クライアントはデータノードから直接データを持ってくると言う具合。データはファイル単位ではなくブロック単位で各ノードに分散される。これによってひとつのファイルが複数のノードにまたがって構成される=ファイルサイズの制限がディスク容量に縛られなくなるので、ペタバイトに及ぶファイルも問題なくファイルシステム内に保存できる。ブロック単位での保存はレプリケーションとの相性もいいということだ。ちなみにHDFSのブロックサイズ64MBとか128MBだが、各ノードのファイルシステムのブロックサイズはまた別なので、1MBのファイルをHDFS上に保存してもディスク容量は1MBしか食わないとかそんな話もある。必要なディスク容量の見積もりとかどうするんだろう。いう質問とっさに出てきたらいいのに。ネームノードは特に冗長化されていない。データだけローカルディスクとNFSマウントしたディスクに書いて二重化する。二重化してなくてネームノードのデータが破壊されたらHDFS内のファイル全部死亡。フェイルオーバーの仕組みは用意されていないようだ。←こういうのも質問しとけよってかんじですね。それはHadoopが責任持つところとはまた別の話ということなのかな。リアルタイム性の高い処理を行っているわけでもなさそうだし。セカンダリネームノードと言うものもあるが、これは名前負け。ネームノードが落ちたときに代わりにマスタに昇格するような名前だけど、実際の仕事は定期的に名前空間のイメージと編集ログをマージさせること。一応マスタがクラッシュした際にセカンダリネームノードが持っている情報をもとにある程度は復元できるが、最後のマージとクラッシュまでの間の情報は永久に失われる。HDFSじゃなくてもHadoopは動くHadoopファイルシステムの実装はHDFS以外にもいろいろある。S3の上で動くものも。大規模なデータ処理を行う場合はHDFSやKVSのようなデータローカリティの最適化機能を持っている分散ファイルシステムを使うべき。「データローカリティの最適化機能」ってどういうことなんでしょう。Hadoopのファイルシステムとやりとりするインタフェース実装いろいろもっとも一般的なのはJavaのAPI。ファイルの読み書き、ディレクトリの作成、ファイル情報の取得、ファイル一覧の取得と絞り込み、データやファイルの削除といった操作が可能。コマンドラインのインタフェースもある。(中身Java?)APIだとCとかWebDAVとかFUSEとか。Thriftをサービスとして動かしておくとプロキシとして動作してThriftのAPIを使っていろんな言語からHadoopを操作できる。データ読み書きの詳細APIが良きに計らってくれるのでクライアントは中の仕組みが全然分からなくても透過的に利用できる。なくてHadoopを利用する上では一応知っておいた方がいいでしょう。説明はめんどいので略。一応がんばってみよう。読むときはクライアント(のAPI)がネームノードにどのデータノードにデータがあるか聞きに行って、それを聞いたらあとはデータノードから勝手に読むかんじ。ネームノードは場所を教えるだけ。データを中継したりはしないのでここがボトルネックになることはない。障害に備えて同じブロックを持っている複数のデータノード教える。一応ネットワークの近い順に教える。クライアントは障害を見つけたら一応ネームノードに教えるみたいだ。書くときはクライアントがネームノードに書くぞーって言うと、ネームノードで既存のファイルがないかとかパーミッションとかをチェックする。したらネームノードはデータを書くデータノードをクライアントに返して、クライアントはデータ書き終わったらネームノードに書いたぞーって教える。レプリケーションするので書き込むデータノードは複数。書こうとしたデータノードに障害があった場合、一定数のノード(デフォルトは1以上)に書き込みができていれば成功と見なす。書き込めなかったノードにはあとで非同期でレプリケーションが行われる。flashとかsyncとかの使いどころがイマイチわからなかった。syncを呼ぶことで一貫性を保証できるようなので、書き込みつつ適当なタイミングで呼ぶべきってことみたいだけど。以上、間違ってたらすまんてかんじだ。並列動作で効率よくコピー。実はMapReduce実装。Hadoopのバージョンがまったく同じでないと使えない。マイナーバージョンがひとつ違うだけで使えないそうだ。Hadoopアーカイブ小さなファイルをtarのごとく固めて効率よく扱う仕組み。ネームノードのメモリ消費を押さえることができる。アーカイブ内へのファイル追加や削除をしたい場合はアーカイブ作り直し。アーカイブ作るときに元のファイルと同量のディスク容量を食う。うまくmapに渡せない。