Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Буферирование потока данных в файл
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > Linux
DeadMoroz
Здравствуйте!
Имеется система на Линуксе. Примерная логика части программы такова:
программа получает постоянный поток данных от 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.
kurtis
1. В чем вы видите преимущество использования mmap() перед write()/read()?
2. sync() сливает содержимое буферов ядра, в буфер устройства. Но это никак не влияет на надежность, т.к. если данные попали в буфер устройства, то не факт что они попали на физический носитель.
3. Зависит от способа обработки. Если вам нужно 1 раз построить график по данным и больше ничего не делать, то 1 файл вполне пойдет. Но если вам вдруг нужно будет посмотреть что было 23 мая, в 15 часов 12 минут, то искать вы будете долго. Я бы делал за каждый час.

Я бы сначала вообще ничего не писал, а попробовал бы все сделать на баше. Если будет тормозить (а я не думаю что будет тормозить), то тогда уже думать дальше.
DeadMoroz
Цитата(kurtis @ Nov 5 2012, 19:44) *
1. В чем вы видите преимущество использования mmap() перед write()/read()?
2. sync() сливает содержимое буферов ядра, в буфер устройства. Но это никак не влияет на надежность, т.к. если данные попали в буфер устройства, то не факт что они попали на физический носитель.
3. Зависит от способа обработки. Если вам нужно 1 раз построить график по данным и больше ничего не делать, то 1 файл вполне пойдет. Но если вам вдруг нужно будет посмотреть что было 23 мая, в 15 часов 12 минут, то искать вы будете долго. Я бы делал за каждый час.

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


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

Спасибо за обсуждение!
SyncLair
Цитата(DeadMoroz @ Nov 6 2012, 16:15) *
2) как же убедиться, что данные на HDD?

1. Найти опции к Linux-у которые сбрасывают кэш прямо на диск или уменьшают размер кеша до 1кбайта
2. Железный вариант -- отмонтировать файловую систему
3. Помнить что есть такие файлы -- pipe
4. Не пользоваться Linux-ом а самому железно писать на диск начиная с такого-то сектора и заканчивая таким-то
5. Как вариант создать самому драйвер устройства который достоверно пишет на ж/д

Я одно время был фанатом Linux-а, вот когда задумываешся о таких задачах то думаешь а зачем он тады нужен )). Одна из таких задач -- записать на носитель информацию так, чтобы при отключении питания в ЛЮБОЙ момент записи у нас отставалась возможность прочитать/восстановить новую или старую запись.
Например нууу оооочень важный для системы параметр размером ну в 256 байт.
sasamy
Цитата(SyncLair @ Nov 6 2012, 22:22) *
Одна из таких задач -- записать на носитель информацию так, чтобы при отключении питания в ЛЮБОЙ момент записи у нас отставалась возможность прочитать/восстановить новую или старую запись.
Например нууу оооочень важный для системы параметр размером ну в 256 байт.


И как вы ее решили ? Вообще для этого ИБП используют.
kurtis
Цитата
1. Найти опции к Linux-у которые сбрасывают кэш прямо на диск или уменьшают размер кеша до 1кбайта
2. Железный вариант -- отмонтировать файловую систему

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

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

Как сделать так, чтоб софт на жестком диске не буферизировал данные, а писал их прямо на физический носитель?
vshemm
Цитата(kurtis @ Nov 5 2012, 13:44) *
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 дисков
(втридорога, разумеется), а в потребительскую продукцию внедрять новые технологии не спешат wink.gif

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

Возвращаясь к вопросам ТС.
1. mmap() не будет быстрее read/write, т.к. все пойдет через один механизм (VFS и page cache).
2. Следует использовать журналируемую ФС и правильные диски. Неплохим стартом будет ext3/4 с
журналированием данных + HDD поддерживающий спецификацию ATA8 и выше.
3. Лучше делать много файлов из расчета что при сбое потеряются данные последнего файла. Т.е. если
вы готовы потерять последнюю минуту - делайте файлы на каждую минуту на каждый канал. Если вы вообще
не готовы терять данные - тоже решается, но сложнее.
Также старайтесь всегда дописывать данные в файл (append) а не писать в середину.

Вопрос как записать "важный для системы параметр размером ну в 256 байт" чаще решается иными методами.
Например, "голый" (т.е. без внутренней логики) NAND + logfs, а если параметр небольшой - то EEPROM
или вообще FRAM с зиллионом циклов чтения/записи + правильная структура хранения данных (т.е. вообще
без ФС). Батарейка/ИБП тоже вариант, да.
SyncLair
Цитата(sasamy @ Nov 7 2012, 10:45) *
И как вы ее решили ? Вообще для этого ИБП используют.

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

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

Цитата(vshemm @ Nov 7 2012, 21:43) *
Вопрос как записать "важный для системы параметр размером ну в 256 байт" чаще решается иными методами.
Например, "голый" (т.е. без внутренней логики) NAND + logfs, а если параметр небольшой - то EEPROM
или вообще FRAM с зиллионом циклов чтения/записи + правильная структура хранения данных (т.е. вообще
без ФС). Батарейка/ИБП тоже вариант, да.

Грамотный и развёрнуты ответ. А важный параметр имеенно так и писался во фрам. Без всяких ФС и спец структура для хранения данных.
sasamy
Цитата(SyncLair @ Nov 8 2012, 12:40) *
Да да я шас начальству скажу давайте в каждый прибор ИБП поставим biggrin.gif


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

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


Что же вам помешало использовать FRAM в Linux ? ИБП - это единственный вариант не терять данные вообще и при этом не превращать скоростные носители с UDMA в большую дискету (по скорости работы с ним).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.