使用Zeppelin的Pyspark:将文件分发到群集节点而不是SparkContext.addFile()

时间:2018-05-31 15:24:25

标签: python-3.x apache-spark pyspark apache-zeppelin

我有一个我构建的库,我想让它可用于pyspark集群上的所有节点(1.6.3)。我通过Zeppelin(0.7.3)在火花集群上运行测试程序。

我想要的文件位于github存储库中。所以我将该存储库克隆到集群的所有节点上,并通过pssh创建一个脚本来同时更新它们。因此,文件存在于每个节点上的设定位置,我希望每个节点都可以访问它们。

我试过这个

import sys
sys.path.insert(0, "/opt/repo/folder/")

from module import function
return_rdd = function(arguments)

这产生了错误堆栈:

  File "/usr/hdp/current/spark-client/python/pyspark/worker.py", line 98, in main
    command = pickleSer._read_with_length(infile)
  File "/usr/hdp/current/spark-client/python/pyspark/serializers.py", line 164, in _read_with_length
    return self.loads(obj)
  File "/usr/hdp/current/spark-client/python/pyspark/serializers.py", line 439, in loads
    return pickle.loads(obj, encoding=encoding)
ImportError: No module named 'module'

我发现此错误异常,因为它是由pickle调用提示的。代码似乎加载了一个数据帧并对其进行了分区,但只有在转换为rdd的分区df上调用模块中的另一个函数时才会失败。我不确定这里涉及泡菜的地点和原因;模块pyscript不需要被腌制,因为有问题的模块应该已经在集群的每个节点上的sys.path中。

另一方面,我能够通过

来实现这个目标
sc.addFile("/opt/repo/folder/module.py")
import sys
from pyspark import SparkFiles
sys.path.insert(0, SparkFiles.getRootDirectory())

from module import function
return_rdd = function(arguments)

知道为什么第一种方法不起作用?

1 个答案:

答案 0 :(得分:0)

可能的解决方案是:

sc.addFile("/opt/repo/folder/module.py")
import sys
from pyspark import SparkFiles
sys.path.insert(0, SparkFiles.getRootDirectory())

from module import function
return_rdd = function(arguments)

这在群集模式下不起作用