Big Data как концепт довольно понятна, но из-за того, что она включает в себя множество процессов, сложно сказать, с чего именно нужно начать изучение. Как хранятся файлы? Или как получать эти файлы? А может, сразу — как анализировать данные? О своём опыте работе с Big Data и почему Spark лучше, чем Hadoop MapReduce в обработке данных, рассказывает Эмилия Межекова, ETL-developer в Luxoft.
Мой первый опыт
До 2020 года я, как и большинство Python-девелоперов, работала с привычным стеком Python+Django+РСУБД. В этом стеке для меня было многое понятно. Транзакции, обработка на стороне бэкенда, вывод его на фронтенд к пользователю, как РСУБД хранит данные, как подчищает от мусора, какие существуют трюки для оптимизации поиска данных и подобные вещи.
В 2020-м я получила должность ETL-девелопера (от англ. Extract, Transform, Load) в Luxoft. Изначально название этой позиции мне ни о чём не говорило, я только знала, что это связано с Big Data. Этот термин мне был лишь немного знаком, я никогда не интересовалась данным направлением, и мне казалось, что там очень много математики, графиков, расчёта вероятности и так далее. Как оказалось, в Big Data не только данные большие, но и инфраструктура, и найдутся места, где можно применить свои знания и без математики.
Сейчас я работаю в проекте, занимающемся количественными хедж-фондами — инвестиционными фондами, ориентированными на максимизацию доходности участников. Мы анализируем много данных из разных источников: соцсети, новости, транзакции и так далее. На их основе формируются «сигналы» для принятия решения о продаже или покупке акций. В основном я взаимодействую с фреймворком Spark, он служит для обработки данных (you must be joking!). Сначала я использовала его для манипулирования небольшими файлами и добавления определённой логики, это было довольно просто и понятно. Но когда меня пустили на прод, и файлы стали размером под сотни гигабайтов, а обработка этих файлов занимала всего несколько минут, мне стало интересно, как же шестерёнки крутятся внутри.
Я изучала всё довольно сумбурно. Так как я работала немного с Pandas, то команды Spark не казались сложными, потому что они в чём-то схожи. Я изначально читала про него, но очень часто авторы ссылались на Hadoop MapReduce и внесённые по сравнению с этой моделью улучшения. Поэтому я начала изучать Hadoop MapReduce. В итоге у меня есть представление о том и другом направлении, поэтому я решила рассказать, что лучше подходит для обработки данных.
Структура Big Data
Выше показана экосистема больших данных и примеры инструментов, которые можно использовать для каждой группы. Выглядит устрашающе, но нам нужно разобраться лишь в том, как именно данные обрабатываются, — вернее, рассмотреть два варианта, как это можно сделать с помощью следующих фреймворков: Hadoop MapReduce и Apache Spark.
Hadoop MapReduce и что его окружает
Apache Hadoop — инфраструктура, упрощающая работу с кластерами. Основные элементы Hadoop — это:
распределённая файловая система (HDFS);
метод крупномасштабного выполнения программ (MapReduce).
HDFS — распределённая файловая система Hadoop для хранения файлов больших размеров с возможностью потокового доступа к информации, поблочно распределённой по узлам вычислительного кластера. Здесь мы храним, читаем, записываем и перекладываем данные.
MapReduce — модель распределённых вычислений, представленная компанией Google, используемая для параллельных вычислений над очень большими, вплоть до нескольких петабайт, наборами данных в компьютерных кластерах.
Алгоритм легко понять по аналогии:
Представьте, что вам предложено подсчитать голоса на национальных выборах. В вашей стране 25 партий, 2500 избирательных участков и 2 миллиона граждан. Как это можно сделать? Можно собрать все избирательные бюллетени со всех участков и подсчитать их самостоятельно, либо приказать каждому избирательному участку подсчитать голосов по каждой из 25 партий и передать вам результат, после чего объединить их по партиям.
Ниже представлена схема выполнения данного алгоритма на примере подсчёта слов в выборке.
Разберём, что происходит, по этапам;
Input — входные данные для обработки;
Splitting — разбивка данных на порционные данные;
Mapping — обработка этих порционных данных воркерами (вычислительными процессами) в формате ключ-значение. Для этого алгоритма ключ — слово, значение — количество вхождений данного слова;
Shuffling — ключи сортируются, чтобы упростить обобщение данных и сделать всю работу в одном воркере, не раскидывая их по разным местам;
Reducing — после того, как мы посчитали количество одинаковых слов на каждом отдельном воркере, объединяем их вместе.
Между этапами происходит запись промежуточных данных на диск, воркеры и данные обособлены друг от друга. Данный алгоритм отлично подходит для кластеров. Подсчёт происходит в разы быстрее, чем на одной машине.
Но есть и недостатки, обусловленные архитектурными особенностями этой вычислительной модели:
недостаточно высокая производительность: классическая технология, в частности, реализованная в ядре Apache Hadoop, обрабатывает данные ациклично в пакетном режиме. При этом функции Reduce не запустятся до завершения всех процессов Map. Все операции проходят по циклу чтение-запись с жёсткого диска, что влечёт задержки в обработке информации;
ограниченность применения: высокие задержки распределённых вычислений, приемлемые в пакетном режиме обработки, не позволяют использовать классический MapReduce для потоковой обработки в режиме реального времени повторяющихся запросов и итеративных алгоритмов на одном и том же датасете, как в задачах машинного обучения. Для решения этой проблемы, свойственной Apache Hadoop, были созданы другие Big Data – фреймворки, в частности Apache Spark;
программисту необходимо прописывать код для этапов Map и Reduce самостоятельно.
Apache Spark
В своей работе мне приходится очень часто писать SQL-запросы и смотреть, какие данные приходят на вход и что внутри них хранится. Для этих целей мне хочется, чтобы инструмент был более интерактивным и не приходилось ждать выполнения запроса часами (но скорость зависит от количества данных, естественно). В этом поможет Spark, он работает намного быстрее Hadoop MapReduce.
Spark — инфраструктура кластерных вычислений, сходная с Hadoop MapReduce. Однако Spark не занимается ни хранением файлов в файловой системе, ни управлением ресурсами. Spark обрабатывает данные ещё быстрее с помощью встроенных коллекций RDD (Resilient Distributed Datasets), которые дают возможность выполнять вычисления в больших кластерах. Благодаря RDD можно совершать такие операции, как map, join, reduce, записывать данные на диск и загружать их.
Добавлю таблицу для сравнения Hadoop MapReduce и Spark.
Но как же достигается данное ускорение? Ниже представлены самые значимые решения в архитектуре Spark.
Промежуточные данные вычислений не записываются на диск, а образуют своего рода общую оперативную память. Это позволяет разным рабочим процессам использовать общие переменные и их состояния.
Отложенные вычисления: Spark приступает к выполнению запроса лишь при непосредственном обращении к нему (вывод на экран, запись конечных данных на диск). В этом случае срабатывает планировщик, соединяя все преобразования, написанные ранее.
Из-за некоторых архитектурных особенностей Hadoop MapReduce уступает по скорости Spark. Для своих задач я выбрала Spark, потому что при моём наборе данных и итерациях он работает быстрее. Мне было интересно посмотреть, что было до инструмента, которым я пользуюсь, и каким образом всё развивалось. Это лишь общее описание работы этих фреймворков, дающее немного понять, как всё внутри обрабатывается. Зная, как работает тот и другой алгоритм, вы теперь можете выбрать для себя подходящий.
Комментарии (10)
Stinkynnov
24.07.2021 15:39+1Как хранятся файлы? Или как получать эти файлы? А может, сразу — как анализировать данные? Читайте подробнее под катом.
Но ничего этого под катом нет.
x-tray
26.08.2021 12:14конечно немного офтоп но что то у вас там совсем не так с HR
Диана Андреева, [26.08.21 11:56] Добрый день, Михаил! К сожалению, придется отменить интервью по позиции Системного администратора в Quadcode. Пока что коллеги не готовы рассмотреть вашу кандидатуру, так как общались только в мае. Если что-то изменится, мы с вами свяжемся! Спасибо большое за уделенное время!
Mishka Ivashka, [26.08.21 12:01] В Мае?? Вы что то путаете )), ну ладно
Диана Андреева, [26.08.21 12:04] Не знаю, мне коллеги передали просто) спасибо)
Mishka Ivashka, [26.08.21 12:06] Там приходили за админ openstak , а тут нужна Voip админ это разные позиции , ваши коллеги просто перепутали
Диана Андреева, [26.08.21 12:07] Да. всё верно. Коллеги не перепутали, просто мало прошло времени, когда можно снова в одну и ту же компанию собеседоваться.
Mishka Ivashka, [26.08.21 12:08] Бред , какой-то , я не собеседовался, ладно, выложу на хабр , пусть народ рассудить
Coocos
Стоит добавить, что расплата за высокую производительность Spark - требования к объему оперативной памяти.
sshikov
Вообще говоря — нет. Спарк много чего умеет, и производительность достигается разными способами.
Прежде всего спарк — это оптимизатор, который достаточно умный, чтобы понимать, что имеющиеся данные обладают определенными характеристиками, например, партиционированы, и способен строить планы соответствующим образом. И в итоге скажем предикат вида a=123 будет выполнен на уровне HDFS, т.е. спарк будет обрабатывать только файлы из папки ../a=123/*, понимая, что это партиция таблицы, и только она нам и нужна. А файлы эти (список) он получит у namenode, не просматривая физические диски.
И где вы тут видите другие требования к оперативной памяти?
Yo1
он прав, чуть перекошены данные и спарк падает с OOM. в случае джойна у оптимизатора не хватает ума предсказать какого размера окажется партиция 123. экзекьютеры ее считают и отошлют на один единственный экзекьютор, если 123 больше чем память экзекьютора, спарк упадет.
я не так давно искал разницу между табличкой и ее бэкапом размером гигов 60, пришлось выкручивать до 6G memory и 4G overhead
sshikov
Вы ощущаете разницу между «бывают проблемы, если налицо перекос», и «спарк потребляет больше памяти» (без какого-либо уточнения, когда и зачем)?
>в случае джойна у оптимизатора не хватает ума предсказать какого размера окажется партиция 123
В случае map reduce вам вообще придется забыть о том, что существуют какие-то там join, потому что в нем нет такого механизма. А в случае спарка вы вполне сможете запрограммировать оценку размера сами, и выбрать другой алгоритм для джойна, или репартиционировать данные перед ним.
Речь о том, что у спарка нет никакого врожденного высокого потребления памяти. А есть скорее умение имеющуюся в наличии память использовать, чтобы увеличивать производительность. Да, бывает что это чревато ООМ. Но говорить что спарк всегда потребляет больше памяти? Чем что? Чем mapreduce? Так сначала надо тоже самое на оном запрограммировать (что будет далеко нетривиально в общем случае), и еще далеко не факт, что самописная реализация на mapreduce не выжрет памяти еще больше).
Yo1
выглядит, что вы совершенно не понимаете предмет. переджоинить данные в map-reduce геморно, но никогда не было непреодолимым препятствием. в книгах разжевываются с десяток стратегий для MR. да, стратегию подбирают под задачу, это не будет каким-то общим, но практически гарантированно по памяти нет нужны затягивать целую партицию, как это делает спарк. в MR редюсер вычитывает строку и это up to you как потратить память. затягивать все в подавляющем большинстве случаев не нужно. вот как с моей задачей сравнения с бэкапом, MR более двух строк в принципе в памяти не требуется, а спарк зачем-то пытается засосать десяток гигов и упасть.
sshikov
>выглядит, что вы совершенно не понимаете предмет.
Скорее вы не пытаетесь понять, о чем я говорю. В API mapreduce нет понятия join, в отличие от спарка, где это можно сделать как через dataset, так и через SQL.
Разумеется, вы можете сделать join по факту, хоть на ассемблере. Но делать вы скорее всего будете все теми же стратегиями, т.е. Nested Loop, Hash Join, или Sort-Merge, или еще какая-то (просто потому, что ничего нового тут не придумано практически со времен публикации Исскусства программирования) — и ни одна из них не будет оптимальна для любой задачи, любого размера и распределения датасета. И делая join врукопашную, вы точно так же имеете возможность накосячить, как оптимизатор спарка — ну или затратить на реализацию кучу своего времени, потому что API mapreduce по сравнению со спарком сильно ниже уровнем.
А я, зная заранее про перекос в данных, точно также смогу спарк настроить, чтобы выбрать стратегию получше, вместо вероятного broadcast, который в вашем случае всю память и выжирает. И сделаю это возможно сильно быстрее.
А уж выбирать, что вам важнее, ваше время или память железки — только вам.
Yo1
простите но вы говорите не понятную ерунду. спарк это по сути высокоуровневая надстройка над MR, у которой стратегия - зачитывать в память и все операции проводить в памяти. товарищ выше свершено прав - расплата за мощь и универсальность спарка - память. что вы пытаетесь доказать противопоставляя низкоуровневому MR не понятно.
я рад что в первый год вы уже знаете о приемах влияющих на план спарка, но сути это не меняет. выставьте 1Gb экзекьютерам и задача переджоинить что-то станет практически не реальной, без каких либо перекосах в данных. а с SQL api - гарантированно не реально, т.к. возможностей через SQL повлиять на план сильно меньше.
sshikov
У меня в проме спокойно джойнятся терабайтовые датасеты без всякого ООМ. А у вас проблемы на 60 гигабайтах. Ну и с чего я должен верить вам, а не своему опыту?