большой объем данных во многих текстовых файлах - как процесс?

У меня есть большие объемы данных (несколько терабайт) и накапливаются... Они содержатся во многих плоских текстовых файлах с разделителями табуляции (каждый около 30 МБ). Большая часть задачи включает чтение данных и агрегирование (суммирование/усреднение + дополнительные преобразования) по наблюдениям/строкам на основе ряда операторов предикатов, а затем сохранение выходных данных в виде файлов text, HDF5 или SQLite и т. д. Я обычно использую R для таких задач, но я боюсь, что это может быть немного большим. Некоторые решения-кандидаты

  1. напишите все это в C (или Fortran)
  2. импорт файлов (таблиц) в реляционная база данных напрямую и затем вытащите куски в R или Python (некоторые преобразования не поддается для чистых решений SQL)
  3. напишите все это на Python

будет ли (3) плохой идеей? Я знаю, что вы можете обернуть подпрограммы C в Python, но в этом случае, поскольку нет ничего вычислительно запретительного (например, процедуры оптимизации это требует многих итеративных вычислений), я думаю, что ввод-вывод может быть таким же узким местом, как и само вычисление. Есть ли у вас какие-либо рекомендации относительно дальнейших соображений или предложений? Спасибо

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

8 ответов


(3) не обязательно плохая идея-Python упрощает обработку файла "CSV" (и, несмотря на то, что C означает запятую, tab как разделитель так же прост в обращении) и, конечно, получает примерно столько же пропускной способности в I/O ops, как и любой другой язык. Что касается других рекомендаций, numpy, помимо быстрого вычисления (которое вам может не понадобиться в соответствии с вашими утверждениями), предоставляет очень удобные, гибкие многомерные массивы, которые могут быть очень удобны для ваших задач; и стандартная библиотека модуль multiprocessing позволяет использовать несколько ядер для любой задачи, которую легко распараллелить (важно, так как почти каждая машина в наши дни имеет многоядерные; -).


хорошо, так что просто быть другим, почему бы не R?

  • вы, кажется, знаете R, поэтому вы можете быстро добраться до рабочего кода
  • 30 Мб на файл не большой на стандартной рабочей станции с несколькими ГБ оперативной памяти
  • на read.csv() вариант read.table() может быть очень эффективным, если вы укажете типы столбцов через colClasses аргумент: вместо guestimating типов для преобразования, они будут обрабатываться эффективно
  • узким местом здесь является ввод-вывод с диска и это то же самое для каждого языка
  • R имеет многожильные для настройки параллельной обработки на машинах с несколькими ядрами (похоже на многопроцессорную обработку Python)
  • если вы хотите использовать "смущающе параллельную" структуру проблемы, R имеет несколько пакетов, которые хорошо подходят для параллельных задач данных: например. снег и foreach можно каждое раскрыть на как раз одной машине, или на наборе networked машины.

посмотреть дискотека. Это легкий распределенный движок MapReduce, написанный примерно в 2000 строках Erlang, но специально разработанный для разработки Python. Он поддерживает не только работу с вашими данными, но и надежное хранение репликации. Они только что выпустили версию 0.3, которая включает в себя индексацию и слой базы данных.


с терабайтами вы все равно захотите распараллелить свои чтения на многих дисках; так что можно перейти прямо в Hadoop.

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


Мне повезло использовать R с Hadoop на эластичной карте Amazon. С EMR вы платите только за компьютерное время, которое вы используете, и AMZN заботится о вращении и вращении экземпляров. Именно то, как структурировать задание в EMR, действительно зависит от того, как структурирован рабочий процесс анализа. Например, все ли записи, необходимые для одного задания, содержатся полностью внутри каждого csv или вам нужны биты из каждого csv для завершения анализа?

вот некоторые ресурсы, которые вы может оказаться полезным:

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

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


Если у вас есть кластер машин, вы можете распараллелить свое приложение с помощью Hadoop Mapreduce. Хотя Hadoop написан на Java, он также может запускать Python. Вы можете проверить следующую ссылку для указателей при распараллеливании кода -PythonWordCount


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

в случаях (1) и (3) вам нужно обрабатывать файлы каждый раз (что было указано ранее как наиболее трудоемкое/ресурсоемкое), если вы не найдете способ сохранить результаты и обновить их новыми файлами.

вы можете использовать R для обработки файлов из csv, для пример, база данных SQLite.


да. Ты прав! I / O будет стоить большую часть вашего времени обработки. Я не предлагаю вам использовать распределенные системы, такие как Hadoop, для этой задачи.

ваша задача может быть выполнена на скромной рабочей станции. Я не эксперт Python, я думаю, что он поддерживает асинхронное программирование. В F#/.Net платформа имеет хорошую поддержку для этого. Однажды я выполнял работу по обработке изображений, загружая 20K изображений на диск и преобразовывая их в векторы объектов только за несколько минут параллельно.

В общем, загружайте и обрабатывайте данные параллельно и сохраняйте результат в памяти (если маленький), в базе данных (если большой).