【Spark】(十)使用UDF(User Define Function)

本文介绍了Spark中的UDF(User Defined Function),包括UDF的概念、使用场景及两种使用方式:在SQL语句中使用和直接对列应用。通过示例展示了如何注册和调用UDF,同时指出UDF受Scala 22参数限制,以及一种基于Hive UDF的实现方案。

一、UDF介绍

UDF(User Define Function),即用户自定义函数,Spark的官方文档中没有对UDF做过多介绍,猜想可能是认为比较简单吧。

几乎所有sql数据库的实现都为用户提供了扩展接口来增强sql语句的处理能力,这些扩展称之为UDXXX,即用户定义(User Define)的XXX,这个XXX可以是对单行操作的UDF,或者是对多行操作的UDAF,或者是UDTF,本次主要介绍UDF。

UDF的UD表示用户定义,既然有用户定义,就会有系统内建(built-in),一些系统内建的函数比如abs,接受一个数字返回它的绝对值,比如substr对字符串进行截取,它们的特点就是在执行sql语句的时候对每行记录调用一次,每调用一次传入一些参数,这些参数通常是表的某一列或者某几列在当前行的值,然后产生一个输出作为结果。

适用场景: UDF使用频率极高,对于单条记录进行比较复杂的操作,使用内置函数无法完成或者比较复杂的情况都比较适合使用UDF。

二、使用UDF

2.1 在SQL语句中使用UDF

在sql语句中使用UDF指的是在spark.sql(“select udf_foo(…)”)这种方式使用UDF,套路大致有以下几步:

  1. 实现UDF,可以是case class,可以是匿名类
  2. 注册到spark,将类绑定到一个name,后续会使用这个name来调用函数
  3. 在sql语句中调用注册的name调用UDF

下面是一个简单的示例:

alice   jogging,Coding,cooking
lina   travel,dance
object SparkUDFDemo {

  case class Hobbies(name:String,hobbies:String)

  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder().appName("SparkUDFDemo").master("local[*]").getOrCreate()
    val sc = spark.sparkContext

    import spark.implicits._

    val rdd = sc.textFile("in/hobbies.txt")
    val df = rdd.map(x=>x.split("\t")).map(x=> Hobbies(x(0),x(1))).toDF()
    // 定义临时表
    df.registerTempTable("hobbies")
    //注册自定义函数,注意是匿名函数
    spark.udf.register("hobby_num", (v:String) => v.split(",").size)
    val frame = spark.sql("select name,hobbies,hobby_num(hobbies) as hobnum from hobbies")
    frame.show()
  }
}

在这里插入图片描述

2.2 直接对列应用UDF(脱离sql)

在sql语句中使用比较麻烦,还要进行注册什么的,可以定义一个UDF然后将它应用到某个列上:

object SparkUDFStudy {
  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder().master("local[*]").appName("SparkUDFStudy").getOrCreate()
    import spark.implicits._
    val ds = Seq((1, "foo"), (2, "bar")).toDF("id", "text")
    val toUpperCase = functions.udf((s: String) => s.toUpperCase)
    ds.withColumn("text", toUpperCase('text)).show()
  }
}

在这里插入图片描述
注:需要注意的是受Scala limit 22限制,自定义UDF最多接受22个参数,不过正常情况下完全够用了。

小结:
关于UDF:

  • 1、简单粗暴的理解,它就是输入一行输出一行的自定义算子
  • 2、我们可以通过实名函数或匿名函数的方式来实现,并使用sparkSession.udf.register()注册
  • 3、需要注意,截至目前(spark2.4)最多只支持22个输入参数的UDF
  • 4、另外还有一种实现方案(基于spark1.5,spark2.4待测试):
    继承org.apache.hadoop.hive.ql.exec.UDF

参考文献:
https://www.cnblogs.com/cc11001100/p/9463909.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值