Старые-добрые RDD

Любой туториал по Spark на просторах сети начинается с введения в RDD (реально дробленые данные). Я не ставлю перед собой цель их пересказать, но хочу вас уверить, что концепция эта достаточно простая и доступная для пониманию всем любителям функциональных языков и лямбд.

Во-первых, работать с RDD вы будете в старом-добром однопоточном стиле, а сам Spark уже за вас будет заботиться о распределении данных по кластеру. Как и в случае с MapReduce-каркасом, разработчику нужно описать только логику преобразований пар ключ-значение [key-value], но вместо переопределения функций нам достаточно определить лямбды (что возможно даже на Java) и передать их в одну из более чем 80 различных операций.

Во-вторых, вся внутренняя структура и кишочки RDD лежат на поверхности и вы должны держать в голове биение всех операций на два больших набора: "параллельный перенос" и "взял, смешал и вылил в форму". Я говорю здесь о wide/narrow зависимостях.

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

RDD значений и RDD пар ключ-значение

Генерируя очередную RDD при помощи оператора .parallelize(), вы наверняка замечали, что часть операций, таких как reduceByKey, join и т.д., вам недоступна.

val sc = spark.sparkContext

val r = 1 to 10 toArray

val ints = sc.parallelize(r, 3)

ints.<no groupByKey>

Дело в том, что RDD созданная из массива значений - это эдакая "неполноценная RDD", где коллекция значений только готовится стать либо набором ключей для индексации элементов, либо набором значений, для которых ключи будут получены как-то иначе.

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

   val groups = ints.map(x => if (x % 2 == 0) {
      (0, x)
    } else {
      (1, x)
    })

    println(groups.groupByKey.toDebugString)
    groups.groupByKey.collect.foreach(println)

Зачем нужно разбираться с RDD?

К сожалению, Structured Streaming имеет пока недостаточно зрелое API, поддержка DataFrames ограничена в MLlib, DStreams, GraphX. Да имеются проекты GraphFrames, TensorFrames, новый пакет ml. Но пройдет еще пару лет, пока весь функционал переедет на DataFrames. За это время накопится столько Spark-легаси на проектах, что эти знания пригодятся и тем, кто стартует в 2018 и 2019 годах на Spark-проектах.

results matching ""

    No results matching ""