Каковы различия между срезами и разделами RDD?

Я использую Spark Python API и запускаю Spark 0.8.

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

Есть ли разница между срезами и разделами в RDD?

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

Например, существует ли существенная разница между этими двумя фрагментами кода?

rdd = sc.textFile(demo.txt, 100)

против

rdd = sc.textFile(demo.txt)
rdd.partitionBy(100)

Ответ 1

Я считаю, что slices и partitions - одно и то же в Apache Spark.

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

Этот код попытается загрузить demo.txt непосредственно в 100 разделов, используя 100 одновременных задач:

rdd = sc.textFile('demo.txt', 100)

Для несжатого текста он будет работать, как ожидалось. Но если вместо demo.txt у вас был demo.gz, вы получите RDD только с одним разделом. Считывание файлов gzipped невозможно распараллелить.

С другой стороны, следующий код сначала откроет demo.txt в RDD с числом разделов по умолчанию, тогда он будет явно перераспределять данные на 100 разделов, которые примерно равны по размеру.

rdd = sc.textFile('demo.txt')
rdd = rdd.repartition(100)

Итак, в этом случае даже с demo.gz вы получите RDD со 100 разделами.

В качестве примечания я заменил твой partitionBy() на repartition() тем, что, как я полагаю, вы искали. partitionBy() требует, чтобы RDD являлся RDD кортежей. Поскольку repartition() недоступен в Spark 0.8.0, вместо этого вы можете использовать coalesce(100, shuffle=True).

Spark может запускать 1 параллельную задачу для каждого раздела RDD, вплоть до количества ядер в вашем кластере. Поэтому, если у вас есть кластер с 50 ядрами, вы хотите, чтобы ваши RDD имели как минимум 50 разделов (и, вероятно, в 2-3 раза больше, чем).

По Spark 1.1.0 вы можете проверить, сколько разделов имеет RDD:

rdd.getNumPartitions()  # Python API
rdd.partitions.size     // Scala API

До 1.1.0 способ сделать это с помощью API Python был rdd._jrdd.splits().size().

Ответ 2

Вы можете сделать раздел следующим образом:

import org.apache.spark.Partitioner

val p = new Partitioner() {
  def numPartitions = 2
  def getPartition(key: Any) = key.asInstanceOf[Int]
}
recordRDD.partitionBy(p)