はじめに
[!NOTE] この記事は、筆者が鈍器本を読みながら書き殴った個人的な読書メモをAIに食べさせ、ブログ用に読みやすく再構成させたものです。
CPU、メモリ、ネットワークと分析の基礎を固めてきましたが、今回はアプリケーションのパフォーマンスに直結する「8章 ファイルシステム」です。
システムが遅いとき、私たちは脊髄反射で「ディスクI/Oが遅い」とストレージのせいにしがちですよね。しかし、アプリケーションが実際にやり取りし、処理の終了を待っている相手はディスクではなく「ファイルシステム」です。ファイルシステムはあの手この手でディスクの遅さを隠蔽しようと奮闘しているため、ここをブラックボックスにしたままディスクの統計だけを眺めていても、真のボトルネックは見えてきません。
今回は、ファイルシステムとディスクの間に横たわる「深い溝」を理解し、最新のBCC/bpftraceツールを使ってファイルシステムレイテンシの正体を暴くためのサバイバル術をチートシート化しました。
1. 「ディスクが遅い」の嘘を暴く:論理I/Oと物理I/Oの乖離
アプリケーションがファイルシステムに要求するI/O(論理I/O)と、実際にディスクへ向かうI/O(物理I/O)は、決して1対1にはなりません。この乖離を知らないと、分析の際に出口のない迷路に迷い込むことになります。
- 小さくなる・なくなるI/O: アプリケーションが何度読み書きを要求しても、ページキャッシュにヒットしたり、ファイルシステムが書き込みをメモリ上で相殺(キャンセル)したりすれば、ディスクへの物理I/Oは「ゼロ」になります。
- 大きくなるI/O: アプリケーションが「1バイト」の書き込みを要求しただけでも、ファイルシステムのレコードサイズ(たとえば128KB)に合わせて読み書きが拡大され、さらにメタデータ(最終アクセス時刻やiノード情報)の更新やジャーナル(ログ)への書き込みが追加されるため、ディスクには巨大なI/Oの嵐が吹き荒れることがあります。
「アプリは何もしていないのに謎のディスクI/Oが発生している」ときは、バックグラウンドのファイルシステムタスクが暗躍している可能性が高いですね。
2. 賢すぎるがゆえの罠:プリフェッチとライトバック
ファイルシステムは、遅いディスクアクセスを回避するために非常に高度な先読みと遅延書き込みを行っています。
- プリフェッチ(先読み): ファイルシステムはシーケンシャルな読み出しを検知すると、「次も読むだろう」と予測して先回りしてデータをキャッシュに読み込みます。これが当たれば爆速になりますが、予測が外れると「誰も使わない無駄なディスクI/O」が大量発生し、キャッシュを汚染してしまいます。
- ライトバックキャッシング: ファイルシステムは書き込みデータを一旦メインメモリ上のページキャッシュにバッファリングし、あとで非同期にディスクへ「フラッシュ」します。そのため、アプリから見ると書き込みは爆速で完了しますが、裏では数十秒分のダーティデータが溜まっており、フラッシュのタイミングで突然ディスクI/Oの強烈なバーストが発生します。
3. 同期書き込みの代償と fsync(2) の使い所
DRAM上のキャッシュは電源が落ちれば消えます。データベースのトランザクションログのように、絶対にデータを失いたくない場合は同期書き込みを行いますが、これには致命的なパフォーマンスペナルティが伴います。
- 同期書き込みはディスクデバイスにデータが届くまでアプリケーションスレッドを容赦なくブロックしてしまいます。
- すべての書き込みを
O_SYNCなどのフラグで同期的に行うと、そのたびにファイルメタデータの更新も発生するため、ストレージが悲鳴を上げます。 - パフォーマンスを出す定石は、アプリケーションのアドレス空間で非同期に書き込みをまとめ、キリの良いチェックポイントで
fsync(2)を呼んで論理グループごと一気にフラッシュすることですね。
4. パフォーマンス分析の盲点「VFSレイテンシ」
伝統的に、OSはディスクデバイスレベルの統計(iostat など)しか提供してきませんでした。しかし、ディスクが遅延していなくても、ファイルシステム層のロック競合やキューイングによってアプリケーションが待たされていることは頻繁にあります。
- VFS(Virtual File System)のレイテンシを測れ: 現代のパフォーマンス分析では、ディスクではなく、ファイルシステムの共通インターフェイスであるVFSレベルでのレイテンシを計測するのが定石になっています。
bpftraceによる二峰性分布の可視化: BPFベースのトレーサーであるbpftraceなどを使ってvfs_readのレイテンシをヒストグラム化すると、キャッシュヒットによる高速な応答(数マイクロ秒)と、キャッシュミスによるディスクアクセス(数ミリ秒)の「二峰的な分布」が一目瞭然になります。これは非常に美しい可視化ですね。
5. ベンチマーキングの罠:あなたは「何」をテストしているのか?
ファイルシステムのベンチマークを実行して「このストレージは爆速だ!」と喜んでいるエンジニアの大半は、実は単に「メインメモリの速度」を測っているに過ぎません。
- ワーキングセットサイズ(WSS)の罠: テストで使うファイルサイズの合計がメインメモリ容量(ページキャッシュ)に収まってしまう場合、100%キャッシュヒットするためディスクのテストにはなりません。
- キャッシュのふるまいを排除して純粋なストレージ性能を測りたい場合は、テスト前に
echo 3 > /proc/sys/vm/drop_cachesでキャッシュをフラッシュしてコールド状態にするか、O_DIRECT(Direct I/O)を使ってファイルシステムキャッシュをバイパスする必要があります。
おわりに
この章を読むと、ディスクの統計(iostat)だけを見て「ディスクI/Oが遅い」と判断することがいかに危険であるかが痛いほどわかります。ファイルシステムが間に介在することで、I/Oの形は完全に変質してしまうのですね。









