Надежная запись на диск

Тема в разделе "WASM.WIN32", создана пользователем PavPS, 31 мар 2010.

  1. PavPS

    PavPS New Member

    Публикаций:
    0
    Регистрация:
    24 фев 2004
    Сообщения:
    109
    Адрес:
    Russia
    Здравствуйте!
    Есть задача написать некую службу, принимающую данные и складирующую их с возможностью одновременного непоследовательного чтения.
    И есть очень важное требование: при любых не штатных ситуациях (программные, аппаратные сбои) принятые данные должны уцелеть (принятые на данный момент времени). Запись последовательная, непрерывная по времени, частыми, но не большими объемами. Средний боевой вариант - это 1мс по 5 килобайт(фрагмент). Каждый фрагмент самодостаточен.
    ОГРАНИЧЕНИЯ: ОС - WinXP и выше. Бесперебойника нет. Каких либо экстра устройств с резервным питанием и памятью нет.
    Поясню видимые сложности:
    - кэширование файловой системы не всегда сбрасывает буфера на диск.
    - отключение кэша (WRITE_THROUGH или FlushFileBuffers) снижает производительность при частом обращении. В худшем случае программа висит, ожидая завершения обращения к винту.
    - в момент сброса буфферов на диск, так же может произойти отключение питания и файл (БД) будет испорчен и не обязательно в конце.

    Важно добиться наилучшего соотношения надежности, производительности.

    Бегло сделав обзор, ничего конкретного не нашел. Так что, если есть какой материал почитать, покодить, то прошу показать где взять.

    Безусловно, что уровень будь то простое проиложение, драйвер или еще как не важен. Важен результат или максимальное приближение к нему.

    Есть и своя идея как это реализовать, но хотелось бы сперва услышать Ваши.
    Спасибо.
     
  2. Dian

    Dian Member

    Публикаций:
    0
    Регистрация:
    19 июн 2008
    Сообщения:
    222
    1 поставить все-так бесперебойник
    2 использовать СУБД

    Оптимально не только по надежности/производительности, но и цене
     
  3. PavPS

    PavPS New Member

    Публикаций:
    0
    Регистрация:
    24 фев 2004
    Сообщения:
    109
    Адрес:
    Russia
    все же расчитывать на это не приходится.
    а есть какие либо на это расчитанные?? не слишком раздутые под мал-мальские одноядерные процы... и где почитать про их надежность именно в ситуациях выключения питания, BSOD и прочего...
     
  4. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    PavPS
    Необходима надстройка над ядром, тоесть нужно перехватывать шлюзы в IDT и вручную работать с диском. В любом ином случае решение будет крайне не стабильным, даже такой вариан весьма плох - множество ситуаций есть при которых железо не будет выполнять ваш код, например железячный сброс и пр.
     
  5. PavPS

    PavPS New Member

    Публикаций:
    0
    Регистрация:
    24 фев 2004
    Сообщения:
    109
    Адрес:
    Russia
    Спасибо.
    А есть ли какие прототипы, изыскания в эту сторону? Явно ведь тема беспокоила многих...
    Може еще идеи есть?
     
  6. PavPS

    PavPS New Member

    Публикаций:
    0
    Регистрация:
    24 фев 2004
    Сообщения:
    109
    Адрес:
    Russia
    Безусловно я не прошу ссылок из гугла. Может у формучан были подобные изыски?
     
  7. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Без стабильного питания всё равно добиться 100% гарантии сохранности данных невозможно в принципе, но также и повышается вероятность механического повреждения носителя. Ну а насчёт сброса на диск, то Cи функция fflush по-моему это делает. В линукс ещё есть функция fsync. Конечно сбой вполне может произойти в самый неподходящий момент, тут ничего не сделаешь, нужно заново запрашивать блок. Иначе никак.
     
  8. gorodon

    gorodon New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2009
    Сообщения:
    301
    Может, стоит повернуться в сторону ОС реального времени QNX, VxWorks?
     
  9. RET

    RET Well-Known Member

    Публикаций:
    17
    Регистрация:
    5 янв 2008
    Сообщения:
    789
    Адрес:
    Jabber: darksys@sj.ms
    Или на DOS (дешевле на лимон:)
     
  10. PavPS

    PavPS New Member

    Публикаций:
    0
    Регистрация:
    24 фев 2004
    Сообщения:
    109
    Адрес:
    Russia
    Да я бы рад, но сопутствующий софт должен работать как и раньше (всякий там офис, видео, наконец...).

    Вот какой вариант мне пришел на ум:
    Условно, каждый непрерывный промежуток времени записи назовем сессией.
    Считаем разовую посылку 1 килобайт. Период 10мс. (вариант штатный)
    Каждая сессия пишется так:
    Принимаются данные и пишутся в файл без WRITE_THROUGH. Размер файла ограничен размером 300 килобайт или временем 3 секунды. По истечению этого времени выполняется "flush" для этого файла, хэндл закрываем. Переоткрываем на рандом чтение.
    И так далее, пока не наберется цепочка из 100 открытых файлов. Как только набралась, сливаю все файлы в один файл (при этом не закрывая до этого 100 предыдущих мелких файлов), затем сбрасываю на диск буфера от полученного большого файла, жду немного и удаляю предыдущие 100 файлов, и теперь как новый источник предыдущих данных использую уже большой файл.
    Примечание: Каждый записываемый файл (будь то самый первый в 300 кб или дугие), естественно сопровождается контрольной суммой и в будущем инфой для восстановления.

    Такой подход дает возможность потерять (запороть) не более 300 записей. Естественно, период flush и граничный размер могут быть и ниже. Это еще нужно протестировать.
    Т.е. в приближении, любой аппаратный сбой не попортит предыдущие записи.

    Пожалуйста, покритикуйте, может можно улучшить? Илb другой алгоритм?

    PS:Если кто вдруг прочитав мой вариант понял, что изначально вопрос он мой не понял, пожалуйста, подумайте, может у вас теперь есть ответ...
     
  11. RET

    RET Well-Known Member

    Публикаций:
    17
    Регистрация:
    5 янв 2008
    Сообщения:
    789
    Адрес:
    Jabber: darksys@sj.ms
    Может стоит тогда попробовать (я пробовал) создать виртуальный диск в памяти (придется писать драйвер, который будет полностью эмулировать работу например FAT32 и перекачивать все это дело квантами на реальный хард, здесь правда в ядре помню с nonpaged- пулами при эмуляции FAT32 была проблема, но если использовать неболшой объем эмуляции, то и потерь намного меньше). Если чего пиши в ЛС, может тот дров откопаю у себя.
     
  12. PavPS

    PavPS New Member

    Публикаций:
    0
    Регистрация:
    24 фев 2004
    Сообщения:
    109
    Адрес:
    Russia
    Да, но в чем приемущество? Все тот же sync нужно выполнять часто, да и так же придется синкать только модифицированную часть только, а иначе всё встанет в тормозах. Плюс я вижу только один - унифицированность работы, и не обращение внимания на способ записи данных.
     
  13. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    PavPS
    На счёт количества файлов ничего подсказать пока не могу, но по поводу самой записи есть следующие соображения:
    1) Файлы нужно открывать только на запись. (для чтения можно параллельно записывать в другой файл, для которого надёжность не требуется).
    2) Изначально файл нужно чем-то заполнить и записывать не выходя за пределы файла.
    3) Записывать только блоки выровненные по размеру кластера.
    При таких условиях мне кажется не будут модифицироваться структуры описывающие размещение файла, и испорченный может оказаться только записываемый в данный момент блок.
     
  14. PavPS

    PavPS New Member

    Публикаций:
    0
    Регистрация:
    24 фев 2004
    Сообщения:
    109
    Адрес:
    Russia
    Спасибо!
    А не могли бы вы пояснить необходимость пунктов 1 и 2 по подробнее?
     
  15. dag

    dag New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    446
    Аппаратный RAID на него блок резервного питания + ИБП на комп, если данные стоят дороже полученного решения то не вижу причин почему необходимо городить программный огород...
     
  16. PavPS

    PavPS New Member

    Публикаций:
    0
    Регистрация:
    24 фев 2004
    Сообщения:
    109
    Адрес:
    Russia
    dag
    Это требует траты денег на клиентские машины, а значит дорога конкурентам, у которых может все и порушится, но изначально дешево и просто. Увы.
     
  17. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    PavPS
    Второй пункт нужен чтобы системе не требовалось расширять файл и следовательно модифицировать связанные с ним структуры файловой системы. Первый пункт коненчо несколько сомнителен, но мне кажется, что чтение может задержать модифицированый блок в кеше и отложить его фактическию запись на диск. А вот по поводу блоков могу добавить, что для них нужно обязательно сделать нумерацию защищённую каким-то кодом. Причем код должен зависеть от имени файла или какого-то случайного уникльного числа(эго можно в файл положить), чтобы если файл окажется на месте какого-то старого файла, его блоки не могли быть приняты за корректные.
     
  18. dag

    dag New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    446
    PavPS
    если у тебя данных на 10.000.000 и жаба душит потратить 20.000 на то чтобы не допустить их потерю то тогда используй избыточность размерностью которая перекроет твои траты на аппаратную избыточность, возможно стоит поставить ещё 10ток жестких дисков и писать на них в 10 потоков без использования всяких рэйдов ну или рида-соломона или xor обычный по 100 файлам в разных местах 1 - 2 дисков
     
  19. PavPS

    PavPS New Member

    Публикаций:
    0
    Регистрация:
    24 фев 2004
    Сообщения:
    109
    Адрес:
    Russia
    Black_mirror
    Спасибо за пояснения, про размеры блоков. Так и сделаю, если буду применять описанный выше алгоритм...
    вот именно на имени файла я и хотел завязываться. плюс так же и в тело файла писать.
    dag
    Прои избыточность совершенно верно! Скорее всего сразу и надо буде вводить. Только вот она пригодится при порче последнего файла. остальные, успевшие засинкаться должны быть невредимыми.

    Может есть у кого еще идеи по поводу вариаций алгоритма складирования?
     
  20. Twister

    Twister New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    720
    Адрес:
    Алматы
    Зачатки идеи уже озвучили выше:

    Sender отправляет блок информации, временно сохраняет его у себя и ждет от Receiver'а подтверждения о получении. Как только получил - удаляет сохраненный блок. Receiver же должен уведомить Sender'а только после того, как произойдет гарантированная запись информации на диск. Так же Receiver должен помнить, что он что-то принял, чтобы в случае сбоя перезапросить информацию.

    При этом, если архитектура вашего проекта позволяет, то можно запретить Sender'у отправлять последующие блоки до тех пор, пока не придет подтверждение о записи последнего отправленного.