OS: ファイルシステム

 組み込みシステムでないコンピュータには、CPUとメモリーのほかに、プログラムやデータを格納するストレージがあります。OS上で動作するプログラムは、ストレージ上のデータにファイルシステムを通じてアクセスします。例外は、一部のDBMSファイルシステムを作成・修復するツールだけです。


 プログラムは、カーネルの他の機能と同様、APIによってファイルシステムにアクセスします。カーネルは、これらの操作とストレージ上のデータを対応付けます。加えて、入出力されるデータをキャッシュするためのメモリー管理、アクセス権管理のためのユーザー管理などのセキュリティ機能、ストレージI/Oのためのデバイスドライバとそれぞれ連携します。ファイルシステムがさまざまなストレージに対応できるように、ファイルシステムデバイスドライバの間には、標準化されたストレージデバイスドライバのインタフェースが存在します。
f:id:nonbei:20180608172027j:plain
OS上で動作するプログラムはファイルシステムを通じてストレージを利用する


 ファイルシステムAPIは、ファイルの作成、ファイルのオープン・クローズ、ファイルの読み書き、ディレクトリの一覧取得、ファイルの属性情報取得・設定などの操作を提供します。


 読み書きするファイルの内容は、メモリー管理で紹介したように、カーネルがメモリーにキャッシュとして保持します。また、先頭から順番にファイルを読み込むのは、非常によくあるファイルアクセスの方法なので、ファイルシステムは、このような順次アクセスを検知したとき、ファイルを先読みしてキャッシュに置きます。データベースの表領域のようなランダムアクセスの場合、先読みはムダになるので行いません。


 LinuxWindowsファイルシステムは、書き込みの性能を重視して、デフォルトで書き込みにキャッシュを使います。書き込みのAPIが成功して完了しても、書き込んだデータはメモリー中のキャッシュにあるだけで、ストレージへの書き込みは完了していないことを意味します。このようなデータは、一定のタイミングでストレージに書き込まれます。API正常終了時に、ストレージへのデータ書き込みを保証したい場合、書き込みを保証するモードでファイルをオープンするか、キャッシュの書き戻しを指示するAPIを明示的に発行する必要があります。


書き込みサイズがI/O性能に影響

 ストレージは一定のブロックサイズ単位でしか読み書きできませんが、ファイルシステムAPIは1バイトなど任意の大きさのデータをファイルに読み書きできます。これは、プログラムの作成のしやすさの面ではよいのですが、I/O性能の面では注意を要します。

 ファイルシステムがストレージに対して行うI/Oは、ストレージのI/Oの最低単位であるブロックサイズと、メモリー管理の単位であるページサイズの両方に都合のよいサイズで行います。PCやIAサーバーが採用するインテル系のCPUでは4096バイト単位です。したがって、例えば、1バイトだけの書き込みを行うと、このバイトを含む4096バイトのデータを読み込み、1バイトを更新し、更新された1バイトを含む4096バイトを書き込む必要があります。

 このように非効率なストレージI/Oを行わないために、高レベルのファイルシステムAPIは、特に指定がない限り、ライブラリやプログラム中に確保したバッファを使って、4096バイトの倍数単位でファイルの読み書きを行います。

 ストレージI/Oの統計情報から分かる入出力されたデータ量やI/O要求の回数を見るとき、カーネルによる先読みとキャッシュ、ライブラリによるバッファの影響を考慮する必要があります。プログラムが行ったファイル入出力の量や回数と、ディスクに対して行ったI/Oは、多くの場合一致しません。直近にアクセスされたファイルならキャッシュ、書き込みの場合バッファによりI/O回数が少なくなることがあります。

 順次アクセスの場合、先読みで一時的にI/Oが多く見えることがあります。また、ファイルの新規作成時は、ストレージ上のデータ配置情報などファイルシステム自体が使うデータも更新する必要があるので、同一のファイルを上書きするときより多くのI/Oが行われます。


ソ-ス:プログラムやデータを読み書きする仕組み、OSのファイルシステム - 新人SEのためのOS基礎:日経 xTECH Active