我正在使用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)上运行上一段代码。
答案 0 :(得分:2)
[重新发表评论作为答案。]
对于这个概念,我认为link on understanding closures是一个非常好的读物。本质上,您不需要广播RDD范围之外的所有变量,因为闭包(在您的情况下为video
)将被序列化并发送到每个执行程序和任务执行期间的访问任务。当广播的数据集很大时,广播变量很有用,因为它将作为只读缓存存在,它将位于执行程序上,而不是在该执行程序上运行每个任务时进行序列化/发送/反序列化。