簡體   English   中英

為什么在過濾器中使用集合會導致“ org.apache.spark.SparkException:任務無法序列化”?

[英]Why does using a set in filter cause “org.apache.spark.SparkException: Task not serializable”?

我正在嘗試根據列表中這些對象的字段來篩選RDD中的對象集合。

我嘗試的方法與此處相同: 基於Spark中另一個RDD的過濾器

val namesToFilterOn = sc.textFile("/names_to_filter_on.txt").collect.toSet

val usersRDD = userContext.loadUsers("/user.parquet")

這有效:

usersRDD.filter(user =>  Set("Pete","John" ).contains( user.firstName )).first

當我嘗試

usersRDD.filter(user => namesToFilterOn.contains( user.firstName )).first

我得到這個錯誤

org.apache.spark.SparkException: Task not serializable
Caused by: java.io.NotSerializableException: org.apache.spark.SparkContext

嘗試此操作時遇到的相同錯誤

val shortTestList = Set("Pete","John" )

usersRDD.filter(user => shortTestList .contains( user.firstName )).first

在這些過濾器語句中指定一組名稱/字符串時,為什么會出現此錯誤?

據我認為這應該工作,我沒有在filter語句的任何地方指定SparkContext。 那么為什么會出錯呢? 以及如何不得到錯誤?

我正在使用的Spark版本是1.5.2。

我還嘗試過首先廣播名稱集。

val namesToFilterOnBC = sc.broadcast(namesToFilterOn)
usersRDD.filter(user => namesToFilterOnBC.value.contains( user.firstName )).first

這再次導致相同的錯誤

org.apache.spark.SparkException: Task not serializable
Caused by: java.io.NotSerializableException: org.apache.spark.SparkContext

原因是val namesToFilterOn = sc.textFile("/names_to_filter_on.txt").collect.toSet屬於包含無法序列化val namesToFilterOn = sc.textFile("/names_to_filter_on.txt").collect.toSet的對象,因此是錯誤。

user => namesToFilterOn.contains( user.firstName )轉換為字節格式以通過網絡發送給執行者時,Spark將檢查是否存在對不可序列化對象的引用,並且SparkContext是否在其中。

似乎Spark找到了一個引用不可序列化SparkContext的地方,並引發了異常。

一種解決方案是將val namesToFilterOn = sc.textFile("/names_to_filter_on.txt").collect.toSetval shortTestList = Set("Pete","John" )為Scala中object單獨方法。 您還可以使用閉包內部的另一個val shortTestList (如Job由於階段故障而中止:任務不可序列化中所述 )或廣播它。

您可能會發現文件SIP-21-Spores對於這種情況很有幫助

詢問userContext的開發人員,並通過不顯式實例化userContext而是僅導入其功能來解決此問題。

import userContext._
sc.loadUsers("/user.parquet")
usersRDD.filter(user => namesToFilterOn.contains( user.firstName )).first

代替

val userContext = new UserContext(sc)
userContext.loadUsers("/user.parquet")
usersRDD.filter(user => namesToFilterOn.contains( user.firstName )).first

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM