Вы понимаете Hadoop неправильно

    — Мы получаем больше миллиона твитов в день, и наш сервер просто не успевает их обрабатывать. Поэтому мы хотим установить на кластер Hadoop и распределить обработку.

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

    — А что вы собираетесь делать с уже обработанными данными?
    — Скорее всего, мы будем складывать их в MySQL, как делали это раньше, или даже удалять.
    — Тогда вам определённо не нужен Hadoop.

    Мой бывший коллега был далеко не первым, кто говорил про распределённые вычисления на Hadoop. И каждый раз я видел полное непонимание того, зачем была придумана и разработана эта платформа.



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

    Точечная обработка активных данных


    Самый частый сценарий, с которым нам всем приходится сталкиваться, это хранение «активных» данных — информации о пользователях, списка товаров, комментариев к статьям и т.д. — всего, что может часто меняться. В этом случае мы хотим иметь возможность обрабатывать данные точечно — извлекать нужный объект по индексу, обрабатывать его и загружать обратно. Именно такой функционал предоставляет большинство СУБД (причём как реляционных, так и NoSQL).

    При масштабировании основная проблема здесь возникает с максимальным объёмом данных, хранимым в базе. Однако, даже если используемая СУБД не поддерживает распределённую структуру, проблема легко решается за счёт партиционирования на уровне приложения.

    Потоковая обработка в реальном времени


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

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

    Пакетная обработка исторических данных


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

    Представим, что у нас есть данные обо всех покупках в крупной сети супермаркетов за последние пол года. Мы хотим проанализировать эти данные: посчитать среднюю эффективность каждого супермаркета, эффект от проведённых акций, корреляцию между купленными товарами и множество других метрик. Как организовать работу с данными таким образом, чтобы вычисление этих параметров занимало резонное время?

    Мы можем загрузить все данные в распределённую базу Oracle и работать с ними так же, как с активными. Но в этом случае сервер приложений будет последовательно забирать данные из базы и последовательно обрабатывать каждую запись, что крайне неэффективно.

    Мы также можем настроить конвеер для потоковой обработки, распределяя нагрузку между серверами приложений. Но рано или поздно мы упрёмся в канал связи между обрабатывающими узлами и узлами данных.

    Единственный способ распределить нагрузку и не переполнить канал связи — минимизировать передвижение данных между узлами. А для этого необходимо максимум вычислений производить локально на тех машинах, где лежат обрабатываемые данные. Именно принцип локальности данных лежит в основе парадигмы MapReduce и всего Hadoop.

    Подробней о MapReduce


    Принято считать, что каждое задание MapReduce состоит из двух фаз — фазы map и фазы reduce. На самом деле всё несколько сложней: сначала данные разбиваются на сплиты (splits), затем над каждым из них выполняется функция map, затем результаты сортируются, затем комбинируются, затем снова сортируются и наконец передаются функции reduce. Однако именно map и reduce описывают основную идею парадигмы.

    На этапе применения функции map выполняется вся работа, которую можно выполнить локально. Например, локально можно посчитать количество слов в строке или вычислить метрику одной записи в CSV файле, или проанализировать твит и т.д. Map обеспечивает прозрачное распараллеливание и минимальную нагрузку на канал связи.

    Но одного локального map для большинства задач недостаточно: чтобы посчитать количество слов во всём тексте, нужно сложить их количество в каждой строке, а чтобы посчитать среднее значение метрики, нужно собрать вместе результаты по каждой записи из CSV файла. Именно это и является задачей функции reduce. При этом количество данных, передаваемых по сети, значительно снижается (немало в это помогает и функция комбинирования, которая выступает как локальный reduce).

    Так почему же мой коллега был не прав, собираясь использовать Hadoop для сентиментного анализа твитов? Ведь, как уже было сказано выше, на фазе map можно проанализировать каждый твит по отдельности, полностью проигнорировав фазу reduce! Всё дело в инфраструктуре. Во-первых, твиты всё равно сначала придётся транспортировать к вычислительным узлам, а это означает потерю преимущества локальности данных. Во-вторых, Hadoop плохо подходит для онлайн обработки: работа ведётся с пакетами данных, а значит твиты придётся сначала собрать, а только затем запустить задание MapReduce. Даже если настроить задачу map на постоянное и бесконечное считывание твитов из источника, Hadoop через какое-то время убьёт всё задание как сбойное. Ну и, в-третьих, если вы услышите, что Hadoop быстрый, помните, что производительность достигается за счёт минимизации передвижения данных, в то время как сами задания MapReduce, особенно на небольших объёмах данных, могут выполняться довольно долго за счёт накладных расходов (запуск JVM, выполнение резервных заданий, запись промежуточных результатов на диск и т.д.).

    Поэтому используйте правильные инструменты для правильных задач, и будет вам счатье!
    Поделиться публикацией
    Похожие публикации
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 22
    • +1
      Хорошо, а как тогда решить эту задачу? Какие инструменты правильные? Что делать? Как жить?
      • +8
        Жить надо в удовольствие, делать лучше всего то, что нравится, правильные инструменты — это те, которые подходят, а задачу с сентиментным анализом лучше всего решать через потоковую обработку. Насколько я знаю, мой бывший коллега в итоге так и оставил скрипты для анализа независимыми друг от друга, а спереди просто поставил скрипт для диспетчеризации твитов и контроля за ошибками. Вроде, полёт нормальный. По крайней мере, это должно работать, пока очередной высокий менеджер не услышит яркую презентацию про Hadoop и не захочет его снова внедрить :)
        • +4
          Storm спроектирован для такого типа задач.
          Можно попробовать с Эрлангом заморочиться
          • +1
            Stream Computing, в более общем плане если говорить. IBM Infosphere Streams, или Storm и Kafka как писали выше.
          • +14
            К сожалению, в последние годы стремительного прогресса в сфере технологий обработки и хранения данных грань между правильными и неправильными инструментами постепенно исчезает. Документацию никто не читает, специалистов на все стартапы не хватает, маркетинг тоже играет не маловажную роль (привет OpenStack), а потом это уже превращается в «легаси». Другие видят как это вроде бы успешно работает и тоже подхватывают на лету (привет NoSQL).
            И возразить при этом нечего, зачастую аргументов против «как в фейсбуке» не хватает.
            • Согласен. При правильном подходе очень ценная работа должна быть аналитика и архитектора проекта, которые смогут грамотно определить в каком месте какие технологии нужно использовать и каких специалистов нужно привлекать.

              P.S.: Я в данном случаи пошёл другим путём, сменил технологии на те, которые мне больше нравятся и стал заниматься только теми проектами, куда логично применять эти технологии. Вроде и саморазвитие, и при этом стал больше заниматься консультациями, т.к. могу на опыте оценить необходимость применения.
              • +2
                В случае с Hadoop-ом, документацию не только не читают, но и не пишут. К сожалению, технология очень и очень непростая, и некоторые аспекты остаются непонятными даже после прочтения длинных руководств. Ситуация осложняется ещё и тем, что многие участки кода (вплоть до MapReduce API) часто переписываются, что делает долговременную качественную документацию бесполезной.

                Тем не менее, есть надежда, что в какой-то момент всё это устаканится, и разработчики начнут думать не просто, как это сделать (например, как обеспечить безопасность доступа к данным), а как сделать это красиво. Тогда, как мне кажется, и вопросов о правильности инструмента для конкретной задачи станет на порядок меньше.
                • +2
                  2 года работаю c Hadoop, не могу согласиться, что документация по Hadoop плохая. Отличное описание языков программирования Hive, Pig. Много достойных книг по этой технологии. Да, есть небольшие пробелы, но они отлично находятся на stackoverflow. Если бы меня попросили сравнить документацию на MS SQL и Hadoop, я бы выбрал Hadoop.
                  • 0
                    Ну, смотрите. Возьмём самый базовый пример, с которого многие начинают знакомство с Hadoop — задание MapReduce. Вбиваем в Гугль «hadoop mapreduce» и попадаем на страницу официального руководства с… примером устаревшего API. При этом даже мне, знающему, что искать, пришлось долго порыться, чтобы найти пример использования нового интерфейса. А если на официальную документацию нельзя рассчитывать, то на какую можно? Apache, Cloudera, Hortonworks — никто из них не уделаяет внимания поддержанию качества, актуальности и согласованности своих документов. Например, Cloudera активно рекоммендует использовать свой менеджер, но при этом половина примеров написана для базовой версии Hadoop и с менеджером не работает. В книгах такие детали тоже не описывают, так что многие вещи приходится просто делать наугад и затем проверять.

                    Недавно у нас был интересный случай. Мы долгое время искали способ соединить Oracle и Hive/Impala через ODBC. Всё, что выдавал Google либо просто не работало, либо стоило много денег и всё равно не работало (по крайней мере так, как было нужно нам). И совершенно случайно в одной из рассылок user group заметили упоминание про Cloudera ODBC Driver. Попробовали — отработал на отлично. Но ни до, ни после этого случая найти упоминание про этот драйвер через поисковик так и не удалось. Т.е. если бы не рассылка и стечение обстоятельств, драйвер мы бы так и не нашли.
                    • 0
                      Я больше занимаюсь Pig and Hive — возможно там лучше ситуация. ODBC драйвер тоже искал для MS SQL. Как вам производительность ODBC для Oracle? Быстро работает?
                      • 0
                        Пока тестируем, но вроде неплохо. Правда, мы больше рассчитываем на Impala, чем на Hive — пока она себя показала быстрее и… адекватнее, что ли. Impala — это, в смысле, Cloudera Impala. Ещё Hortonworks ведёт в этом направлении работы, обещая стократное ускорение SQL запросов по сравнению с Hive, но им ещё далеко до завершения.

                        • 0
                          Какой размер агрегатов будет передаваться в Oracle? Мне кажется, что здесь как раз Hive лучше подойдет, если объем передаваемых данных большой.
                          • 0
                            По разному, от 300 строк до десятков миллионов, в зависимости от отчёта. А что, у Hive есть какие-то плюшки для передачи больших объёмов данных? Или это у Impala с этим есть какие-то проблемы?
              • 0
                На Hadoop, либо никак (для большинства алгоритмов), ещё работает замечательная библиотека машинного обучения Mahout. Как она это делает с помощью MR — загадка.
                • +1
                  Скорее всего такие алгоритмы работают через цепочку (а вернее даже направленный граф) MR заданий — это значительно расширяет возможности парадигмы. По идее, хороший толчок развитию Mahout должен дать переход на MR2 и YARN вообще. Конечно, если это когда-нибудь всё-таки случится :)
                  • +1
                    Цепочка MR jobs с передачей промежуточных данных через HDFS между jobs. Это очень похоже на использование временных таблиц в SQL, когда вы сохраняете результаты работы одного скрипта, чтобы потом отправить эти данные следующему блоку кода SQL.
                  • +5
                    Спасибо за разъяснения. Есть какая-то книга (или хотя бы статья), где собраны типы задач, встречающиеся в высоконагруженных системах и способы решения этих типовых задач?
                    • 0
                      Вот немножко в другую степь (хотя рядом) — Интел рассказывает как в пределах одной машины правильно параллелить разные типы задач. Это не то же самое, что задачи в распределённой системе, но кое-какие паттерны и выводы почерпнуть можно.
                      • 0
                        Возможно вам поможет цикл книг POSA: Pattern-Oriented Software Architecture. Там их аж 5 томов — думаю, что найдете то, что вам нужно.
                        • +3
                          Мне кажется, здесь надо плясать не от нагруженности систем, а от области применения. В этой статье я писал про обработку больших данных, а ведь распределённые системы могут проектироваться и с другими целями: где-то упор делается на надёжное хранение, и тогда первостепенными становятся вопросы репликации и высокой доступности; где-то на надёжности выполнения распределённых задач, и тогда на первый план выходят надёжность доставки сообщений и соблюдение happens-before отношений; где-то важней всего производительность, и тогда всё упирается в низкоуровневые библиотеки и протоколы передачи данных. Соответсвенно, и способы решения таких типичных задач нужно искать в литературе из этой области.

                          Лично я предпочитаю подсматривать идеи в готовых системах. Например, в своё время понравилась архитектура Твиттера — очень прагматичная, и главное, можно быть уверенным, что это работает. Если вас интересует именно литература и именно «в целом», без конкретной области, то я бы посоветовал почитать что-нибудь про внутренности того же Hadoop — в нём решено множество типичных задач, причём зачастую несколькими способами (см., например, планировщики задач).
                        • +1
                          В посте есть ряд спорных утверждений и очевидных неточностей.
                          проблема легко решается за счёт партиционирования на уровне приложения.
                          Наихудшее из возможных на текущий момент решений.
                          Мы можем загрузить все данные в распределённую базу Oracle и работать с ними так же, как с активными.
                          Откуда столько денег? Вместо одно распределенной Oracle/Teradata DB можно купить Хадуп кластер на пол сотни машин. Ничто не мешает на этих же машинах гонять Storm, как вы упомянули в посте.

                          затем над каждым из них выполняется функция map, затем результаты сортируются, затем комбинируются, затем снова сортируются и наконец передаются функции reduce.
                          Вы забыли смерджить и отсортировать данные на reducer'e. Да и не только.
                          static.oschina.net/uploads/img/201303/14004621_AjkO.png

                          Hadoop через какое-то время убьёт всё задание как сбойное.
                          Какой жестокий Хадуп :)
                          mapred.task.timeout
                          В общем случае, если приходится прибегать к этой property, значит что-то не так в реализации алгоритма.
                          • +1
                            Наихудшее из возможных на текущий момент решений.

                            Почему и какое решение лучше?

                            Откуда столько денег? Вместо одно распределенной Oracle/Teradata DB можно купить Хадуп кластер на пол сотни машин. Ничто не мешает на этих же машинах гонять Storm, как вы упомянули в посте.

                            Смысл всего раздела был в том, что для анализа больших объёмов, например, бизнес логов стандартные базы данных будут неэффективны, даже если это Oracle за много денег.

                            Вы забыли смерджить и отсортировать данные на reducer'e. Да и не только.

                            У меня не было цели давать глубокое техническое описание ни Hadoop, ни конкретно MapReduce. Цель статьи — дать представление о том, для чего Hadoop вообще нужен, когда он хорошо подходит, а когда лучше использовать что-нибудь другое.

                            Какой жестокий Хадуп :)
                            mapred.task.timeout

                            А также можно сказать Хадупу переиспользовать JVM, передавать выходные данные не через файлы, а через пайпы, и вообще настроить систему под любые нужды, но при этом вся инфраструктура Хадупа будет постоянно вставлять палки в колёса. Спрашивается, зачем тогда использовать слонёнка, если сознательно бороться с предлагаемой им парадигмой?

                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.