Я хотел бы задать один теоретический вопрос.
Представьте, что у нас есть наш главный объект как:
val pathToFile: String = "/some/path/to/file.csv"
val rddLoader: RddLoader = new RddLoader(pathToFile)
val rdd = rddLoader.load()
def transformer = new Transformer(rdd)
transformer.transform1(someOtherRdd)
transformer.transform2(yetAnotherRdd)
И выход трансформатора определяется как (псевдокод)
class Transformed(rdd: RDD[sruct]) {
val rddToTransform = rdd.someTransformation
def complexTransformations1(anotherRdd: RDD[struct]) = {
rddToTransform.complexTransformationsInvlovingAnotherRdd
}
def complexTransformations2(anotherRdd: RDD[struct]) = {
rddToTransform.complexTransformations2InvlovingAnotherRdd
}
}
Будет ли влиять тот факт, что rddToTransfrom является членом класса и, следовательно, членом экземпляра класса, повлияет на производительность. Я думаю, что весь класс будет сериализован. Но приведет ли это к тому, что rddToTransform будет сериализован для каждого раздела, таким образом, несколько раз.
Будет ли приведенное ниже описание с точки зрения производительности, сериализации служебных данных и т. Д. В нем мы используем объект, а наш СДР не является членом класса, а просто передается в качестве параметра методу.
val pathToFile: String = "/some/path/to/file.csv"
val rddLoader: RddLoader = new RddLoader(pathToFile)
val rdd = rddLoader.load()
def transformer = Transformer
transformer.transform1(rdd, someOtherRdd)
transformer.transform2(rdd, yetAnotherRdd)
object Transformer {
def complexTransformations1(rdd, anotherRdd: RDD[struct]) = {
rddToTransform.complexTransformationsInvlovingAnotherRdd
}
def complexTransformations2(rdd, anotherRdd: RDD[struct]) = {
rddToTransform.complexTransformations2InvlovingAnotherRdd
}
}
Я могу привести пример с широковещательными переменными. Я понимаю их способ работы. Мне просто интересно, будет ли то, что объясняется ниже, применимо также к СДР и нужно ли нам избегать использования СДР, как в первом примере (член класса)
Допустим, у нас есть большой набор данных с 420 разделами и кластером из 8 узлов-исполнителей. В операции, как:
val referenceData = Map(...)
val filtered = rdd.filter(elem => referenceData.get(elem) > 10)
Объект referenceData будет сериализован 420 раз, или столько задач, сколько требуется для выполнения преобразования.
Вместо этого широковещательная переменная:
val referenceDataBC = sparkContext.broadcast(Map(...))
val filtered = rdd.filter(elem => referenceDataBC.value.get(elem) > 10)
будет отправлено одному исполнителю или 8 раз. Следовательно, экономя много сети и ЦП, уменьшая издержки сериализации.