TT Lab
はじめる
学ぶ 学習パス コース

Apache Hadoop — 1つのPodにHDFSとYARNを立てて運用する

1 バイトのファイルが 30MB のクォータに阻まれる理由を再現する

TT Labで続きを見る

目標

ディレクトリに名前クォータとスペースクォータをかけ、名前クォータがディレクトリ自身まで数えることと、スペースクォータがブロックサイズ×レプリケーション係数の分だけ事前に予約することを、拒否メッセージで確認します。ブロックサイズを減らして同じファイルを入れ、クォータが移動(mv)までブロックすることも見ます。

なぜ重要なのか

複数のチームが1つのHDFSを共有すると、あるチームのミス(無限にファイルを作るジョブ、小さなファイル数百万個)が、NameNodeのヒープとディスクを、全員のものから奪います。クォータは、その被害を1つのディレクトリに閉じ込める仕組みです。名前クォータはファイルとディレクトリの数を、スペースクォータはレプリカを含むバイト数を制限します。 スペースクォータには、落とし穴が1つあります。ファイルを書き始めるとき、NameNodeはまだ何バイト書くかを知らないので、ブロック1つを丸ごと(ブロックサイズ×レプリケーション係数)予約します。そのため、残りのクォータが128MBより小さければ、1バイトのファイルも入れません。書き込みが終われば実際のサイズに調整されますが、始めることさえできなければ意味がありません。本番での「クォータが残っているのに、なぜ書けないのか」という問い合わせの大半は、これです。 クォータは、新しい名前ができるすべての操作にかかります。別のディレクトリから移動してくることも、そのディレクトリから見れば新しい名前です。

ステップ

  1. /quota/team-aをHDFSに作成し、名前クォータ10をかけてください(hdfs dfsadmin -setQuota)。
  2. 小さなローカルファイルを1つずつteam-aにアップロードして、拒否されるまで埋め、拒否されたputのエラー出力を、/root/hdp/quota/quota_err.txtに保存してください。
  3. /quota/team-bを作成し、スペースクォータ30MBをかけてください(hdfs dfsadmin -setSpaceQuota 30m)。
  4. /root/hdp/quota/one.txt(1バイトのローカルファイル)を作成し、/quota/team-b/one.txtにアップロードしてみて、エラー出力を、/root/hdp/quota/space_err.txtに保存してください。
  5. 同じファイルを、ブロックサイズ1MiB(-D dfs.blocksize=1048576)で、/quota/team-b/one-1m.txtにアップロードしてください。
  6. hdfs dfs -count -q -v /quota/team-a /quota/team-bの出力を、/root/hdp/quota/count.txtに保存してください。
  7. /quota/stagingを作成し、ファイル1つ(/quota/staging/f.txt)をアップロードしたあと、それをteam-aに-mvしてみて、エラー出力を、/root/hdp/quota/mv_err.txtに保存してください。
  8. /root/hdp/quota/report.mdに、## 이름 쿼터・## 공간 쿼터・## 쿼터가 막는 것の3つの節を書いてください(見出しは韓国語で、順に「名前クォータ」「スペースクォータ」「クォータが防ぐもの」を意味します)。最初の節にteam-aに実際に入ったファイル数を、2つ目の節に予約しようとしたバイト数(134217728)を入れてください。

参考

名前クォータをかける

/quota/team-aをHDFSに作成し、hdfs dfsadmin -setQuota 10 /quota/team-aで名前クォータ10をかけてください。

名前クォータは、そのディレクトリの下(自身を含む)のファイルとディレクトリの数の上限です。かかった値は、hdfs dfs -count -qの最初の列で見ます。

10なのに、いくつ入るのか

小さなローカルファイルを複数作成し、1つずつhdfs dfs -putでアップロードしていってください(アップロード先: /quota/team-a/)。拒否されたputのエラー出力(標準エラー出力)を、/root/hdp/quota/quota_err.txtに保存してください。

ディレクトリ自身も、名前1つとして数えます。そのため、ファイルはクォータより1つ少なく入ります。拒否メッセージには、クォータと「入れようとしたあとの個数」が一緒に出力されます。

スペースクォータをかける

/quota/team-bをHDFSに作成し、hdfs dfsadmin -setSpaceQuota 30m /quota/team-bでスペースクォータ30MBをかけてください。

30mは、30×1024×1024バイトです。スペースクォータは、レプリカまで数えた実際のディスク使用量の上限です。

1バイトがブロックされる

/root/hdp/quota/one.txt(1バイトのローカルファイル)を作成し(printf x > /root/hdp/quota/one.txt)、hdfs dfs -putで、/quota/team-b/one.txtにアップロードしてみてください。エラー出力を、/root/hdp/quota/space_err.txtに保存してください。

書き込みを始める瞬間、NameNodeはブロック1つ(ブロックサイズ×レプリケーション係数)を予約します。デフォルトのブロックサイズ128MBは、30MBのクォータより大きいです。メッセージの2つの数値、つまりクォータと必要だった容量を比べてみてください。

ブロックを小さくすると入る

/root/hdp/quota/one.txt(先ほどと同じファイル)を、hdfs dfs -D dfs.blocksize=1048576 -putで、/quota/team-b/one-1m.txtにアップロードしてください。

ブロックサイズが1MiBなら、予約も1MiBです。書き込みが終わると、使用量は実際のサイズ(1バイト×レプリケーション係数)に調整されます。-count -qのREM_SPACE_QUOTAがどれだけ減ったかを見てください。

count -qで2つのクォータを読む

hdfs dfs -count -q -v /quota/team-a /quota/team-bの出力を、/root/hdp/quota/count.txtに保存してください。

クォータがない列は、none/infと出力されます。team-aはREM_QUOTAが0で、team-bは容量がほとんどそのまま残っています。拒否は「残りの量」ではなく、「予約する量」が原因でした。

移動もクォータに引っかかる

/quota/stagingをHDFSに作成してファイル1つを、/quota/staging/f.txtとしてアップロードしたあと、hdfs dfs -mv /quota/staging/f.txt /quota/team-a/を実行してみて、エラー出力を、/root/hdp/quota/mv_err.txtに保存してください。

移動はバイトを動かしませんが、team-aから見れば名前が1つ増えます。そのため、名前クォータが拒否し、ファイルはstagingにそのまま残ります。

クォータの問い合わせに答えられるように

/root/hdp/quota/report.mdに、## 이름 쿼터・## 공간 쿼터・## 쿼터가 막는 것の3つの節を書いてください(見出しは韓国語で、順に「名前クォータ」「スペースクォータ」「クォータが防ぐもの」を意味します)。最初の節にteam-aに実際に入ったファイル数を、2つ目の節にステップ4で予約しようとしたバイト数を、数値で入れてください。

「クォータ10なのに、なぜ9個しか入らないのですか」「30MBが残っているのに、なぜ1バイトも書けないのですか」という問い合わせに答えるつもりで書いてください。