在python中,我可以这样做:
lRet = []
llData = [range(3) for i in range(5)]
def func(l):
lRet.append(l[0])
return l
map(func, llData)
print(lRet)
-> [0, 0, 0, 0, 0]
现在,我想在PySpark
中做类似的事情。我的理由是我需要从我的rdd中的数据创建RDD外部的东西。让我们做同样的事情:
lRet = []
#rddData.collect() is of form llData above
def func(l):
lRet.append(l[0])
return l
rddData.map(func).collect()
print lRet
-> []
我还注意到,在本地pyspark实例的import pdb; pdb.set_trace()
中执行第一个示例会使lRet
的结果保持不变,即使它在内部跟踪lRet
有什么想法吗?
答案 0 :(得分:1)
简短的回答是不可能的。 Spark编程不包括维护共享可变状态所需的工具。当您执行代码时,每个执行程序解释器都会获得自己的lRet
变量副本,该副本在本地修改并稍后丢弃。
如Katya Handler in the comments所述,Spark提供accumulators
但这些是只写的,在外部操作时使用时不保证一致的结果,并且驱动程序状态是使用fold
按任务更新的喜欢逻辑。
有些项目在Spark之上使用长时间运行的任务和外部同步原语,但它是一个完全不同的模型。