- ベストアンサー
HDDの書込み速度ばらつきの原因と解析方法
- HDD(ハードディスク)の書込み速度ばらつきが発生する理由はRAID0構成のハードディスクにアプリケーションから1MB単位で連続してwrite()し、1GBの巨大ファイルを作成する際に、各write()システムコールにかかる時間が異常に長くなることが原因です。
- 解析の結果、RAIDボードの割込み応答を待つ時間が異常に長くなっていることが判明しました。これはRAIDコントローラまたはハードディスクの特性に起因している可能性があります。
- ディスクを取り替えても同じ現象が発生することから、原因はハードディスクの特性やRAIDコントローラにあると考えられます。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
補足を読みました。 >RAIDボードの割込み応答を待つ時間が異常に長くなっていました。 という事ですし。 割り込みを取りこぼしているのならその時点でハングアップしているはずです。速度以外の点では正常に動いているのなら、RAIDユニットは正常な動作として、書き込み完了が遅くなっているのでしょう。 RAIDコントローラかディスクドライブのキャッシュメモリがが一杯になって、物理的な書き込みが完了するのを待っているいるタイミングではないでしょうか。写真を見る限り、RocketRAID 1640はキャッシュメモリはないもようですが。 本来は O_SYNC|O_DIRECTを指定するとキャッシュもバイパスしてライトスルーでディスクに書き込まないと行けないのですが、そこがちゃんとしていないのでしょう。 あるいは、「AV用」ではないグレードのディスクドライブでは、長時間連続で書き込み続ける場合の応答速度が保証されていません。そのせいかも。 いちど、RAIDコントローラを外して裸の単体ディスクドライブ相手に同じ事をしてみて、やはり同様な挙動を示すのなら、現状のlinuxはそんなものとあきらめるしかないのでは? 20msごとに1MByteということは、毎秒50MBです。2.5Inch1000rpmのSeagate SAVVIOでもsustaind transfer rateは41~63MByte/secなので、50MBytesecで書き込み続ければどこかで追いつかなくなります。
その他の回答 (2)
- a-saitoh
- ベストアンサー率30% (524/1722)
ANo1で説明されているとおりです。 通常、UNIX/POSIX系のOSでは書き込みはカーネル内バッファに対して行われます。writeシステムコールから戻ったことは、バッファへの書き込みが終了したことを示すに過ぎません。 同期マウントするとか、書き込み時にオプションで同期書き込みを指示すればディスクに書き込んでからwriteシステムコールがリターンするようになります。 ただ、linuxはここのところの問題があるようで、ディスクに書き込んでないのに戻ってくることがあるそうです。詳しくは参考 URL をみてください。 日本語の情報は、UNIXマガジンの月刊時代の最後の2冊(今年の3,4月号)を読んでください。
補足
回答およびたいへん興味深いサイトのご紹介ありがとうございます。 申し訳ありません。説明不足でした。 open()時にO_DIRECTとO_SYNCを指定しています。なので (1)カーネル内のディスクキャッシュを使っていない (2)write()から戻ったときにはディスクへの書込みが終わっている と思っています。 実際ロジックアナライザでPCIバスの信号を見るとwrite()1024回のうち90%は20msec程度で1MBを書き込んでます(速度50MB/sec)。なのでこの90%は「たまにディスクに書き込んでいないのに戻って速い速度になっている」という現象ではなさそうです。 残り10%がいろいろなレベルでばらついてまして、ごく稀に最悪値の300msec程度になります。このときPCIバスをロジアナで見ると、バスを占有するような他プロセスの動きはみられません。 ただ最悪値をとるのは3~4MBを書き出したあたりになることが多いです。このへんに何かヒントがあるのでしょうか…
- Tacosan
- ベストアンサー率23% (3656/15482)
ちょっと考えればわかりますが, 1MB のデータを 20ms でディスクに書き出すのは不可能です. いくらなんでも 50GB/s は無理. でどうするかというと, write したデータを一旦バッファにためておきます. その後, 特定のタイミングで実際にディスクに書き出します. ということで, その「300ms とケタはずれに時間がかかる」タイミングでディスクに書き出している (正確には RAID コントローラにデータを渡している) んでしょう. ちなみに, RAID コントローラにデータを渡すのに 300ms かかったとしても, 実際に 300ms でディスクに書き出せるはずはないので注意. つまり, 「カーネルはデータをディスクに書き込んだつもり」でも, 「実際には書き込まれていない」という瞬間が存在します. このような瞬間を減らす (究極的にはなくす) のが, たとえばジャーナリングというものだったりするんですが, Linux ではねぇ....
補足
すすすすみません50GB/sではなく50MB/sとなります。 PCIバス 33MHz, 32bit なので計算では最高133MB/secです。 write()の計測時間と、RAIDディスクへDMA転送している時間(ロジアナでPCIバスをみた)がほぼ一致していました。なので1MBあたり20msecでディスクに書き込みんでいると思っていいのではないかと思いました。 問題の300msec時は、RAIDコントローラ自らバスを解放しDMA転送を途中でとりやめていました。なのでOS側に原因はないのではないか?というスタンスです。
お礼
RAIDカードをも調べていただいたようで恐縮です。 ディスクドライブのキャッシュメモリ、グレード sustaind transfer rate これらが大きなヒントになりました。 現状のLinux、RAIDコントローラ、ハードディスクのもつこのような性質を考慮した上で設計する必要がありますね。ありがとうございます。