Перейти к содержанию
    

Буферирование потока данных в файл

Здравствуйте!

Имеется система на Линуксе. Примерная логика части программы такова:

программа получает постоянный поток данных от FPGA (64 байта/мс * 12 каналов), если при этом установлено соединение (100Мбит изернет) с GUI, то весь поток должен передаваться туда. Если соединения нет, то поток должен писаться в файл на HDD (EXT3\4). Размер файла может быть до 170Гбайт на канал (30 дней), 12 файлов соответственно. Данные из потока должны передаваться последовательно, т.е. перестановка недопустима. В данный момент собираюсь реализовать это следующим образом:

1) для каждого из каналов создать/открыть файл размером 230Мбайт (1 час данных), отобразить файл в память с mmap().

2) писать данные в файл в независимости от состояния соединения с GUI как в ФИФО буфер.

3) если соединение установлено - читать данные из файла как из ФИФО буфера, при этом файл не будет превышать первоначального/текущего размера.

4) если соединения нет, продолжать писать в файл, при достижении максимального размера, увеличивать размер файла опять на 230Мбайт (1 час) и делать mremap().

По этой реализации у меня такие вопросы:

1) будет ли это достаточно быстро работать (mmap|mremap)?

2) насколько это все надежно (питание может пропасть в произвольный момент), как делать сброс буфера на диск (как fflush)?

3) что лучше один файл на 30 дней или куча файлов (например 1 час) с точки зрения надежности и быстродействия?

4) какие есть альтернативные варианты?

 

P.S. Это мой первый проект под Линукс. Подобное ранее не делал. Система на TI OMAPL-138, 128MB DDR, SATA HDD.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. В чем вы видите преимущество использования mmap() перед write()/read()?

2. sync() сливает содержимое буферов ядра, в буфер устройства. Но это никак не влияет на надежность, т.к. если данные попали в буфер устройства, то не факт что они попали на физический носитель.

3. Зависит от способа обработки. Если вам нужно 1 раз построить график по данным и больше ничего не делать, то 1 файл вполне пойдет. Но если вам вдруг нужно будет посмотреть что было 23 мая, в 15 часов 12 минут, то искать вы будете долго. Я бы делал за каждый час.

 

Я бы сначала вообще ничего не писал, а попробовал бы все сделать на баше. Если будет тормозить (а я не думаю что будет тормозить), то тогда уже думать дальше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. В чем вы видите преимущество использования mmap() перед write()/read()?

2. sync() сливает содержимое буферов ядра, в буфер устройства. Но это никак не влияет на надежность, т.к. если данные попали в буфер устройства, то не факт что они попали на физический носитель.

3. Зависит от способа обработки. Если вам нужно 1 раз построить график по данным и больше ничего не делать, то 1 файл вполне пойдет. Но если вам вдруг нужно будет посмотреть что было 23 мая, в 15 часов 12 минут, то искать вы будете долго. Я бы делал за каждый час.

 

Я бы сначала вообще ничего не писал, а попробовал бы все сделать на баше. Если будет тормозить (а я не думаю что будет тормозить), то тогда уже думать дальше.

 

1) читал, что с mmaped файлами работа выполняется быстрее (за счет неиспользования swap в том числе)

2) как же убедиться, что данные на HDD? Если сделать повторное чтение, то тоже нет гарантии, что оно не выполняется из буфера(

 

Спасибо за обсуждение!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2) как же убедиться, что данные на HDD?

1. Найти опции к Linux-у которые сбрасывают кэш прямо на диск или уменьшают размер кеша до 1кбайта

2. Железный вариант -- отмонтировать файловую систему

3. Помнить что есть такие файлы -- pipe

4. Не пользоваться Linux-ом а самому железно писать на диск начиная с такого-то сектора и заканчивая таким-то

5. Как вариант создать самому драйвер устройства который достоверно пишет на ж/д

 

Я одно время был фанатом Linux-а, вот когда задумываешся о таких задачах то думаешь а зачем он тады нужен )). Одна из таких задач -- записать на носитель информацию так, чтобы при отключении питания в ЛЮБОЙ момент записи у нас отставалась возможность прочитать/восстановить новую или старую запись.

Например нууу оооочень важный для системы параметр размером ну в 256 байт.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Одна из таких задач -- записать на носитель информацию так, чтобы при отключении питания в ЛЮБОЙ момент записи у нас отставалась возможность прочитать/восстановить новую или старую запись.

Например нууу оооочень важный для системы параметр размером ну в 256 байт.

 

И как вы ее решили ? Вообще для этого ИБП используют.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. Найти опции к Linux-у которые сбрасывают кэш прямо на диск или уменьшают размер кеша до 1кбайта

2. Железный вариант -- отмонтировать файловую систему

Системный вызов sync() и syncfs() должны это делать.

 

4. Не пользоваться Linux-ом а самому железно писать на диск начиная с такого-то сектора и заканчивая таким-то

Как сделать так, чтоб софт на жестком диске не буферизировал данные, а писал их прямо на физический носитель?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2. sync() сливает содержимое буферов ядра, в буфер устройства. Но это никак не влияет на надежность, т.к. если данные попали в буфер устройства, то не факт что они попали на физический носитель.

 

Увы, данное ложное утверждение повлекло за собой бла бла бла, а не обсуждение. Дело в том,

что sync() не только сбрасывает ядерные буфера в устройство, но еще дает команду устройству

сбросить свои кеши. Но есть два нюанса.

 

Первый - устройство может обмануть и сказать что кеши сброшены, хотя это не так (не говоря

уже о том, что такой команды для данного типа устройств может не быть). Например,

спецификация ATA определяет команду FLUSH_CACHE (0xe7) как mandatory, но это не мешает

дешевым/кривым дискам врать. Плюс, кеши могут сбрасываться в измененном порядке, алгоритмы

внутреннего хранения данных могут накладывать свой отпечаток и т.д. - это тоже важно.

 

Второй нюанс заключается в том, что sync() сбрасывает ядерные буфера на уровне блочных устройств,

а ведь еще могут быть буфера ФС и даже в пользовательском пространстве существует буферизация. Для

решения этой проблемы есть fflush().

 

Таким образом, чтобы данные файла гарантированно оказались на диске (не кривом), нужно выполнить

комбинацию fwrite(); fflush(); fsync(); Несложно заметить, что это не решает проблему ТС, т.к.

пропадание питания во время этой последовательности может привести (и приведет) к порче данных/ФС.

 

Поэтому единственным выходом является использование специальных файловых систем (журналируемых или

log-based). Например, те же ext3/ext4 позволяют журналировать не только метаданные, но и данные,

хоть и с потерей производительности (причем практически двукратной, т.к. данные сначала пишутся

в журнал, а потом еще раз в "обычное" место; впрочем, некоторые ФС - ZFS, Btrfs, .. - используют

COW и данные пишутся один раз, но у них присутствуют другие недостатки). Для совсем "голых" устройств

есть jffs2, logfs и т.д.

 

Разумеется, эти ФС требуют, чтобы диски умели честно сбрасывать свои кеши. Диски с вращающимися

блинами также любят переупорядочивать запись кешей чтобы лишний раз не гонять головки. Но для ФС

порядок записи данных и метаданных очень важен, поэтому с этим тоже нужно бороться (курим маны на

ext3/4, термин barrier).

 

Для SSD (и других девайсов на флеше типа Compact Flash) все еще печальнее из-за статического

wear-leveling`а и прочих наворотов вроде представления данных как сжатого архива внутри девайса

(поэтому на некоторых новых контроллерах SSD рекомендуется не использовать TRIM во избежание

потери производительности/повышения износа).

 

Подобные проблемы не решаются на уровне ОС, т.к. все это делается прозрачно для нее внутри логики

девайсов. Ушлые производители об этом знают, поэтому выпускают линейки "надежных" power-safe дисков

(втридорога, разумеется), а в потребительскую продукцию внедрять новые технологии не спешат ;)

 

В двух словах примерно так...

 

Возвращаясь к вопросам ТС.

1. mmap() не будет быстрее read/write, т.к. все пойдет через один механизм (VFS и page cache).

2. Следует использовать журналируемую ФС и правильные диски. Неплохим стартом будет ext3/4 с

журналированием данных + HDD поддерживающий спецификацию ATA8 и выше.

3. Лучше делать много файлов из расчета что при сбое потеряются данные последнего файла. Т.е. если

вы готовы потерять последнюю минуту - делайте файлы на каждую минуту на каждый канал. Если вы вообще

не готовы терять данные - тоже решается, но сложнее.

Также старайтесь всегда дописывать данные в файл (append) а не писать в середину.

 

Вопрос как записать "важный для системы параметр размером ну в 256 байт" чаще решается иными методами.

Например, "голый" (т.е. без внутренней логики) NAND + logfs, а если параметр небольшой - то EEPROM

или вообще FRAM с зиллионом циклов чтения/записи + правильная структура хранения данных (т.е. вообще

без ФС). Батарейка/ИБП тоже вариант, да.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И как вы ее решили ? Вообще для этого ИБП используют.

Да да я шас начальству скажу давайте в каждый прибор ИБП поставим :biggrin:

 

Просто надо писать в два места с контрольной суммой и ставить метку времени.

 

Вопрос как записать "важный для системы параметр размером ну в 256 байт" чаще решается иными методами.

Например, "голый" (т.е. без внутренней логики) NAND + logfs, а если параметр небольшой - то EEPROM

или вообще FRAM с зиллионом циклов чтения/записи + правильная структура хранения данных (т.е. вообще

без ФС). Батарейка/ИБП тоже вариант, да.

Грамотный и развёрнуты ответ. А важный параметр имеенно так и писался во фрам. Без всяких ФС и спец структура для хранения данных.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да да я шас начальству скажу давайте в каждый прибор ИБП поставим :biggrin:

 

Что это за прибор с SATA диском - на микроконтроллере еще наверно :lol: помоему задача высосана даже не из пальца.

 

Грамотный и развёрнуты ответ. А важный параметр имеенно так и писался во фрам. Без всяких ФС и спец структура для хранения данных.

 

Что же вам помешало использовать FRAM в Linux ? ИБП - это единственный вариант не терять данные вообще и при этом не превращать скоростные носители с UDMA в большую дискету (по скорости работы с ним).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...