Scala中Spark SQL注册临时视图时出现空指针异常求助
问题根源与解决方案
你碰到的这个NullPointerException其实是Spark开发里的常见坑——SparkSession是Driver进程独有的对象,没办法在Executor节点的分布式任务中直接使用。
你用Select_Querydf.foreach{...}的时候,这段代码逻辑是被分发到各个Executor节点上执行的,但SparkSession并没有被序列化传递到Executor,所以当你在Executor里调用spark.sql(Selectstmt)时,spark这个引用就变成了null,自然抛出空指针异常。而之前的println能正常工作,是因为row里的数据已经被序列化到Executor了,打印操作不需要依赖SparkSession。
快速解决方法
因为你的alldata表存的是SQL语句和视图名,数据量肯定不大,完全可以把数据拉到Driver端来处理,这样就能直接使用Driver的SparkSession了:
// 先把DataFrame的数据拉到Driver本地内存 Select_Querydf.collect().foreach{row => val Selectstmt = row(0).toString() val viewname = row(1).toString() println(Selectstmt+"-->"+viewname) // 这里使用的是Driver端的SparkSession,不会有空指针问题 spark.sql(Selectstmt).createOrReplaceTempView(viewname) }
补充说明
如果你的alldata数据量真的大到不能用collect()(会导致Driver内存溢出),那可以考虑在mapPartitions里重新获取SparkSession(每个Partition初始化一次),但这种场景在你的业务里其实没必要——毕竟注册视图是控制层面的操作,适合在Driver端集中执行,不需要分布式处理。
按照上面的代码修改后,就能正常执行每个SQL并注册临时视图了。
内容的提问来源于stack exchange,提问作者Lokesh
相关产品推荐
相关产品推荐

