реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Буферирование потока данных в файл, Идеи, критика
DeadMoroz
сообщение Nov 3 2012, 13:21
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 3-02-05
Пользователь №: 2 391



Здравствуйте!
Имеется система на Линуксе. Примерная логика части программы такова:
программа получает постоянный поток данных от 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.
Go to the top of the page
 
+Quote Post
kurtis
сообщение Nov 5 2012, 09:44
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205



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

Я бы сначала вообще ничего не писал, а попробовал бы все сделать на баше. Если будет тормозить (а я не думаю что будет тормозить), то тогда уже думать дальше.
Go to the top of the page
 
+Quote Post
DeadMoroz
сообщение Nov 6 2012, 12:15
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 3-02-05
Пользователь №: 2 391



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

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


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

Спасибо за обсуждение!
Go to the top of the page
 
+Quote Post
SyncLair
сообщение Nov 6 2012, 18:22
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 209
Регистрация: 6-01-12
Пользователь №: 69 197



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

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

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


--------------------
Go to the top of the page
 
+Quote Post
sasamy
сообщение Nov 7 2012, 06:45
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 783
Регистрация: 22-11-08
Пользователь №: 41 858



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


И как вы ее решили ? Вообще для этого ИБП используют.
Go to the top of the page
 
+Quote Post
kurtis
сообщение Nov 7 2012, 07:38
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205



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

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

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

Как сделать так, чтоб софт на жестком диске не буферизировал данные, а писал их прямо на физический носитель?
Go to the top of the page
 
+Quote Post
vshemm
сообщение Nov 7 2012, 17:43
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 167
Регистрация: 15-08-07
Пользователь №: 29 803



Цитата(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 с зиллионом циклов чтения/записи + правильная структура хранения данных (т.е. вообще
без ФС). Батарейка/ИБП тоже вариант, да.
Go to the top of the page
 
+Quote Post
SyncLair
сообщение Nov 8 2012, 08:40
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 209
Регистрация: 6-01-12
Пользователь №: 69 197



Цитата(sasamy @ Nov 7 2012, 10:45) *
И как вы ее решили ? Вообще для этого ИБП используют.

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

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

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

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


--------------------
Go to the top of the page
 
+Quote Post
sasamy
сообщение Nov 9 2012, 08:59
Сообщение #9


Знающий
****

Группа: Участник
Сообщений: 783
Регистрация: 22-11-08
Пользователь №: 41 858



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


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

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


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

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 14:42
Рейтинг@Mail.ru


Страница сгенерированна за 0.01434 секунд с 7
ELECTRONIX ©2004-2016