-
Notifications
You must be signed in to change notification settings - Fork 14
Precise Number of Disk Accesses
Overviewを見ると、CannyLSが提供する各操作実行時のディスクアクセス回数は、以下の通りであることが分かる:
操作名 | ディスクアクセス回数 | 内訳 |
---|---|---|
GET | 1 | データ領域からの読み込み |
HEAD | 0 | |
LIST, LIST_RANGE | 0 | |
DELETE, DELETE_RANGE | 1 | ジャーナル領域へのログ追加 |
PUT | 2 | データ領域への書き込み + ジャーナル領域へのログ追加 |
PUT(ジャーナル埋め込み) | 1 | ジャーナル領域へのログ追加 |
基本的には上の通りであるが、 実際にはジャーナル領域のGCとメモリバッファの影響で発生するディスクアクセスがある。 この点について以下で述べる。
StorageBuilder::journal_syn_interval
オプションに1
以上の値が指定されている場合には、ジャーナル領域のメモリバッファが有効となる。その場合、更新系操作(i.e., PUT/DELETE/DELETE_RANGE)を処理した際に、それに対応するジャーナルレコードは、即座にディスクに書き込まれるのではなく、いったんメモリ上のバッファに保持され、(通常は)その数が閾値に達した時点で、まとめてディスクに書き出されることになる。
そのため、メモリバッファが有効になっていると、(バッファの内容がディスクに同期されるタイミングを除いて)更新系操作のディスクアクセス回数が全て一回少なくなることになる。ただし、バッファの同期タイミングでディスクI/Oのサイズが大きくなるため、そこに重なった操作の処理時間は(ディスクアクセス回数的には一回だとしても)他に比べて長くなることになる。
ジャーナル領域の形式は「容量が固定のリングバッファ」となっているため、レコードを無限に追記していくことはできず、どこかで不要となったレコード群を回収するためGCを実施する必要がある。
GC処理の概要は以下のようになる(詳細はJournal Region GCを参照):
- ディスクが暇になったら、ジャーナル領域の先頭から一定数(e.g., 数千個)のレコード群を読み込む
- 読み込んだレコード群の内、まだ有効なレコードに関しては、以降の更新系操作用のレコードの追記に合わせて、ジャーナル領域の末尾に再配置する
- 「通常のレコード」+「GCによって再配置されるレコード」の二つのレコードがまとめて追記されることになる
-
1
で読み込んだレコード群を、2
によって全て再配置ないし破棄し終わったら、ジャーナル領域のヘッダに記載の「リングバッファの先端位置」の情報を更新する
この内の1
のためのディスクI/Oに関しては「ディスクが暇になったタイミング」で発行されるため、通常の操作要求の処理に影響を与えることはない。(実際には「暇になった」と判定した直後に、一気に利用者からの大量の要求を受信する可能性もありはするので、確実に影響を与えないという保証は無い。またジャーナル領域の空き容量が少なくなった場合には「暇になった」時に以外にも1
の処理が実行されることもある。)
2
のために必要なディスクI/Oに関しては、GCが存在しない場合に比べて、ディスクへの書き込みサイズは増えるが、発行されるI/Oとしては一回にまとめられることになるため、ディスクアクセス回数への影響はない。さらに内部的な話をするのであれば、CannyLSではダイレクトI/Oを使用している関係上、一回のディスクI/Oで処理されるサイズの下限は512B
となるが、大抵はジャーナルレコードを二つ合わせてもこのサイズ以下になるため、実質的なI/Oサイズの観点でもGCによる影響は軽微といえる。
3
の実行のために必要なディスクI/O(書き込み)は、純粋な増加分となるが、実行頻度はまれでI/Oサイズも小さいため、通常は無視しても問題がない。