Scala UDF在Spark shell上运行正常,但在sparkSQL

时间:2016-03-07 16:34:46

标签: scala apache-spark apache-spark-sql

我创建了一个sparkUDF。当我在spark-shell上运行时,它运行得非常好。但是当我注册它并在我的sparkSQL查询中使用时,它会产生NullPointerException。

阶> test_proc(" 1605","(@ supp In(-1,118)")

16/03/07 10:35:04 INFO TaskSetManager:在cdts1hdpdn01d.rxcorp.com(1/1)的62 ms中完成阶段21.0(TID 220)中的任务0.0

16/03/07 10:35:04 INFO YarnScheduler:从池中删除任务已完成的TaskSet 21.0

16/03/07 10:35:04 INFO DAGScheduler:ResultStage 21(第一次:45)在0.062秒完成16/03/07 10:35:04 INFO DAGScheduler:作业16完成:第一次:45,花了2.406408 s

res14:Int = 1

阶>

但是当我在我的sparkSQL查询中注册并使用它时,它会给出NPE。

阶> sqlContext.udf.register(" store_proc",test_proc _)

阶> hiveContext.sql("选择store_proc(' 1605','(@ supp In(-1,118)')")。first.getInt( 0)

16/03/07 10:37:58 INFO ParseDriver:解析命令:选择store_proc(' 1605','(@ supp In(-1,118)')16 / 03/07 10:37:58 INFO ParseDriver:Parse Completed 16/03/07 10:37:58 INFO SparkContext:开始工作:第一次:24

16/03/07 10:37:58 INFO DAGScheduler:找到工作17(第一次:24),1输出分区16/03/07 10:37:58 INFO DAGScheduler:最后阶段:ResultStage 22(第一次在:24)16/03/07 10:37:58 INFO DAGScheduler:最后阶段的父母:List()

16/03/07 10:37:58 INFO DAGScheduler:失踪父母:名单()

16/03/07 10:37:58 INFO DAGScheduler:提交ResultStage 22(MapPartitionsRDD [86]起初于:24),没有遗漏的父母

16/03/07 10:37:58 INFO MemoryStore:ensureFreeSpace(10520)调用curMem = 1472899,maxMem = 2222739947

16/03/07 10:37:58 INFO MemoryStore:阻止broadcast_30存储为内存中的值(估计大小10.3 KB,免费2.1 GB)

16/03/07 10:37:58 INFO MemoryStore:ensureFreeSpace(4774)调用curMem = 1483419,maxMem = 2222739947

16/03/07 10:37:58 INFO MemoryStore:阻止broadcast_30_piece0作为字节存储在内存中(估计大小为4.7 KB,免费为2.1 GB)

16/03/07 10:37:58 INFO BlockManagerInfo:在162.44.214.87:47564(大小:4.7 KB,免费:2.1 GB)内存中添加了broadcast_30_piece0

16/03/07 10:37:58 INFO SparkContext:在DAG​​Scheduler.scala广播中制作广播30:861

16/03/07 10:37:58 INFO DAGScheduler:从ResultStage 22提交1个缺失任务(MapPartitionsRDD [86]起初于:24)

16/03/07 10:37:58 INFO YarnScheduler:添加任务集22.0,包含1个任务

16/03/07 10:37:58 INFO TaskSetManager:在阶段22.0中启动任务0.0(TID 221,cdts1hdpdn02d.rxcorp.com,分区0,PROCESS_LOCAL,2155字节)

16/03/07 10:37:58 INFO BlockManagerInfo:在cdts1hdpdn02d.rxcorp.com:33678的内存中添加了broadcast_30_piece0(大小:4.7 KB,免费:6.7 GB) 16/03/07 10:37:58 WARN TaskSetManager:阶段22.0中丢失的任务0.0(TID 221,cdts1hdpdn02d.rxcorp.com):java.lang.NullPointerException

atg.apache.spark.sql.hive.HiveContext.parseSql(HiveContext.scala:291)at org.apache.spark.sql.SQLContext.sql(SQLContext.scala:725)at $ line20. $ read $ IWC $ $ IWC IWC $ $ IWC IWC $ $ IWC IWC $ iwC.test_proc(41)

这是我的' test_proc'的示例

def test_proc (x:String,y:String):Int = {

val hiveContext = new org.apache.spark.sql.hive.HiveContext(sc)

val z:Int = hiveContext.sql(" select 7")。first.getInt(0)

返回z }

1 个答案:

答案 0 :(得分:2)

基于独立调用的输出,看起来test_proc正在执行某种Spark操作,这在UDF中无法工作,因为Spark不支持对分布式数据结构的嵌套操作。如果test_proc正在使用SQLContext,那么这将导致NPP,因为Spark上下文仅存在于驱动程序中。

如果是这种情况,您可以使用本地(最有可能是广播的)变量或joins来重构您的代码以达到预期的效果。