Apache Hadoop — 1つのPodにHDFSとYARNを立てて運用する
fsimage と edits を開いて名前空間を読む
目標
NameNodeが名前空間をどのようにディスクに残すか、つまり、ある時点のスナップショットであるfsimageと、そのあとの変更の記録であるeditsを、自分で開いて見ます。セーフモードで書き込みが拒否されるのを見て、saveNamespaceで新しいfsimageを作り、オフラインイメージビューアー(oiv)とエディットログビューアー(oev)で内容を読みます。
なぜ重要なのか
NameNodeは、ファイルツリー全体をメモリに持って動きます。メモリは電源が切れると消えるので、2つをディスクに残します。fsimageは、あるトランザクション番号(txid)までの名前空間全体で、editsは、そのあとに起きた変更(ディレクトリの作成、ファイルのクローズ、名前の変更…)を1行ずつ書いた記録です。NameNodeが再び起動するときは、fsimageを読んで、そのあとのeditsを再適用します。
editsが長くなると起動が遅くなるので、定期的にfsimageにまとめる必要があります(チェックポイント)。本番では、セカンダリNameNodeやスタンバイNameNodeが行い、このラボでは、管理者コマンドsaveNamespaceで自分で行います。このコマンドがセーフモードを要求する理由は、保存している間に名前空間が変わってはいけないからです。
セーフモードは、NameNodeが読み取りだけを受け付ける状態です。起動直後にDataNodeのブロックレポートが十分に集まるまで自動的に入り、管理者が作業のために手で入れることもあります。「書き込みがすべて失敗する」という障害のよくある原因です。
fsimageをオフラインで読めれば、稼働中のNameNodeに負担をかけずに、全ファイルの一覧・サイズ・所有者を分析できます。小さなファイルがどこに集中しているかを探す作業は、たいていここから始まります。
ステップ
hdfs dfsadmin -safemode getの出力を、/root/hdp/meta/safemode.txtに保存してください。/data/finance/q1.csvをアップロードしてください(アップロード先: /user/root/meta/q1.csv)。そのあと、セーフモードに入って(-safemode enter)、/user/root/meta/in-safemodeディレクトリを作成してみて、エラー出力を、/root/hdp/meta/deny.txtに保存してください。- セーフモードのまま
hdfs dfsadmin -saveNamespaceを実行し、新しくできたfsimageのtxid(ファイル名の数字)を、/root/hdp/meta/fsimage_txid.txtに整数で記入してください。 - セーフモードを解除し(
-safemode leave)、/user/root/meta/after-saveディレクトリを作成してください。 - ステップ3のfsimageを、
hdfs oiv -p XMLで展開し、/root/hdp/meta/fsimage.xmlに書き出してください。 - 同じfsimageを、
hdfs oiv -p Delimitedで展開し、/root/hdp/meta/fsimage.tsvに書き出してください。 hdfs dfsadmin -rollEditsで今書いているedits区間を閉じ、ステップ4のディレクトリ作成が入っている閉じた区間(edits_<시작>-<끝>)を、hdfs oevで展開して、/root/hdp/meta/edits.xmlに書き出したあと、その区間名とOP_MKDIRの数を、/root/hdp/meta/ops.jsonに{"segment": "edits_…-…", "OP_MKDIR": 정수}の形式で書き込んでください(プレースホルダーは順に開始、終了、整数です)。- /root/hdp/meta/report.mdに、
## 안전 모드・## fsimage・## editsの3つの節を書いてください(最初の見出しは韓国語で「セーフモード」を意味します)。2つ目の節にステップ3のtxidを、3つ目の節にステップ7のOP_MKDIRの数を入れてください。
参考
- NameNodeのメタデータディレクトリ:
/var/lib/hadoop/name/current。fsimage_<txid>(と.md5)、edits_<시작>-<끝>(閉じた区間)、edits_inprogress_<시작>(書き込み中)、seen_txid(プレースホルダーは順に開始、終了、開始です)。 - fsimageは、最新の2つだけが残ります(
dfs.namenode.num.checkpoints.retained)。saveNamespaceを複数回実行したなら、最後のもののtxidを書いてください。 hdfs oiv -p XML -i <fsimage> -o <출력>、hdfs oiv -p Delimited -i <fsimage> -o <출력>、hdfs oev -i <edits 파일> -o <출력>(デフォルトの出力形式はXML)です(プレースホルダーは出力先とeditsファイルです)。- よくあるミス: セーフモードを解除せずに次のステップに進むこと(すべての書き込みが失敗します)、
edits_inprogress_をoevで開こうとすること(閉じた区間を開いてください)。 - 公式ドキュメント: HDFS Architecture — The Persistence of File System Metadata・Offline Image Viewer・Offline Edits Viewer・HDFS Commands — dfsadmin
セーフモードか
hdfs dfsadmin -safemode getの出力を、/root/hdp/meta/safemode.txtに保存してください。
起動直後は、ブロックレポートが集まるまでセーフモードで、そのあと自分で抜けます。今はオフになっているはずです。オンなら、NameNodeがまだ起動中か、ディスクが足りないのです。
セーフモードでは書き込みが拒否される
/data/finance/q1.csvをHDFSにアップロードしてください(アップロード先: /user/root/meta/q1.csv)。そのあと、hdfs dfsadmin -safemode enterでセーフモードに入り、hdfs dfs -mkdir /user/root/meta/in-safemodeのエラー出力を、/root/hdp/meta/deny.txtに保存してください。
セーフモードは、名前空間を凍結した状態です。読み取り(ls・cat)はできますが、名前を変えるすべての操作が拒否されます。次のステップのsaveNamespaceは、まさにこの状態を要求します。保存している間にツリーが変わってはいけないからです。
saveNamespace(手動チェックポイント)
セーフモードのままhdfs dfsadmin -saveNamespaceを実行し、/var/lib/hadoop/name/currentに新しくできたfsimage_<txid>のtxidを、/root/hdp/meta/fsimage_txid.txtに整数で記入してください。
saveNamespaceは、メモリ上の名前空間を新しいfsimageとして書き、editsを新しい区間に移します。ファイル名の数字は「このイメージに反映された最後のトランザクション番号」です。先頭の0は除いて、整数で記入してください。
セーフモードを解除して再び書く
hdfs dfsadmin -safemode leaveでセーフモードを解除し、/user/root/meta/after-saveディレクトリを作成してください。
このディレクトリは、ステップ3のfsimageにはなく、editsにだけ記録されます。ステップ5–7で、その違いを目で確認します。
fsimageをXMLに展開する
ステップ3のfsimageファイル(fsimage_<txid>)を、hdfs oiv -p XML -i <파일> -o /root/hdp/meta/fsimage.xmlで展開して書き出してください(プレースホルダーはファイルです)。
XMLのNameSectionにこのイメージのtxidが、INodeSectionにinode(ファイル・ディレクトリ)ごとの名前・権限・ブロックが入っています。q1.csvのブロックサイズを探し、after-saveがないことを確認してください。採点ツールも、その2つを見ます。
表に展開する(分析はこちらが楽)
同じfsimageを、hdfs oiv -p Delimited -i <파일> -o /root/hdp/meta/fsimage.tsvで展開して書き出してください(プレースホルダーはファイルです)。
Delimitedはinodeごとに1行で、列はパス・レプリケーション係数・更新時刻・ブロックサイズ・ブロック数・ファイルサイズ・クォータ・権限・所有者・グループです。数百万ファイルのクラスターで「どのディレクトリに小さなファイルが集中しているか」を探すとき、この表をスプレッドシートやSparkで読みます。
editsを開いて変更記録を読む
hdfs dfsadmin -rollEditsで今書いている区間を閉じ、ステップ4のディレクトリ作成が入っている閉じた区間edits_<시작>-<끝>を、hdfs oev -i <파일> -o /root/hdp/meta/edits.xmlで展開してください。その区間名と、その中のOP_MKDIRの数を、/root/hdp/meta/ops.jsonに{"segment": "edits_…-…", "OP_MKDIR": 정수}の形式で書き込んでください(プレースホルダーは順に開始、終了、ファイル、整数です)。
editsは、トランザクションごとにOPCODEとTXIDが付いた記録です。ステップ3のtxidの直後から始まる区間に、after-saveのOP_MKDIRがあります。閉じていないedits_inprogress_は開かないでください。
メタデータがどこにどう残るか
/root/hdp/meta/report.mdに、## 안전 모드・## fsimage・## editsの3つの節を書いてください(最初の見出しは韓国語で「セーフモード」を意味します)。2つ目の節にステップ3のtxidを、3つ目の節にステップ7のOP_MKDIRの数を入れてください。
NameNodeが再び起動するとき、fsimageとeditsをどんな順序で使うか、after-saveがどこにはあって、どこにはなかったかを書いてください。