LINUX.ORG.RU

Запись в большое число файлов


0

1

Если задача парсить гигабайты данных построчно, и, в зависимости от определенных условий, каждая строка должна быть записана в определенный файл. Суть в том, что выходных файлов может быть порядка 100 000 и более. Как правильные люди решают подобные задачи? Как наиболее оптимально писать в множество файлов, чтобы не было тормозов? Сейчас уже реализован самый тупой способ, каждый файл открывается, производится запись, закрывается. Хотелось бы оптимизировать. Вижу следующие пути: 1. Использовать некий пул файлов. Файлы в этом пуле держать открытыми. 2. Записывать в файлы не построчно, а в ходе работы программы накопить некоторый объем, и раз, скажем, в мегабайт скидывать на диск.

Еще варианты? Или чем плохи предложенные?


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

тока открывай файл на добавление - тока когда нужно первый раз писать в этот файл

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

ну если лимит на fd 1000
то открываеш на запись до 1000 файлов - а когда лимит исчерпан - то закрываеш тот fd в который меньше всего было записей

ae1234 ★★
()

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

ну или скажем - если и делать такой кеш - то для неоткрытых файлов

тут еще вопрос - как данные поступают со входа - нонстоп потоком иль порциями

ae1234 ★★
()
Ответ на: комментарий от ae1234

Поток идет порциями по 5 метров. И каждые пять метров отработать это 0.5 секунды. Но когда отработает так гигов 10, т.е. число файлов становится большим, время обработки каждого файла деградирует, порой до минут. И деградирует за счет медленного сброса на хард.

tanenn
() автор топика
Ответ на: комментарий от tanenn

не - имхо чтото нето

с чего ты взял что деградирование идет от числа файлов ?
или это проверка на чистом с 0ля форматированным диском ?

ведь в новь поступающем потоке - примерно такое же содержание fd

скажи точнее как сделано щас ?

и какая файлова система - и как файлы распологаються

тут еще хитрости работы с директориями нужны - длинные директории плохо обрабатываються
поступают как в сквиде - 2 уровневые дериктории
/0/0/00100
/0/0/00101
файлы

ae1234 ★★
()
Ответ на: комментарий от ae1234

5метровый файл это 100к строк. Пишется в среднем в 3-5 тысяч файлов. В выходном каталоге есть деление на подкаталоги. Например, dir/дата/in и dir/дата/out. В in и out лежит по 1500-2500 файлов в среднем. Когда накапливается в подкаталогах выходного каталога тысяч 40 файлов, начинаются лаги. Файловая система ext4.

Проверка не на чистом диске само собой. Просто если выходной каталог очищать и заново запускать прогу, то примерно на 40к файлов опять начинается затык.

tanenn
() автор топика
Ответ на: комментарий от ae1234

Сервак боевой( Нельзя рейзер туда замутить. И новый винт воткнуть тоже не вариант. Больше уровней может поможет кстати.

tanenn
() автор топика
Ответ на: комментарий от tanenn

дак - на любой машине тест сделать
рандом генератор - в качестве входных данных и вперед

а насчет рейзера - в стародавние времена ext2 рейзер был куда щустрее на балших директориях

файлы страшно фрагментированными будут - и изза того что постоянно дергают структуру fs - журнал ее будет тормазить сильно

ae1234 ★★
()
Ответ на: комментарий от arhibot

Экспериментировали на кучаядерном серваке с многооперативой и хитрорейдами) Это не суть. Суть в том, что есть конские объемы данных, по которым необходимо делать выборки. Проверили производительность топ-20 наверное современных баз данных. Но не хватает производительности, без алгоритмических трюков или закупки нового железа.

Есть некие данные в сыром виде. Если их просто хранить в базе как есть, то получается по 25млн записей в сутки. И некоторые нестандартные выборки могут занимать сутки. Было решено заранее парсить сырые данные, и тем самым готовить маленькие порции отчетов. Это тот этап, что в топике сем описан. Далее эти файлы архивируются и блобами записываются с базу. При выборке же блобы достаются, разархивируются, грепаются и т.п. В общем и целом схема выглядит довольно мутной и не очевидной, но такие хитрости ускорили время выполнения запроса с суток до 20 секунд.

tanenn
() автор топика
Ответ на: комментарий от tanenn

а почему сразу тогда неготовить блоб ?

скажем процесс - собирает в 1-8 гигабайтный буффер у себя данные - как собирет
переключаеться на второй буффер - а первый отдает своему второму треду - который делает этот микроотчет и записывает его в базу блобом ?

ae1234 ★★
()
Ответ на: комментарий от ae1234

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

ae1234 ★★
()

> Еще варианты?

Перед оптимизацией тебе нужно:

1) определиться, что именно ты собираешься оптимизировать (скорость открытия/закрытия, скорость записи, потребление ресурсов, етц)

2) сделать нужные измерения

3) определиться с границами, которые нужно достигнуть

4) (самое главное) заняться профилировкой. Это может быть либо спец-тул, либо вы можете дополнить вашу программу средствами снятия нужный метрик

5) оптимизировать нужные фрагменты, пересмотреть варианты решений/имплементации, и далее весь процесс повторить с начала

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

ky-san
()
Ответ на: комментарий от tanenn

> Проверка не на чистом диске само собой. Просто если выходной каталог очищать и заново запускать прогу, то примерно на 40к файлов опять начинается затык.

Ограничь количество файлов в директории до нескольких тысяч.

Пусть, у тебя файлы с именами tanenn, john, jake, hank - делай такую структуру j/o/john, j/a/jake, h/a/hank или jo/john, ja/jake, ha/hank

ky-san
()

40 тыс. файлов в разных каталогах не так уж много. Может у вас просто к этому времени идёт затык по кешированию, всякие умный RAID имеют свои кеши и т.д. Если программу приостановить на несколько минут, а потом продолжить, не удаляя эти 40 тыс., скорость по прежнему будет низкой?

Посмотрите strace'ом работу программы, в иделе, там не должно быть других syscall'ов кроме open(), write(), close(). Пул открытых файлов это хорошо, но если, допустим, вам доступно всего 1000 дескрипторов, а у вас 5 Мбайт пишутся в 3000 файлов, то, ИМХО, толку от него не будет. Уж лучше эти 5 Мбайт целиков в ОЗУ рассортировать, а потом последовательно писать.

mky ★★★★★
()

ИМНО копить надо в памяти, и сбросы делать как можно реже. Своп обычно довольно внятно работает. КРоме того развести файлы по директориям, так что бы в одной директории (на одном уровне) было не оч. большое кол-во записей.

Вообще работа с большим кол-м файлом дело мутное, у меня после оптимизации при профилировании выяснилось, что основноной затык идет на расчете размеров каталогов с результатами расчетов, а до этого оно затыкалось на чтении времени посл изменения файла - вроде фигня, но таких операций было аццки много...

AIv ★★★★★
()

Как я понял задача серьезная, тогда может просто взять серьезное железо, например:

Установить 64 битную ОС, оперативки 24 гига ( считай, что буфер для записи файлов это 20 гб ), распараллелить все( 1 поток читает с винта, 7 пишут) и сохранять на райд из 2-х PCI SSD.

Я почему то уверен, что если все правильно написать, то проблем со скоростью не будет.

AoD314
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.