OS

【図解】データがHDD/SSDに書き込まれるまでの全容

2023年4月28日

作成したアプリケーション・プログラムから、ファイルにデータを書き込んだ際、
どの様な流れで物理デバイス(HDD/SSDなど)に書き込まれるのか。

書き換え回数に制限のあるSSDが主流となった昨今、データの流れを知っておくことは非常に重要です。
どの様なファイル操作を行えば長持ちするのか、寿命を試算する際に必要となるからです。

本記事では、アプリから書き込みを行った際のデータの流れを図とともに解説します。

 

全体像

以下の図は、アプリから標準Cライブラリの fwrite(3) を使って書き込んだ場合と、
システムコールの write(2) を使って書き込んだ場合のデータの流れです。

参考

write(2) の正しい使い方は「write関数の使い方」を参照。

 

アプリが書き込み関数を呼び出した後、データが滞留する場所として
Stream BufferDisk Cache があります。

それぞれ詳しく見ていきましょう。

SANACHAN
SANACHAN
C言語を例に解説しますが、他言語でも同様の仕組みがありますので、適宜読み替えてください。

 

Stream Buffer とは?

fopen(3) で開いたり作成したファイルの戻り値である FILE 構造体に紐づいたバッファです。
Stack Overflow で紹介されている通り、glibc などの標準Cライブラリで実装されている仕組です。

 

標準Cライブラリで提供される fwrite(3) 関数は、指定された FILE に対してデータを書き込みます。
fwrite(3) は、指定された FILE 構造体に紐づく Stream Buffer にまずデータを格納します。

 

Stream Buffer は、バッファサイズと呼ばれる容量制限があり、
書込みデータがバッファサイズを超えた場合に、データがストリームにフラッシュされます。

SANACHAN
SANACHAN
強制的にフラッシュしたい場合は、fflush(3) を呼び出します。

このように、fwrite(3) を呼び出して書き込んだ場合、標準Cライブラリ内のストリームバッファに
一時的にデータが滞留することになります。

この仕組みがあるおかげで、getline(3) など改行を意識せずにテキストを読書きできたり、
fprintf(3) を使った高度なフォーマットの書込みが可能となっています。

SANACHAN
SANACHAN
高水準入出力関数とも呼ばれています。

 

Disk Cache とは?

ディスクキャッシュとは、OSが提供している機能で、ストレージへ書込むデータや読込んだデータを
キャッシュすることでストレージアクセスの高速化を図る仕組みです。

 

通常、ストレージからデータを読込んだり書込んだりする場合、物理的な HDD/SSD などにアクセスします。
物理的なストレージへのアクセスは、以下のようなメカニカルな操作によって遅延が発生します。
「I/O待ち」と呼ばれるように、ストレージアクセスには時間がかかります。

  • HDD:ディスクの回転やヘッドの移動など
  • SSD:Blockの消去、ECCの計算、Page単位での読書きなど
SANACHAN
SANACHAN
このようなI/O待ちを軽減するためにディスクキャッシュが用いられます。

 

ストレージから1度読込んだデータを主記憶(メモリ)内に一時的にキャッシュし、
必要に応じて再利用します。また、書込むデータを一時的に主記憶内にキャッシュし、
OSがタイミングを見て物理的なディスクへ書き出します。

SANACHAN
SANACHAN
物理的に書込まれていない状態のキャッシュを「ダーティ・キャッシュ」と呼びます。

 

キャッシュはメモリ上に配置されますが、どのくらいの容量が使用されているかは、
Windowsでは見ることができません。Linux では Cached Memory などで表現されます。

メモリの空き容量が一定量を下回ったり、再利用頻度などを見てキャッシュは順次クリアされます。

 

これらの副作用

Stream Buffer があるおかげで高度な入出力操作ができるようになり、
Disk Cache があるおかげで高速なストレージアクセスができるように振舞えるようになっています。

しかし、良いことばかりではありません。
開発者にとっては、以下のようなデメリットもあります。

  • 実際に書き込まれるタイミングが分からず、電源断によるファイル破損が起きやすい
  • キャッシュ/ディスクのどちらから読書きしているのか分からず性能測定が厄介

 

ファイル破損を防ぐ方法は、強制的に書き込ますことができる fsync(2) を使うことで防げます。
本サイト「電源断で破損を防ぐ方法」でも紹介していますので、参照ください。

 

性能測定を行う場合は、ディスクキャッシュが配置されるメモリ容量より大きな
ファイルの読書きを行えば、測定することができます。
読書きの最初はキャッシュが利用されますが、後半のアクセスで極端に遅くなることが確認できます。

SANACHAN
SANACHAN
後半が本来の性能になります。

 

まとめ

いかがでしたでしょうか。

作成したアプリがデータをファイルに書き込んだからと言って、
即座にストレージに書き込まれることはなさそう・・・という雰囲気はつかんでいただけたと思います。

ファイル破損やストレージの寿命試算など、本記事が参考になればうれしいです。

 

参考

 

こちらの記事もよく読まれています

  • この記事を書いた人
  • 最新記事
SANACHAN

SANACHAN

「生涯一エンジニア」を掲げ、大手グローバル企業でSE/PGとして8年勤め、キャリアアップ転職した現役のエンジニアです。世にあるメジャーな全プログラム言語(コボル除く)を自由に扱えます。一児の父。自分のため、家族のため、日々勉強してます。システムエンジニア、プログラミングに関する情報を蓄積している雑記帳です。

-OS
-, , ,