【问题标题】:Null Pointer Exception When Trying to Use Persisted Table in Spark Streaming尝试在 Spark Streaming 中使用持久表时出现空指针异常
【发布时间】:2015-09-08 23:01:24
【问题描述】:

我在开始时创建“gpsLookUpTable”并将其持久化,这样我就不需要一遍又一遍地拉它来进行映射。但是,当我尝试在 foreach 中访问它时,我得到空指针异常。感谢任何帮助。

下面是sn-ps代码:

def main(args: Array[String]): Unit = { 

val conf = new SparkConf() ... 

val sc = new SparkContext(conf) 
val ssc = new StreamingContext(sc, Seconds(20)) 
val sqc = new SQLContext(sc) 

//////Trying to cache table here to use it below 
val gpsLookUpTable = MapInput.cacheMappingTables(sc, sqc).persist(StorageLevel.MEMORY_AND_DISK_SER_2) 
//sc.broadcast(gpsLookUpTable) 
ssc.textFileStream("hdfs://localhost:9000/inputDirectory/") 
.foreachRDD { rdd => 
if (!rdd.partitions.isEmpty) { 

val allRows = sc.textFile("hdfs://localhost:9000/supportFiles/GeoHashLookUpTable") 
sqc.read.json(allRows).registerTempTable("GeoHashLookUpTable") 
val header = rdd.first().split(",") 
val rowsWithoutHeader = Utils.dropHeader(rdd) 

rowsWithoutHeader.foreach { row => 

val singleRowArray = row.split(",") 
singleRowArray.foreach(println) 
(header, singleRowArray).zipped 
.foreach { (x, y) => 
///Trying to access persisted table but getting null pointer exception 
val selectedRow = gpsLookUpTable 
.filter("geoCode LIKE '" + GeoHash.subString(lattitude, longitude) + "%'") 
.withColumn("Distance", calculateDistance(col("Lat"), col("Lon"))) 
.orderBy("Distance") 
.select("TrackKM", "TrackName").take(1) 
if (selectedRow.length != 0) { 
// do something
} 
else { 
// do something
} 
} 
} }}

【问题讨论】:

    标签: apache-spark apache-spark-sql spark-streaming


    【解决方案1】:

    我假设您在集群中运行;您的 foreach 将在其他节点上作为闭包运行。引发 Nullpointer 是因为该闭包在没有初始化 gpsLookUpTable 的节点上运行。您显然尝试在

    中广播 gpsLookUpTable
    //sc.broadcast(gpsLookUpTable) 
    

    但是这个需要绑定一个变量,基本上是这样的:

    val tableBC = sc.broadcast(gpsLookUpTable) 
    

    在 foreach 中,你会替换这个:

    foreach { (x, y) => 
    ///Trying to access persisted table but getting null pointer exception 
    val selectedRow = gpsLookUpTable 
    

    用这个:

    foreach { (x, y) => 
    ///Trying to access persisted table but getting null pointer exception 
    val selectedRow = tableBC.value 
    

    这可以有效地让您访问广播值。

    【讨论】:

    • 非常感谢。我累了,它奏效了。然而,问题正在增加。 gpsLookUpTable 的输入文件约为 11Mb,当我执行流式操作时,输入文件约为 3 Mb。在设置 16 个内核和 64 GB(3 个执行器,每个 18GB)时,映射需要 40 多分钟。流式传输中的输入显示每个进程有 11MB(我猜这是在每个 foreach 中访问的映射文件)。你能建议任何解决方法吗?
    • 此外,分配的驱动程序内存为 10GB,我猜应该足以处理大约 6 Mb 的输出数据。
    • 驱动程序内存在这里并不重要。我建议也使用 foreachPartition(),这样可以更有效地并行化
    • @ErikSchmiegelow 你能看看这个stackoverflow.com/questions/35149997/…
    猜你喜欢
    • 1970-01-01
    • 2019-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-16
    相关资源
    最近更新 更多