Рекомендации по обработке больших объемов данных - PullRequest
6 голосов
/ 18 сентября 2008

Итак, у меня есть «большое» количество «очень больших» ASCII-файлов числовых данных (всего гигабайт), и моя программа должна будет последовательно обрабатывать их полностью хотя бы один раз.

Какой-нибудь совет по хранению / загрузке данных? Я думал о преобразовании файлов в двоичный файл, чтобы сделать их меньше и быстрее загружать.

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

Ответы [ 11 ]

6 голосов
/ 18 сентября 2008

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

Я большой поклонник 'сопоставления памяти ввода / вывода' , или 'прямых байтовых буферов' . В Java они называются Mapped Byte Buffers являются частью java.nio. (По сути, этот механизм использует систему подкачки виртуальной памяти ОС, чтобы «отобразить» ваши файлы и представить их программно в виде байтовых буферов. ОС будет управлять перемещением байтов на / с диска и памяти автоматически и очень быстро.

Я предлагаю этот подход, потому что а) он работает для меня, и б) он позволит вам сосредоточиться на вашем алгоритме и позволит JVM, ОС и аппаратному обеспечению заниматься оптимизацией производительности. Все часто они знают, что лучше, чем мы, смиренные программисты. ;)

Как бы вы использовали MBB в вашем контексте? Просто создайте MBB для каждого из ваших файлов и читайте их по своему усмотрению. Вам нужно будет только сохранить свои результаты. .

Кстати: сколько данных вы имеете в ГБ? Если оно превышает 3-4 ГБ, это не сработает для вас на 32-разрядной машине, поскольку реализация архитектуры MBB ответственно в области адресуемой памяти в архитектуре платформы. 64-разрядная машина и операционная система приведут вас к 1 ТБ или 128 ТБ сопоставляемых данных.

Если вы думаете о производительности, то знайте Кирка Пеппердина (несколько известного гуру Java-производительности). Он связан с веб-сайтом www.JavaPerformanceTuning.com, на котором есть еще несколько деталей MBB: NIO Советы по повышению производительности и другие вопросы, связанные с производительностью Java.

2 голосов
/ 18 сентября 2008

Возможно, вы захотите взглянуть на записи в Wide Finder Project (выполните поиск в Google для "wide finder" java ).

Wide finder включает в себя чтение множества строк в файлах журналов, поэтому посмотрите на реализации Java и посмотрите, что сработало, а что не сработало.

1 голос
/ 18 сентября 2008

Это во многом зависит от данных в файле. Большие мэйнфреймы давно выполняют последовательную обработку данных, но обычно они не используют произвольный доступ к данным. Они просто тянут это по очереди и обрабатывают так много, прежде чем продолжить.

Для произвольного доступа часто лучше создавать объекты с помощью кэширующих оболочек, которые знают, где в файле находятся данные, которые они должны построить. При необходимости они считывают эти данные и строят сами. Таким образом, когда памяти мало, вы можете просто начать убивать вещи, не беспокоясь о невозможности вернуть их позже.

1 голос
/ 18 сентября 2008

Без какого-либо дополнительного понимания того, что за обработка происходит, вот некоторые общие мысли о том, когда я проделал аналогичную работу.

  1. Напишите прототип вашего приложения (возможно, даже «один, чтобы выбросить»), который выполняет произвольную операцию с вашим набором данных. Посмотрите, как быстро это идет. Если самая простая, самая наивная вещь, о которой вы можете подумать, это приемлемо быстро, не беспокойтесь!

  2. Если наивный подход не работает, рассмотрите возможность предварительной обработки данных, чтобы последующие прогоны выполнялись в течение приемлемого промежутка времени. Вы упоминаете о необходимости «прыгать» в наборе данных совсем немного. Есть ли способ предварительно обработать это? Или одним из этапов предварительной обработки может быть создание еще большего количества данных - индексных данных, которые обеспечивают точную байтовую информацию о местонахождении критических, необходимых разделов вашего набора данных. Затем ваш основной прогон обработки может использовать эту информацию для прямого перехода к необходимым данным.

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

Не «загружать все в память». Просто выполните доступ к файлу и позвольте кешу страниц операционной системы решить, когда вы действительно извлечете данные из памяти.

1 голос
/ 18 сентября 2008

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

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

Чтобы ответить на ваши вопросы по порядку:

Должен ли я загрузить все в память одновременно?

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

Если нет, то является ли открытие хорошим способом частичной загрузки данных?

BufferedReaders / etc является самым простым, хотя вы можете заглянуть глубже в FileChannel / etc, чтобы использовать отображенный в памяти ввод-вывод для одновременного просмотра окон данных.

Каковы некоторые советы по эффективности, связанные с Java?

Это действительно зависит от того, что вы делаете с самими данными!

0 голосов
/ 20 сентября 2008

Если вам нужен доступ к данным более одного раза, загрузите их в базу данных. Большинство баз данных имеют какую-то утилиту массовой загрузки. Если все данные могут поместиться в памяти, и вам не нужно хранить их или обращаться к ним так часто, вы, вероятно, можете написать что-то простое на Perl или на вашем любимом языке сценариев.

0 голосов
/ 18 сентября 2008

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

0 голосов
/ 18 сентября 2008

Я настоятельно рекомендую использовать регулярные выражения и искать «новый» пакет IO nio для более быстрого ввода. Тогда он должен идти так быстро, как вы можете ожидать, что гигабайты данных будут отправлены.

0 голосов
/ 18 сентября 2008

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

0 голосов
/ 18 сентября 2008

Я считаю Informatica исключительно полезным инструментом для обработки данных. Хорошей новостью является то, что более поздние версии даже допускают преобразования Java. Если вы имеете дело с терабайтами данных, возможно, пришло время найти лучшие в своем классе инструменты ETL.

Я предполагаю, что вы хотите что-то сделать с результатами обработки здесь, например, сохранить это где-нибудь.

...