101:ファイルを格納するディレクトリを分散させる

プログラミング迷子: 1ディレクトリに数万ファイル

  • 後輩W:ユーザーからバグ報告をもらったので調査してるんですが、lsコマンドの結果が表示されるのに数十秒かかってしまって、これってどうにかならないんでしょうか?

  • 先輩T:lsのオプションを指定したり、lsの代わりにfindを使う方法とかあるけれど、そもそも、そんなにたくさんのファイルが置かれてるのがまずそうだね。

  • 後輩W:そういうものなんですね……。

たとえば以下のように、作成したすべてのファイルを1つのディレクトリに置いてしまうと、パフォーマンスの低下などの問題が発生します。

/receipts/receipt-20190718-123456.pdf
/receipts/receipt-20190718-154211.pdf
/receipts/receipt-20190719-081001.pdf
/receipts/receipt-20190720-221020.pdf

ファイルが増え続けるシステムの場合、リリース直後は問題になりませんが、ファイル数の増加とともに徐々に影響が出てきます。

ベストプラクティス

ファイルを格納するディレクトリを分散させましょう。

分散にはいくつかやり方がありますが、元になるデータのID(データベースで自動採番されるID)を利用してディレクトリを分ける方法がよく使われます。

/receipts/123/receipt-20190718-123456.pdf
/receipts/124/receipt-20190718-154211.pdf
/receipts/125/receipt-20190719-081001.pdf
/receipts/126/receipt-20190720-221020.pdf

この方法は、レコード単位で複数のファイルを扱う場合などには、直接的でわかりやすい構造です。 開発中や障害発生時などには、調査がスムーズに進められます。 ただし、デメリットもあります。 この方法ではレコード数分だけディレクトリが増えていくため、10万レコードに対してディレクトリが10万個作成され、再び速度低下の原因になってしまいます。

その他にも、ファイル名等の一意な名前からハッシュを生成して、特定の数文字を使ってディレクトリを分ける方法があります。

cover

(中略)詳細は書籍 自走プログラマー をご参照ください