テストステ論

高テス協会会長が, テストステロンに関する情報をお届けします.

(writeboost report) Understanding the Robustness of SSDs under Power Fault (FAST13) 読んだ & ライトブーストの対策

http://akiradeveloper.hatenadiary.com/entry/2013/12/30/092519

において, ライトブーストの課題は, SSD上に書き込まれた1つのセグメントを読むときに, SSDへのパーシャルライトへのケアだと述べた.

まず, ライトブーストにとってパーシャルライトがどういう問題を起こすかを述べる.

まずデータブロックの異常について,

  1. もし, メタデータ領域は書き変わらず, データ領域だけが書き換わってしまった場合, リプレイでは, 「そのセグメントは正しく判定されてしまい, 書き込んだ覚えのないデータが読めてしまう」という事態が起こる. これは明らかにファイルシステムを破壊する. これは明らかにヤバい.
  2. セグメントの先頭512B以降からチェックサムを作り, 先頭512Bに保存することで, データが正しくないことを発見出来るようにすると仮定する.
  3. すると, 誤ったデータが書き込まれていた場合に, 若いidの領域でセグメントが誤っていると判定されてしまう. この事態の扱いが問題となる.
  4. 安直な方式は, 仮に同時に並列I/Oされていた数Nが分かっているとすると, その部分に限っては「誤っている場合」スキップするということがある(セグメントが再利用されていると仮定すると以前のデータはライトバックされているはずだから, データを捨てるだけ). ただし, これは境界が難しい. idが古い方N個をすべてを無視することが正しいかどうかは分からない(ライトバックされていない可能性がある).
  5. 同時にフラッシュされる数がたかだか一つならばこの部分が緩和される. 1つなら, 境界もへったくれもない. セグメントが異常ならばただスキップするだけで良い.
  6. ただし, バッファが永続的であれば, これをフラッシュしたあとにSSDのリプレイをすることによって, パーシャルライトのセグメントは消え失せるはずであるから, 問題は, バッファが揮発の場合に限る.
  7. 従って, バッファが揮発である場合は並列I/Oを禁じることによって, なんとかなりそう?

次に, メタデータの異常について,

  1. メタデータのうち, 先頭512Bが更新されなかった場合, これはチェックサム異常になるから上の議論の帰着する.
  2. 先頭512Bが書き換わった場合, これはアトミックであるから, idは新しくなる. 従って, 後の方にリプレイされるので問題が発生しない. 仮に永続化ACKしてるならパーシャルライトもあり得ないので, 後ろの方で正常でないセグメントを見つけた場合はリプレイを即中断すればよい.

@kumagiによると, https://twitter.com/kumagi/status/416795237072109568 IntelのDC用SSDは電断にも強く無敵であるとのことだが, 色々な人が使う可能性を考えると, キャッシュデバイスへは最低限の期待しかしてはならない. 出来ることならば, SSDがタコでも動くようにして, 無理ならば制限をつけるのが望ましい.


というわけで, SSD一般でいうと, どの程度まで電断への耐性があるのかということを調べる必要がある. FAST13でちょうどいい発表があったようなのでこれを調べることにする.

https://www.usenix.org/conference/fast13/understanding-robustness-ssds-under-power-fault

著者は, SSDのfailureを以下の6つに分類

  1. Bit Corruption: データ化け. 突然のPower Fault下では, ECCがちゃんと働かなかったためと書いてある.
  2. Flying Writes: FTLのバグなんかで別のLBAに書かれる
  3. Shorn Writes: 部分的に書かれてしまう. 実験では, 4KBライトをして512B単位でこの現象が起こったと書いてある. 著者は, SSDは4KBごとにページ管理するから, これは起こらないだろうと思ってたとのこと.
  4. Metadata Corruption: FTL破壊. ふつう, SSDは内部的にキャパシタを持っていて, 電断時にはこれを使って揮発性のデータを書き戻すようなのだが, これがなされずに死ぬ. SSDは, キャパシタへの電荷がたまるまでは, FTLの書き戻しについて保守的な動作をすることもある.
  5. Dead Device: 死. これはどうしようもない
  6. Unserializability: あるアドレスについて, データX, Yの順でACKしてきたはずなのになぜかXが書かれている. フラッシュを有効活用するためのinternal parallelism(それと, FTLの存在)が問題を起こりやすくしている.

著者は, これらを見つけるために, 例えばBit CorruptionとShorn WritesについてはChecksumを使っている(何bitかわからん・・). あと, completionの時間を記録するなどしてunserializabilityを検出している. ふつうのことをしてふつうに検証したという感じの印象.

ライトブーストは, 512KBごとの大きなライトしかしないが, これらは基本的に, 512Bごとにしかアトミックでなく, バラバラにShorn Writesされる可能性を考慮する必要があると思う. 512Bアトミックというのは, http://stackoverflow.com/questions/2009063/are-disk-sector-writes-atomic を見ると「No」という人もいるが, FlashCache(Facebook)などでも仮定しているし, ことさらライトブーストがこの仮定をしないマゾゲーに走る意味がよくわからないので仮定する. 実際に, この仮定が崩れるとライトブーストは少なくとも揮発バッファでは破綻する.


私の今のところの考えとしては, 揮発バッファの場合だけケアを強めればよく, この場合にフラッシュデーモンの数をたかだか1つにしぼりこめば, なんとかなるものと思う(少なくともShorn Writesについては).

SSDは内部的に揮発性のバッファを持つので, この点も問題になる. SSDへの書き込みを常にFUAにすれば問題は解消されるが性能面で問題がある. 例えば, 最悪ケースの場合, 内部バッファ分のデータが全部corruptする可能性もある. 不揮発バッファの場合でも, この量が内部バッファより少なければ, 失ったデータを取り戻すことが出来なくなる. しかし, 永続ACKを返していないものについては捨ててもいいとすると, 案外なんとかなりそう(古いidのデータがそもそも内部バッファから書き戻されなかったということは, そもそもそれ以降でも一度も永続ACK返してないということだから).


結構ややこしいけど, Checksumを信頼していいならなんとかなりそうな感じはするので, もう少し検討します. 仮に, 最悪のSSDに対しても正しさを追加出来るならば, それもライトブーストの価値になる.