我有这段代码:
List tmp = colRDD.collect();
int ctr = 0;
for(Object o : tmp){
if (!dictionary.containsKey(o)) {
dictionary.put(o, ctr++);
}
}
revDictionary = dictionary.entrySet().stream()
.collect(Collectors.toMap(Entry::getValue, c -> c.getKey()));
colRDD = colRDD.map(x -> {return dictionary.get(x);});
在开始时,我实现了RDD并将每个值放在一个散列表中,其中RDD值是键。
然后,我很想将RDD中的每个值映射到它们的字典值。
但是,我收到Task not serializable
错误。那是为什么?
答案 0 :(得分:3)
这是因为尝试从执行程序评估的代码中访问作用于驱动程序的变量。
鉴于您的示例代码,此代码行中最可能的罪魁祸首是dictionary
:
colRDD = colRDD.map(x -> {return dictionary.get(x);});
然而,问题也可能来自您在代码中的进一步提升,因此您可能需要检查它。
原因是因为dictionary
驻留在驱动程序的内存中,这可能在一个单独的JVM实例中运行而不是执行程序。传递给colRDD.map
的lambda由执行者而不是驱动程序进行评估。该函数被序列化为要执行的任务,发送给执行程序以运行。但Spark引擎无法将任务序列化,因为关闭'大约dictionary
因此,例外。