Параллельная обработка файлов: какие рекомендуемые способы?

Это большая проблема сочетания дизайна и кода.

Случай использования
. При наличии множества файлов журналов в диапазоне (2 МБ–2 ГБ) мне нужно проанализировать каждый из этих журналов и применить некоторую обработку, сгенерировав Java POJO.
– Для этой проблемы давайте предположим, что у нас всего 1 файла журнала
. Кроме того, идея состоит в том, чтобы наилучшим образом использовать System. Доступно несколько ядер.

Вариант 1
 – открыть файл (синхронно), прочитать каждую строку, сгенерировать POJOs

FileActor -> read each line -> List<POJO>  

Плюсы: простота понимания
Минусы: последовательный процесс, не использующий преимущества нескольких ядер в системе

Вариант 2
 – открыть файл (синхронно), прочитать N строк (N можно настроить), передать другим участникам для обработки

                                                    / LogLineProcessActor 1
FileActor -> LogLineProcessRouter (with 10 Actors) -- LogLineProcessActor 2
                                                    \ LogLineProcessActor 10

Плюсы Некоторое распараллеливание за счет использования разных акторов для обработки части строк. Актеры будут использовать доступные ядра в системе (? как, может быть?)
Минусы Все еще последовательный, потому что файл читается в последовательном режиме

Вопросы
. Является ли любой из вышеперечисленных вариантов хорошим выбором?
. Есть ли альтернативы получше?

Пожалуйста, предоставьте ценные мысли здесь

Большое спасибо


person daydreamer    schedule 07.05.2015    source источник
comment
Я думаю, что ParallelStreams может подойти для вашей проблемы.   -  person Turing85    schedule 07.05.2015
comment
Или даже storm.apache.org, если вы постоянно получаете новые файлы и хотите действительно надежный конвейер.   -  person Dathan    schedule 07.05.2015
comment
Это решение необходимо установить на клиентские машины, поэтому я не уверен, что Storm выполнимо.   -  person daydreamer    schedule 07.05.2015
comment
Если это файл журнала для анализа, вы, вероятно, также можете использовать logstash   -  person macias    schedule 07.05.2015


Ответы (2)


Почему бы не воспользоваться тем, что уже доступно, и использовать возможности параллельного потока, которые поставляются с jdk 1.8? Я бы начал с чего-то вроде этого и посмотрел, как это работает:

Files.lines(Paths.get( /* path to a log file */ ))
     .parallel() // make the stream work paralell
     .map(YourBean::new) // Or some mapping method to your bean class
     .forEach(/* process here the beans*/);

Вам могут понадобиться некоторые настройки с пулом потоков, потому что paralell() по умолчанию выполняется с использованием ForkJoinPool.commonPool(), и вы не можете настроить его для достижения максимальной производительности, но люди, кажется, находят обходные пути и для этого, кое-что по теме здесь.

person Balázs Édes    schedule 07.05.2015

Альтернатива 2 выглядит хорошо. Я бы просто кое-что изменил. Прочитайте самый большой кусок файла, который вы можете. IO будет проблемой, если вы будете делать это небольшими очередями. Так как файлов несколько, я бы создал актор, чтобы получать имена файлов, читающих конкретную папку. Затем он отправит путь к каждому файлу в папку LogLineReader. Он будет читать большой кусок файла. И, наконец, он будет отправлять каждую строку в LogLineProcessActor. Имейте в виду, что они могут обрабатывать строки не по порядку. Если это не проблема, они будут загружать ваш процессор.

Если вы любите приключения, вы также можете попробовать новый поток akka. 1.0.

person Carlos Vilchez    schedule 08.05.2015