Slide 1

Slide 1 text

同期I/Oとdirect I/O Dec, 21 2020 Satoru Takeuchi Twitter: satoru_takeuchi, EnSatoru 1

Slide 2

Slide 2 text

同期I/O ● Q: ページキャッシュからディスクへの書き込み前にシステムが死ぬと? ○ A: データは消える! ○ ついでにファイルシステムが壊れることも … ● 同期I/O ○ I/O速度よりもディスクへの書き込みされたことの保証を優先するときに使う ○ 書き込み時にページキャッシュに加えてディスクにも書き込んでから復帰 Buffered I/O 同期I/O メモリ(速い) ディスク(遅い) メモリ(速い) ディスク(遅い) 1) 書く 1) 書く 2) 書く 2

Slide 3

Slide 3 text

同期I/Oの使い方 ● open()システムコールのO_SYNCフラグ ● “sync” mountオプション: ファイルシステムの全I/Oを同期I/Oにする ● 既存のページキャッシュを明にディスクに同期することも ○ fsync()システムコール ○ syncコマンド ■ ファイル、ファイルシステム、システム上の全データをディスクに同期可能 ○ 使用例 i. open()時にはO_SYNCを付けない ii. トランザクションを構成する複数 write I/Oを発行 iii. fsync()で同期 3

Slide 4

Slide 4 text

Direct I/Oとは ● ときにはページキャッシュがいらないことがある ○ バックアップデータへの書き込み : 一度書いた後は読み出さない ○ 自分でキャッシュ機構を作りたい ● Direct I/O ○ I/O時にページキャッシュを使わない Buffered I/O メモリ(速い) ディスク(遅い) 書く direct I/O メモリ(速い) ディスク(遅い) 書く 読む 読む 4

Slide 5

Slide 5 text

Direct I/Oの使い方 ● open()システムコールのO_DIRECTフラグ ● 制約が多いので注意(詳しくはman 2 openを参照) ○ I/Oサイズはストレージのセクタサイズ (512バイトや4Kバイト)単位 ○ 書き込むデータはセクタサイズの境界に存在 ○ fork()と同時にI/Oが発生するとデータが壊れるかも ● いろいろややこしいのでLinus Toravaldsに嫌われている 5 man 2 openより抜粋 “The thing that has always disturbed me about O_DIRECT is that the whole interface is just stupid, and was probably designed by a deranged monkey on some serious mind-controlling substances."—Linus

Slide 6

Slide 6 text

Direct I/Oマニアクス ● direct I/Oでwrite()しても同期書き込みにはならない ○ write()が復帰した時点で書き込み完了は保証されない (すぐ終わるけど) ○ 同期direct I/OしたければO_DIRECTとO_SYNC両方つけるべし ● ページキャッシュがあるときの振る舞い ○ read(): ページキャッシュを使うし捨てない ○ write(): ページキャッシュを捨てる 6

Slide 7

Slide 7 text

まとめ ● ページキャッシュに関して3つのI/Oモードがある(相互排他ではない) ○ 通常のI/O ■ ページキャッシュがあれば使う。書き込み時はページキャッシュに書くだけで復帰 ○ 同期I/O ■ ページキャッシュがあれば使う。書き込み時は必ずディスクにも書き込む ○ Direct I/O ■ 書き込み時はページキャッシュを使わない。読み出し時はあれば使う ● 用途によって使い分けが必要 7