Что такое MapReduce?

Ответ

MapReduce — это программная модель и фреймворк для параллельной обработки огромных объёмов данных (петабайты) на больших кластерах (тысячи узлов). Это фундаментальная вычислительная парадигма экосистемы Hadoop.

Принцип работы: Задача разбивается на две основные фазы:

  1. Map (Отображение):

    • Входные данные разбиваются на независимые фрагменты (сплиты).
    • На каждом узле кластера запускается множество Mapper-задач.
    • Каждый Mapper обрабатывает один сплит, применяя пользовательскую функцию. На выходе он генерирует набор промежуточных пар ключ-значение.
      // Пример: Подсчёт слов. Mapper читает строку и emits (ключ: слово, значение: 1)
      map(String key, String value):
      for word in value.split():
          emit(word, 1)
  2. Shuffle & Sort:

    • Фреймворк автоматически распределяет все промежуточные пары с одинаковым ключом на один и тот же узел для Reducer-а.
    • Данные сортируются по ключу.
  3. Reduce (Свёртка):

    • На каждом узле запускаются Reducer-задачи.
    • Reducer получает все значения для определённого ключа, агрегирует их (суммирует, усредняет и т.д.) и записывает финальный результат.
      // Пример: Reducer суммирует все единицы для каждого слова
      reduce(String key, Iterator values):
      sum = 0
      for v in values:
          sum += v
      emit(key, sum)

Почему это было революционно (и где используется сейчас):

  • Отказоустойчивость: Фреймворк автоматически перезапускает упавшие задачи.
  • Локалитет данных: Задачи выполняются на узлах, где хранятся данные (HDFS), минимизируя сетевой трафик.
  • Наследие: Многие высокоуровневые инструменты (как Apache Hive, Pig) компилируют запросы в цепочки MapReduce-задач. Хотя сегодня для интерактивной аналитики чаще используются более быстрые движки (Apache Spark, Tez), понимание MapReduce критично для отладки и оптимизации работы в экосистеме Hadoop.

Ответ 18+ 🔞

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

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

Как это, блядь, работает:

  1. Фаза Map (Разбросать и посчитать):

    • Берёшь свою гору данных — терабайты логов, например — и нарезаешь её на куски, которые одному компуютеру по зубам.
    • Запускаешь на каждом узле кластера кучу мелких задач — Mapper'ов. Их работа — прочитать свой кусок и наковырять из него промежуточные результаты. Каждый работает сам по себе, нихуя не зная о других.
    • Например, считаем слова. Mapper видит строку "мама мыла раму" и выдаёт: (мама, 1), (мыла, 1), (раму, 1). И так для каждой строки своего куска.
    // Грубо говоря, код Mapper'а — это:
    map(String key, String value):
        for word in value.split(): // Разделил строку на слова
            emit(word, 1)          // Выплюнул каждое слово с единичкой
  2. Волшебная фаза Shuffle & Sort (Перетасовать и разложить по кучкам):

    • Вот тут охуенно умный момент. Система сама, без твоего участия, берёт все эти выплюнутые пары со всех Mapper'ов.
    • Всё, что с одинаковым ключом (например, все "мама"), она сгребает в одну кучу и отправляет на один и тот же компьютер, где будет работать Reducer. Попутно всё сортируется. Это и есть "reduce" в названии — свести вместе.
  3. Фаза Reduce (Собрать и получить итог):

    • На других компах запускаются Reducer'ы. Каждый получает свою персональную кучку: например, одному достаются все пары для слова "мама", другому — для "мыла".
    • Reducer просто проходит по всей своей стопке значений и делает с ними что надо — суммирует, усредняет, находит максимум.
    • В нашем примере: Reducer для "мама" получает итератор значений [1, 1, 1, 1...], складывает их в кучу и пишет в итог: (мама, 14503).
    // Код Reducer'а — тупая арифметика:
    reduce(String key, Iterator values): // key = "мама", values = [1,1,1...]
        sum = 0
        for v in values:
            sum += v // Просто плюсуем все единички
        emit(key, sum) // Выдаём итог: ("мама", 14503)

В чём был, блядь, прорыв и где это сейчас:

  • Не боится падений: Если один из тысяч компов накрылся медным тазом, система не орёт "всё пропало!", а спокойно перезапускает его задачу на другой машине. Доверия ебать ноль к железу, но система работает.
  • Данные близко к вычислениям: Задачи стараются запускать прямо на тех серверах, где лежат данные, чтобы не гонять овердохуища информации по сети. Это гениально и просто.
  • Наследие: Хотя сейчас для скорости все используют Spark или Flink, под капотом многих старых и надёжных систем (типа Hive) всё ещё копошится этот самый MapReduce. Так что если полезешь в дебри Hadoop'а для отладки — сам от себя охуеешь, когда упрёшься в его логи. Без понимания этих фаз будешь как слепой котёнок.

Короче, идея проще, чем кажется: раздробить, раздать, посчитать параллельно, собрать по кучкам, сложить. Вся хитрость — в автоматизации этого "раздробить-собрать". Без этого мы бы до сих пор бздели, как обработать петабайты.