Рекомендации по обработке больших объемов данных

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

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

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

11 ответов


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

Я большой фанат 'memory mapped i / o', иначе 'прямой байт буфер'. В Java они называются Сопоставленные Буферы Байтов являются частью java.НИО. (В основном этот механизм использует подкачку виртуальной памяти ОС система для "сопоставления" ваших файлов и представления их программно в виде байтовых буферов. ОС будет управлять перемещением байтов на / из диска и памяти автоматически и очень быстро.

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

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

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

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


возможно, вы захотите взглянуть на записи в Широкий Проект Finder (выполните поиск в google для "широкий finder" java).

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


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

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

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

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

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

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

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

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

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


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

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

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

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

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


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

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


вы действительно не дали нам достаточно информации, чтобы помочь вам. Вы должны загрузить каждый файл в своем entiretly для того, чтобы обработать его? Или вы можете обрабатывать его строка за строкой?

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


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

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


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


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


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


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