Сравнение инструментов пакетной обработки данных: анализ производительности
В мире Больших Данных ключевую роль в обеспечении оптимальной производительности и эффективности играет правильный выбор инструмента пакетной обработки. В рамках своего проекта я проанализировал несколько наиболее популярных инструментов пакетной обработки, представленных на рынке. Для оценки производительности инструментов я использовал программу подсчета количества слов - стандартную задачу, выполняемую при пакетной обработке. В данном проекте мы рассматриваем такие инструменты, как Apache Spark (на Scala), Apache Hadoop (на Java), Apache Beam (на Java), Polars (на Rust), Pandas и PySpark.
Наш текстовый файл состоит из 10 случайных слов: visionofsid, Scala, Data, Java, Rust, Go, Spark, Sid, Beam и Pandas. Файл .txt содержит 16 миллионов строк, каждая из которых состоит из 10 случайных слов из заданных вариантов. Это означает, что мы применяем пакетную обработку для 160 миллионов слов! Машина, на которой был создан и протестирован этот проект, имеет процессор AMD Ryzen 5 (5600H), 16 ГБ оперативной памяти и графическую карту Nvidia GeForce 1650. Технические характеристики машины, на которой тестируется проект, также могут повлиять на результаты.
Мы рассмотрим различные инструменты, которые мы используем, и соответствующую функциональность в связи с этим проектом, который можно найти по адресу https://github.com/VOSID8/Batch-Processing-Benchmark.
Шаги, необходимые для запуска проекта:
- Установите необходимые окружения, уникальные для каждого инструмента (см. readme на GitHub)
- Перейдите в корневой каталог и запустите compile_project.bat
- После успешной компиляции без ошибок запустите run_project.bat
- Запустив проект, в терминале Вы увидите время, затраченное каждым инструментом.
- Для beam в корневом каталоге есть отдельная папка, перейдите в нее и запустите run_beam.bat, чтобы запустить Beam с помощью Java (Beam нужно запускать отдельно, так как он потребляет довольно много памяти)
Результаты
Вы можете сгенерировать или создать свой собственный текстовый файл. Для этого проекта я сгенерировал текстовый файл из ChatGPT, содержащий 160 миллионов слов. «Встречаемость» каждого слова в файле textinput.txt выглядит следующим образом:
- visionofsid -> 16018400
- Rust -> 16103680
- Scala -> 16008000
- Go -> 15976800
- Spark -> 15979360
- Data -> 15998400
- Sid -> 15964320
- Java -> 16026880
- Beam -> 15965600
- Pandas -> 15958560
Производительность каждого инструмента пакетной обработки измерялась по времени и записывалась как:
- Apache Spark и Scala -> 42.1 сек
- Apache Hadoop и Java -> 105.23 сек
- Apache Spark и Python (PySpark) -> 135.09 сек
- Pandas и Numpy с Python -> 165.21 сек
- Apache Beam и Java -> 371 сек
При каждом новом запуске время, затраченное каждым инструментом, будет меняться. Результаты, отображенные выше, получены в ходе одного случайного запуска, однако при любом количестве запусков с данным текстовым файлом последовательность/ранг производительности этих инструментов остается неизменной.
Обсуждение результатов
Производительность каждого инструмента варьируется в зависимости от его базовой архитектуры, принципов проектирования и конкретной реализации в бенчмарке. Ниже я рассмотрю причины полученных результатов:
1. Apache Spark (Scala)
Apache Spark оказался самым быстрым среди всех инструментов, выполнив задачу всего за 42,10 секунды. Основными причинами такой производительности Spark являются:
- Обработка в памяти: Spark обрабатывает все данные в памяти, значительно сокращая дисковый ввод-вывод по сравнению с другими инструментами, такими как Hadoop.
- Оптимизация Scala: Ядро Spark написано на языке Scala, и использование Scala для реализации обеспечивает минимальные накладные расходы и максимальную совместимость.
- Эффективное выполнение DAG: Планировщик Directed Acyclic Graph (DAG) в Spark оптимизирует выполнение задач, минимизируя перетасовку и максимизируя параллелизм.
Является ли Spark в 100 раз быстрее Hadoop? Утверждение, что Spark в 100 раз быстрее Hadoop, часто относится к конкретным сценариям, связанным с итеративными или in-memory рабочими нагрузками. В этом бенчмарке Spark примерно в 2,5 раза быстрее Hadoop. Такое различие объясняется тем, что дисковая модель MapReduce в Hadoop связана со значительными накладными расходами на ввод-вывод, в то время как обработка в памяти в Spark устраняет большую часть этих задержек. Однако утверждение о «100-кратном» увеличении может быть справедливо в случае больших итерационных алгоритмов. Если набор данных невелик, так что hadoop обрабатывает их только в памяти и не нуждается в дисковой поддержке, spark и hadoop будут работать одинаково. Аналогичным образом, если количество итераций продолжает расти, Hadoop продолжает становиться медленнее.
2. Pandas
Pandas, широко используемый для анализа данных на Python, справился с задачей за 165,21 секунды. Хотя Pandas очень быстр для небольших наборов данных (я тестировал на наборах данных с 10 тыс. строк, и он с большим отрывом обошел все инструменты, включая spark), он не справляется с большими нагрузками из-за:
- Однопоточные операции: Pandas работает в основном на одном ядре, что делает его менее эффективным для задач, требующих большого количества процессора.
- Ограничения памяти: Pandas загружает весь набор данных в память, что может привести к узким местам при работе с большими файлами.
Является ли Pandas лучшим инструментом на базе Python? Pandas - это мощный и универсальный инструмент для манипулирования данными и их анализа на Python. Однако его нельзя назвать универсальной панацеей. Для обработки больших объемов данных или задач, требующих многопоточности, такие инструменты, как Polars или PySpark, часто превосходят Pandas по производительности и результативности.
3. Polars на Rust
Polars, написанный на языке Rust, создан для скорости и эффективности и часто превосходит Pandas в многопоточных сценариях и сценариях с большими объемами данных. В этом бенчмарке Polars потребовалось 106,28 секунды по сравнению с 165,21 секунды Pandas. Такое повышение производительности подчеркивает способность Polars обрабатывать вычисления более эффективно благодаря своей реализации на основе Rust. Однако:
- Работа с текстовыми файлами: В Polars отсутствует встроенная поддержка чтения обычных текстовых файлов. В данной реализации для чтения текстового файла использовалась стандартная библиотека Rust, после чего данные преобразовывались в Polars DataFrame, что добавляло дополнительные накладные расходы.
- Одномашинная природа: Polars работает на одной машине, в то время как Pandas, хотя и тоже одномашинный, пользуется преимуществами развитой экосистемы Python для оптимизации рабочих процессов.
Когда использовать Polars вместо Pandas? Polars идеально подходит для сценариев, требующих:
- Многопоточной обработки данных.
- Критичнности по производительности задач на умеренно больших массивах данных.
- Безопасности и эффективности, надежных гарантий Rust.
Для небольших наборов данных или сценариев, в которых нет необходимости в распределенных вычислениях, Pandas и Polars предлагают простоту и легкость использования. Python делает их идеальными для использования в команде python-разработчиков или в python-среде.
4. Hadoop (Java)
Hadoop, пионер в области распределенной пакетной обработки, показал время 105,23 секунды. На его производительность влияют:
- Обработка на основе дисков: Hadoop в значительной степени полагается на дисковый ввод-вывод, записывая промежуточные результаты на диск во время операций MapReduce.
- Накладные расходы, связанные с установкой заданий: Каждое задание MapReduce несет значительные накладные расходы, связанные с инициализацией и обменом данными между узлами.
Когда следует использовать Hadoop? Hadoop остается надежным выбором для обработки очень больших массивов данных, особенно в средах, где важна надежная отказоустойчивость. Его развитая экосистема поддерживает широкий спектр интеграций, что делает его подходящим для длительных рабочих процессов, ориентированных на пакетную обработку. Однако в современной инженерии данных Hadoop часто заменяется такими инструментами, как Spark, который вдохновлен и наследует многое от самого Hadoop.
5. PySpark
PySpark, Python API для Spark, выполнил задание за 135,09 секунды, что медленнее, чем у Spark на Scala и Hadoop. Это объясняется тем, что:
- Накладные расходы на сериализацию: PySpark использует Python workers, что влечет за собой дополнительные расходы на сериализацию/десериализацию между Python и JVM.
- Накладные расходы на интерпретатор: Интерпретируемая природа Python увеличивает накладные расходы по сравнению с компилируемым исполнением Scala.
Почему стоит выбрать PySpark вместо Spark? Хотя PySpark работает медленнее, чем Spark with Scala, он предлагает более доступный API для разработчиков на Python. Он идеально подходит для команд, уже владеющих языком Python, или для тех случаев, когда требуется гибкость богатой экосистемы Python.
6. Apache Beam (Java)
Apache Beam оказался самым медленным - на выполнение задачи ушло более 300 секунд. Причины:
- Накладные расходы на абстракцию конвейера: Beam предоставляет единую модель для пакетной и потоковой обработки, что добавляет дополнительные уровни абстракции.
- Неоптимальная конфигурация бегуна: Используемый по умолчанию запуск (например, DirectRunner) может быть не оптимизирован для производительности. DirectRunner часто используется для «тестирования» на локальной машине и рассчитан на максимальную эффективность.
Когда использовать Apache Beam? Сила Beam заключается в его переносимости. Если вам нужна унифицированная модель программирования как для пакетной, так и для потоковой обработки на нескольких движках выполнения, Beam - это то, что вам нужно.
Заключение
Выбор инструмента для пакетной обработки зависит от каждого конкретного случая. Для крупномасштабных распределенных рабочих нагрузок больше всего подходитявляется Apache Spark благодаря своей обработке в памяти и эффективному исполнению. Такие инструменты, как Polars и Pandas, могут отлично подойти для небольших нераспределенных рабочих нагрузок. Hadoop и Beam удовлетворяют нишевым требованиям, обеспечивая надежность и переносимость соответственно. Понимание этих компромиссов очень важно.
В продолжении этого блога я буду публиковать статьи, посвященные каждому инструменту, и углубляться в каждый из них. А пока поздравляю Вас с Новым годом!






