scala用户定义函数在spark sql中不起作用

Posted

技术标签:

【中文标题】scala用户定义函数在spark sql中不起作用【英文标题】:scala user define function not working in sparksql 【发布时间】:2017-08-12 13:22:47 【问题描述】:

我写了一个 UDF,它基本上计算给定的 IP 地址是否在 cidr 列表中。我可以从 scala 调用我的 UDF,它工作正常,但是当我从 spark sql 调用 udf 时,它抛出了这个错误。请帮帮我。

%spark
def isinlist = (ip:String) => 
  import org.apache.commons.net.util.SubnetUtils

  def checkipinrange = (cidr:String,ip:String) => 
    val utils = new SubnetUtils(cidr);
    val isInRange = utils.getInfo().isInRange(ip);
    if (isInRange) 
      true
     else 
      false
    
  
  sqlContext.udf.register("checkipinrange",checkipinrange)

  val query=s"""select * 
                from tag_ip  
                where checkipinrange(tag_ip.cidr, '$ip') """
  val validrange = sqlContext.sql(query)
  if(validrange.count > 0) 
    true
   else 
    false
  

isinlist("5.9.29.73")
sqlContext.udf.register("isinlist",isinlist)

tag_ip 是一个 cidr ip 范围列表。这里 isinlist 函数工作正常。但是当我从 spark sql 调用 isinlist 函数时,它会在下面显示错误。

java.lang.NullPointerException
at $line926276415525.$read$$iwC$$iwC$$iwC$$iwC$$iwC$$$$3baf9f919752f0ab1f5a31ad94af9f4$$$$$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$anonfun$isinlist$1.apply(<console>:198)
at $line926276415525.$read$$iwC$$iwC$$iwC$$iwC$$iwC$$$$3baf9f919752f0ab1f5a31ad94af9f4$$$$$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$anonfun$isinlist$1.apply(<console>:184)
at org.apache.spark.sql.catalyst.expressions.GeneratedClass$SpecificUnsafeProjection.apply(Unknown Source)
at org.apache.spark.sql.execution.Project$$anonfun$1$$anonfun$apply$1.apply(basicOperators.scala:51)
at org.apache.spark.sql.execution.Project$$anonfun$1$$anonfun$apply$1.apply(basicOperators.scala:49)
at scala.collection.Iterator$$anon$11.next(Iterator.scala:328)
at scala.collection.Iterator$$anon$11.next(Iterator.scala:328)
at scala.collection.Iterator$$anon$11.next(Iterator.scala:328)
at scala.collection.Iterator$$anon$10.next(Iterator.scala:312)
at scala.collection.Iterator$class.foreach(Iterator.scala:727)
at scala.collection.AbstractIterator.foreach(Iterator.scala:1157)
at scala.collection.generic.Growable$class.$plus$plus$eq(Growable.scala:48)
at scala.collection.mutable.ArrayBuffer.$plus$plus$eq(ArrayBuffer.scala:103)
at scala.collection.mutable.ArrayBuffer.$plus$plus$eq(ArrayBuffer.scala:47)
at scala.collection.TraversableOnce$class.to(TraversableOnce.scala:273)
at scala.collection.AbstractIterator.to(Iterator.scala:1157)
at scala.collection.TraversableOnce$class.toBuffer(TraversableOnce.scala:265)
at scala.collection.AbstractIterator.toBuffer(Iterator.scala:1157)
at scala.collection.TraversableOnce$class.toArray(TraversableOnce.scala:252)
at scala.collection.AbstractIterator.toArray(Iterator.scala:1157)
at org.apache.spark.sql.execution.SparkPlan$$anonfun$5.apply(SparkPlan.scala:212)
at org.apache.spark.sql.execution.SparkPlan$$anonfun$5.apply(SparkPlan.scala:212)
at org.apache.spark.SparkContext$$anonfun$runJob$5.apply(SparkContext.scala:1858)
at org.apache.spark.SparkContext$$anonfun$runJob$5.apply(SparkContext.scala:1858)
at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:66)

有人可以帮我解决问题吗?

【问题讨论】:

上面的代码有效吗?你是如何从 sql 查询中调用 isinlist 的? 【参考方案1】:

您应该检查null 值。例如:

val isInRange = ip != null && utils.getInfo().isInRange(ip);

【讨论】:

以上是关于scala用户定义函数在spark sql中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Spark/Scala - 无法执行用户定义的函数

无法使用 Scala 在 Apache Spark 中执行用户定义的函数

关于在 Spark Scala 中创建用户定义函数 (UDF)

scala/spark 代码中不允许在配置单元中添加列

Spark SQL UDF 使用 df.WithColumn() 返回 scala 不可变映射

AngularJS、SweetAlert.js 在自定义指令中不起作用