为什么pyspark会选择一个未广播的变量?

时间:2015-10-26 02:11:03

标签: apache-spark distributed-computing pyspark spark-dataframe

我正在使用pyspark来分析数据集,即使我使用的是广播的变量,我也会对以下代码正常工作的原因感到有些惊讶。

有问题的变量是video,在联接之后在函数filter中使用。

seed = random.randint(0,999)

# df is a dataframe
# video is just one randomly sampled element
video = df.sample(False,0.001,seed).head()

# just a python list
otherVideos = [ (22,0.32),(213,0.43) ]

# transform the python list into an rdd 
resultsRdd = sc.parallelize(similarVideos)

rdd = df.rdd.map(lambda row: (row.video_id,row.title))

# perform a join between resultsRdd and rdd
# note that video.title was NOT broadcast
(resultsRdd
   .join(rdd)
   .filter(lambda pair: pair[1][1] != video.title) # HERE!!!
   .takeOrdered(10, key= lambda pair: -pair[1][0]))

我在独立模式下使用pyspark,并使用以下pyspark-submit参数:

--num-executors 12 --executor-cores 4 --executor-memory 1g --master local[*]

另外,我在 jupyter (新的ipython-notebooks)上运行上一段代码。

1 个答案:

答案 0 :(得分:2)

[重新发表评论作为答案。]

对于这个概念,我认为link on understanding closures是一个非常好的读物。本质上,您不需要广播RDD范围之外的所有变量,因为闭包(在您的情况下为video)将被序列化并发送到每个执行程序和任务执行期间的访问任务。当广播的数据集很大时,广播变量很有用,因为它将作为只读缓存存在,它将位于执行程序上,而不是在该执行程序上运行每个任务时进行序列化/发送/反序列化。