2025/04/06 12:39 The order of files in your ext4 filesystem does not matter

ロボ子、大変なのじゃ!Bashのglob展開のファイル順序が原因で、本番環境が数時間も停止したらしいぞ!

それは大変ですね、博士。glob展開の順序がそんなに重要な影響を与えるとは驚きです。

そうなんじゃ。Dockerイメージ内のJVMワークロードで、クラスパスに`/jars/*`みたいなワイルドカードを使ってたのが原因らしいぞ。

なるほど。JVMがワイルドカードを展開する際に、POSIXシステムの`readdir`システムコールを使うんですね。

`readdir`はext4ファイルシステムのハッシュBツリーでディレクトリのエントリをキャッシュするらしいんじゃ。ここでディレクトリハッシュシードが重要になるみたいだぞ。

ノードイメージのパッチ更新でディレクトリハッシュシードが変わって、クラスパス内のjarファイルの順序が変わった、と。

その通り!それで、アプリケーションの初期化中に`NoSuchFieldError`が発生して、初期化が止まってしまったらしいのじゃ。

`NoSuchFieldError`ですか。特定のクラスが見つからない場合に発生するエラーですね。

そうじゃ。原因はBouncy Castleプロバイダーの依存関係にあったみたいじゃ。特定のクライアントライブラリが`jdk15`以上のバージョンを必要としていたらしい。

ノードイメージ更新前は、`jdk15`または`jdk18`が`jdk14`より前に読み込まれていたのが、更新後に`jdk14`が先に読み込まれるようになったんですね。

さすがロボ子、理解が早い!ext4の`readdir`実装はh-treeインデックスを使っていて、`is_dx_dir`と`ext4_dx_dir`がディレクトリの走査に使われるらしいぞ。

Buildahのレイヤー順序やOverlayFSのレイヤー順序も調査されたんですね。でも、根本的な原因はディレクトリハッシュシードだった、と。

そうなんじゃ。最終的には、16進数エディタでディレクトリハッシュシードを直接変更して、順序が一致することを確認したらしいぞ。すごい執念じゃ!

原因特定までの道のりが長いですね。それにしても、ファイルシステムの内部構造が、こんな形でアプリケーションに影響を与えるとは。

本当にそうじゃ。教訓としては、クラスパスの順序に依存しないように、より具体的な指定をするのが大事じゃな。例えば、ワイルドカードではなく、個別のjarファイルを明示的に指定するとか。

そうですね。あとは、環境が変わっても同じ順序でjarファイルが読み込まれるように、設定ファイルを工夫するとか。

それも良い考えじゃ!しかし、まさかディレクトリハッシュシードがこんな落とし穴になるとはのう…。

本当にそうですね。今回の件で、ファイルシステムの奥深さを改めて認識しました。

ロボ子、今回の件で学んだことを活かして、明日のランチは一番最初に食べるのじゃ!

えっ?それはちょっと違うような…
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。