Подтвердить что ты не робот

Mind blown: метод RDD.zip()

Я просто обнаружил метод RDD.zip(), и я не могу представить, что его contract может быть.

Я понимаю, что он делает, конечно. Тем не менее, я всегда понимал, что

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

Другими словами, RDD является (мульти) набором, а не последовательностью (и, конечно, в, например, Python получает AttributeError: 'set' object has no attribute 'zip')

Что не так с моим пониманием выше?

В чем причина этого метода?

Является ли это законным за пределами тривиального контекста, например a.map(f).zip(a)?

ИЗМЕНИТЬ 1:

  • Другим сумасшедшим методом является zipWithIndex(), а также различные zipPartitions().
  • Обратите внимание, что first() и take() не сумасшедшие, потому что они являются просто (неслучайными) образцами RDD.
  • collect() тоже хорошо - он просто преобразует set в sequence, который совершенно прав.

EDIT 2: ответ говорит:

когда вы вычисляете один RDD из другого, порядок элементов в новом RDD может не соответствовать порядку в старом.

Это означает, что даже тривиальный a.map(f).zip(a) не гарантированно эквивалентен a.map(x => (f(x),x)). Какова ситуация, когда результаты zip() воспроизводятся?

4b9b3361

Ответ 1

Неверно, что RDD всегда неупорядочены. RDD имеет гарантированный порядок, если он является результатом операции sortBy, например. RDD не является множеством; он может содержать дубликаты. Разделение не является непрозрачным для вызывающего, и его можно контролировать и запрашивать. Многие операции сохраняют как разделение, так и порядок, например map. Тем не менее я считаю, что немного легко случайно нарушить предположения, что zip зависит от того, что они немного тонкие, но это, безусловно, имеет цель.

Ответ 2

Моральная модель, которую я использую (и рекомендую), состоит в том, что элементы RDD упорядочены, но когда вы вычисляете один RDD из другого, порядок элементов в новом RDD может не соответствовать этому в старой.

Для тех, кто хочет знать о разделах, я бы сказал, что:

  • Разделы RDD имеют порядок.
  • Элементы внутри раздела имеют порядок.
  • Если вы думаете о "конкатенировании" разделов (например, кладя их "от конца до конца" по порядку), используя порядок элементов внутри них, общий порядок, в котором вы заканчиваете, соответствует порядку элементов, если вы игнорируете разделы.

Но опять же, если вы вычисляете один RDD из другого, все ставки относительно отношений порядка двух RDD отключены.

Несколько членов класса RDD (я имею в виду API Scala) настоятельно рекомендую концепцию заказа (как и их документация):

collect()
first()
partitions
take()
zipWithIndex()

как и Partition.index, а также SparkContext.parallelize() и SparkContext.makeRDD() (которые принимают как Seq[T]).

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

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

Но это подводит меня к вашему вопросу о "контракте", и действительно, у документации есть проблема в этом отношении. Я не видел ни одного места, где эффект операции на порядок элементов становится ясным. (Класс OrderedRDDFunctions не учитывается, поскольку он относится к упорядочению на основе данных, которое может отличаться от необработанного порядка элементов в RDD. Также класс RangePartitioner.) Я вижу, как это может привести вы пришли к выводу, что существует концепция нет элементарного порядка, но приведенные выше примеры делают эту модель неудовлетворительной для меня.