2016/04/01

大量かつ高速に空ファイルを作成する

INSUITEグループのエンジニア、セイイチです。

テストのために大量かつ高速に空ファイルを作成する…そんなとき、みなさんはどのように対応していますか?いたって単純な処理…かとおもいきや、いざやってみるとこれがなかなか手ごわい。今回はその辺について自分の経験を書いてみます。

 

そもそもなぜ大量ファイル?

なぜ大量ファイルが必要になったか?

それは「inode番号が32bitの範囲を超えるファイルを32bit環境でビルドしたプログラムから読み込もうとしたときに読み込むことができない」という事象が発生したことに起因します。

事象に対応するために、自分の環境でそれらを再現させる必要がありました。

 

inode番号って何?

inode番号というのはUnix系OSでよく利用されるext2,ext3,ext4等のファイルシステムで使われるinodeという仕組みで利用されている番号です。

ちなみにinodeとは…

inode(あいのーど)は、ext2などのUnix系ファイルシステムで古くから使われているデータ構造である。
inode にはファイル、ディレクトリなどのファイルシステム上のオブジェクトに関する基本情報が格納される。 by Wikipedia

基本情報というのはファイルの所有者や更新情報などのこと。

これらの情報をinodeというところに格納しています。

inode番号というのはその名の通りinodeを指す番号のことで、ファイルとinodeを結びつけるものです。

ファイルのinode番号からinodeを特定することでファイルの基本情報を取得することができ、ファイルのinode番号はlsコマンドに-iオプションを付けることで簡単に確認可能です。


 

32bitを超えるってどういうこと?

inode番号は、通常、符号なし整数値で表現され、32bit環境では0〜4,294,967,295の範囲になります。

つまりinode番号が32bitの範囲を超える場合、0〜4,294,967,295の範囲以上になります。

 

大量ファイルとの関連は?

inode番号というのはファイル作成時に狙い撃ちできるものではありません。(少なくとも私のレベルでは無理)

しかもざっくり動作を見てみるとどうもシーケンシャルに連番で振られているように見える(注1)。

仮にシーケンシャルに連番が振られると仮定すると、32bitを超えるinode番号を持つファイルを作成するには少なくとも4,294,967,295以上のファイルを作成する必要があるということ(注2)。

なんと約43億ファイルが必要になります。

 

とりあえず、やってみよう

少し調べてみると、seqforを組み合わせるのが正攻法とのこと。

ファイルは空ファイルなのでtouchでいいとしてベンチマークをとるために10000ファイルをこんな感じで作成してみました。


じゃあ43億ファイルを作成するためにどのくらい時間が必要か?

計算してみると、なるほど、約36日。…これでは時間がかかりすぎます。

 

逆転の発想

試行錯誤していると、大量にファイルを削除するときはループじゃなくてパイプでxargsが早いという情報が。情報は削除ですが、もしやで実践。


なんと75倍も早い!

さっきまで約36日で想定していたものが、半日程度の間で終わることに。

結果、帰宅時に実行すれば翌出社時には32bitを超えるinode番号を持つファイルが手に入ることになりました。

 

まとめ

大量かつ高速に空ファイルを作成する方法について説明してきましたが、他にも大事なことが2つあります。

1つは「なぜ32bitを超えるinode番号を持つファイルを読み込めないのか」

もう一つは「なぜループじゃなくてパイプ+xargsで早くなったのか」

ここでは割愛しますが、比較的情報は得やすいと思うのでぜひ調べて見てください。

 

本記事が少しでもみなさまのエンジニアライフのお役に立つと幸いです。

Enjoy your engineering

 

注1: 実際は必ずしもシーケンシャルではないようです。
注2: 必ずしもシーケンシャルではないので、実際はもっと少なくてすみます。