2016-08-18 7 views
6

私はC++ 11(VS2013)を使ってUDPベースの転送プロトコルを書いています。それは速くて驚異的で、時間の99,9%を稼いでいます。間違ったバイトがディスクに書き込まれることがあります。ハードウェアの問題?

enter image description here

しかし、私は間違ったバイトがディスクに書き込まれていることを数回(サムスン250ギガバイトSSD 850 EVO)を観察している - あるいは少なくともそれはそう思えます。サイズは64K - ファイルが小さいUDPのdatapackagesに分割され

  1. は、ここで私が6ギガバイトのテストファイルを転送するときにいつか何が起こるかは基本的です。 (ネットワーク層はUDPデータグラムを解読し、より大きなパッケージに再構築する)。

  2. クライアントはサーバーにデータパッケージ(udp)を送信します。ペイロードはAES256(OpenSSL)を使用して暗号化され、データとメタデータが含まれています。ペイロードには、ペイロード全体のSHA256ハッシュも含まれています.UDPチェックサムの上に余分な完全性チェックがあります。
  3. サーバーはデータパッケージを受信し、 "ACK"パッケージをクライアントに送り返し、SHA256ハッシュを計算します。ハッシュはクライアントハッシュと同じです - すべてが良いです
  4. サーバーは、パッケージのデータをディスクに書き込みます(パフォーマンスの差が大きいため、ストリームの代わりにfwriteを使用します)。サーバーは一度に1つのパッケージのみを処理し、各ファイルポインタにはミューテックスガードがあり、10秒間アクティブではないファイルポインタを閉じる別のワーカースレッドによって閉じられることを防ぎます。
  5. クライアントはUDP「ACK」パッケージを受け取り、受け入れられていないパッケージを再送します(意味がない)。入ってくるACKパッケージのレートは、クライアントの送信速度(別名、輻輳制御/スロットル)を制御します。サーバー上で受け取ったパッケージの順序は、各パッケージにPosition値(ファイル内のどこにデータを書き込むべきか)が含まれているので重要ではありません。ファイル全体が、私は、サーバーとクライアントの両方で6ギガバイトのファイルのフルSHA256ハッシュを行う転送されますが、私の恐怖に私はハッシュがませで二回最後の数日間ことを観察した後

同じ(約20回のテスト転送を行う場合)。

Beyond Compareのファイルを比較したところ、(6 GBファイル内)のが1つまたは2つ見つかりましたが、これはサーバー側で間違っています。

下記を参照のスクリーンショット:enter image description here

Serverコード - DataPackageハッシュだから合計する

void WriteToFile(long long position, unsigned char * data, int lengthOfData){ 

    boost::lock_guard<std::mutex> guard(filePointerMutex); 

    //Open if required 
    if (filePointer == nullptr){ 
     _wfopen_s(&filePointer, (U("\\\\?\\") + AbsoluteFilePathAndName).c_str(), L"wb"); 
    } 

    //Seek 
    fsetpos(filePointer, &position); 

    //Write - not checking the result of the fwrite operation - should I? 
    fwrite(data, sizeof(unsigned char), lengthOfData, filePointer); 

    //Flush 
    fflush(filePointer); 

    //A separate worker thread is closing all stale filehandles 
    //(and setting filePointer to NULLPTR). This isn't invoked until 10 secs 
    //after the file has been transferred anyways - so shouldn't matter 
} 

を確認された後に呼び出さ:

  • のchar *が上のメモリに正しかったですサーバー - そうでなければサーバーSHA256ハッシュは失敗しました - そうですか? (sha256とのハッシュ衝突はほとんどありません)。
  • ディスクに書き込むときに破損が発生するようです。 (それがすべてで発生したときに)それだけで一度か二度起こる - - そこにおよそ95.000 6ギガバイトのファイルを送信する際に、ディスクに書き込まれたこれらの64Kのパッケージのがあるので、どのようにこのことができ、それは

まれな現象であることを意味し起こる?私のハードウェア(悪いラム/ディスク)はこれに責任がありますか?

実際には、書き込み後にディスクから読み込む必要がありますか?正しいバイトがディスクに書き込まれることを100%確かめるためにmemcmp? (オハイオ州の男の子 - どのようなパフォーマンスヒットになる...)

+3

ヒント:ハードウェアに問題があるかどうかを確認するために、2番目または3番目のコンピュータで同じテストを試してください。 – BitTickler

+14

新規ユーザーが直面する最も一般的な問題は次のとおりです。1)ハードウェアの問題。 2)コンパイラのバグ。 3)リンカーのバグ。 4)CPU設計のバグ。 5)正常な人がいないと思われるCPUの設計が間違っている。 6)介入している子供たち。そして7)、非常にまれに、なぜあなたにも、ユーザーのコードのバグを提案しています。 –

+3

@KerrekSB OSがWindowsであれば最も人気のあるバージョンであることを忘れていました;) – BitTickler

答えて

4

私のローカルpc - それはRAMの問題であることが判明しました。 memtest86を実行して見つけました。

私は、実動サーバー上で動作するソフトウェアのコードを変更しました。ディスクから読み込み、正しいバイトが実際に書き込まれたことを確認しました。これらのサーバーは毎日約10TBをディスクに書き込みます。新しいコードを実行してから1週間後にエラーが発生しました。ソフトウェアはこれをもう一度書いて確認することでこれを修正しますが、実際に起こったことはまだ興味深いです。

560000000000000ビットのうち1ビットがディスクに間違って書き込まれました。素晴らしい。

これはおそらくRAMの問題であるかどうかを確認するために、このサーバーでmemtest86を実行することになりますが、ファイルの整合性がより保証されているため、そうでなければハードウェアの問題の

ファイルの整合性が非常に重要な場合(私たちの場合のように)、ハードウェアを100%信頼して読み書き操作を検証しないでください。異常はHWの問題の初期の兆候かもしれません。

関連する問題