将spark rdd的pickled表示写入文件时发生错误

时间:2017-11-30 10:56:54

标签: apache-spark pyspark bigdata rdd pickle

我使用以下代码来保存spark rdd。

rdd = sc.parallelize([1,2,3])
file = open('test','w')
import pickle
pickle.dump(rdd, file)

,错误信息为:

Py4JError: An error occurred while calling o550.__getstate__. Trace:
py4j.Py4JException: Method __getstate__([]) does not exist
        at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:335)
        at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:344)
        at py4j.Gateway.invoke(Gateway.java:252)
        at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:133)
        at py4j.commands.CallCommand.execute(CallCommand.java:79)
        at py4j.GatewayConnection.run(GatewayConnection.java:209)
        at java.lang.Thread.run(Thread.java:722)

我认为rdd类似于句柄,我不必将所有数据保存在hdfs中以供下次使用。

那么,pyspark rdd对象可以保留吗?如果没有,为什么?如何保存rdd 使用优雅方法在anothor运行时访问的对象?

2 个答案:

答案 0 :(得分:3)

您是否考虑过使用 SparkContext 中提供的 saveAsPickleFile 方法保存为Pickle文件?

rdd = sc.parallelize([1,2,3])
rdd.saveAsPickleFile('user/cloudera/parallalized_collection')

来自documentation

  

saveAsPickleFile(path,batchSize = 10)

     

将此RDD保存为序列化对象的SequenceFile。使用的序列化程序是pyspark.serializers.PickleSerializer,默认批量大小为10.

答案 1 :(得分:1)

RDD是Java对象的代理。要正确序列化,您必须序列化Java和Python对象。不幸的是,这根本不会给你带来任何帮助。虽然JVM RDDSerializable,但它only for internal purposes

  

Spark不支持对通过反序列化创建的RDD副本执行操作和转换。 RDD是可序列化的,因此可以在执行程序中调用它们上的某些方法,但最终用户不应尝试手动执行RDD序列化。

解决您的问题:

  

如何使用优雅的方法保存rdd对象以便在anothor运行时访问?

  • 如果您对保留数据感兴趣,请使用其中一种输出方法(RDD.saveAs*)
  • 否则从头开始创建RDD - 成本可以忽略不计,因为它只是一个食谱。