2016-08-18 4 views
6

Я написал протокол передачи на основе UDP, используя C++ 11 (VS2013). Он быстро вспыхивает и отлично работает в 99,9% случаев.Неверные байты иногда записываются на диск. Проблемы с оборудованием?

enter image description here

Но я наблюдал несколько раз, что неправильные байты записаны на диск (Samsung 250 GB SSD 850 EVO) - или по крайней мере так кажется.

Вот в основном то, что когда-то происходит, когда я передаю тестовый файл 6GB:

  1. Файл разбит на более мелкие datapackages UDP - 64K в размере. (Сетевой уровень отключает и повторно собирает дейтаграммы UDP в более крупный пакет).
  2. Клиент отправляет datapackage (udp) на сервер - полезная нагрузка зашифровывается с использованием AES256 (OpenSSL) и содержит метаданные данных +. Полезная нагрузка также содержит хэширование SHA256 всей полезной нагрузки - в качестве дополнительной проверки целостности пополнить контрольную сумму UDP.
  3. Сервер получает пакет данных, отправляет пакет «ACK» обратно клиенту, а затем вычисляет хеш SHA256. Хэш идентичен хеш-клиенту - все хорошо
  4. Затем сервер записывает данные пакета на диск (используя fwrite вместо потоков из-за огромных различий в производительности). Сервер обрабатывает только один пакет за раз - и каждый файл-указатель имеет защитник мьютекса, который защищает его от закрытия другим рабочим потоком, который закрывает файловые указатели, которые были неактивны в течение 10 секунд.
  5. Клиент получает пакеты UDP «ACK» и повторно отправляет пакеты, которые не были выделены (что означает, что они не сделали это). Скорость входящих пакетов ACK контролирует скорость отправки клиента (например, управление перегрузкой/дросселирование). Порядок пакетов, полученных на сервере, не имеет значения, поскольку каждый пакет содержит значение Position (где в файле должны быть записаны данные).

После того, как весь файл будет передан я полный SHA256 хэш файла 6GB на сервере и на клиенте, но к моему террору я наблюдал два раза за последние несколько дней, что хэш НЕ (при выполнении приблизительно 20 тестовых передач).

После сравнения файлов в Beyond Compare я обычно обнаруживаю, что есть один или два бита (в файле объемом 6 ГБ), что неверно на сервере.

Смотрите скриншот ниже: enter image description here

код

Сервер - вызывается после того, как 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 
} 

Так, чтобы подвести итог:

  • полукокса * была правильной в памяти на сервер - в противном случае серверы SHA256 Hash провалились - правильно? (хеш-столкновение с sha256 крайне маловероятно).
  • Коррупция, похоже, происходит при записи на диск. Поскольку существует около 95,000 этих 64k пакетов, записанных на диск при отправке 6GB файла - и это происходит только один раз или два раза (если это вообще произойдет) - означает, что это редкое явление

Как это может случиться? Является ли мое оборудование (плохой ram/диск) виноватым в этом?

Нужно ли мне читать с диска после написания и т. Д. memcmp, чтобы быть на 100% уверенным, что правильные байты записываются на диск? (О, мальчик - какое ударное действие получится ...)

+3

Совет. Попробуйте выполнить те же тесты на втором/третьем компьютере, чтобы узнать, есть ли у вас проблемы с аппаратным обеспечением. – BitTickler

+14

Наиболее распространенными проблемами, с которыми сталкиваются новые пользователи, являются: 1) Проблемы с оборудованием. 2) Ошибки в компиляторе. 3) Ошибки в компоновщике. 4) Ошибки в дизайне ЦП. 5) Плохая конструкция ЦП, которую не придумал бы здравомыслящий человек. 6) Те, кто мешает детям. И 7), но очень редко и почему вы даже предлагаете это, ошибки в коде пользователя. –

+3

@KerrekSB Вы забыли обвинить ОС, самую популярную версию, если это окна;) – BitTickler

ответ

4

На моем локальном компьютере - оказалось, что это проблема с ОЗУ. Обнаружили, запустив memtest86.

Тем не менее - я изменил код нашего программного обеспечения, который запускается на наших производственных серверах, - чтобы он читал с диска, чтобы убедиться, что на самом деле написаны правильные байты. Эти серверы пишут около 10 ТБ на диск каждый день - и через неделю после запуска нового кода ошибка произошла один раз. Программное обеспечение исправляет это путем написания и проверки снова, но все же интересно видеть, что это действительно произошло.

1 бит из 560000000000000 бит был записан неправильно на диск. Удивительно.

Я, скорее всего, запустил memtest86 на этом сервере позже, чтобы узнать, не является ли это проблемой ОЗУ, - но меня больше не беспокоит этого, поскольку целостность файла более или менее обеспечена, а серверы не показывают никаких признаков проблем с оборудованием.

Таким образом, если целостность файлов чрезвычайно важна для вас (например, для нас), то не доверяйте своему оборудованию на 100% и проверяйте операции чтения/записи. Аномалии могут быть ранним признаком проблем HW.

Смежные вопросы