可从PySpark / Python调用的Spark(2.3+)Java函数

时间:2018-08-11 07:13:21

标签: java apache-spark pyspark

re Spark Doc 2.3:

https://spark.apache.org/docs/latest/api/python/pyspark.sql.html#pyspark.sql.SQLContext.registerJavaFunction

  

registerJavaFunction(name,javaClassName,returnType = None)[源代码]

     

将Java用户定义的函数注册为SQL函数。

     

除了名称和函数本身之外,还可以>可选地指定返回类型。如果未指定返回类型,我们将通过反射进行推断。

     

参数:

     

name –用户定义函数的名称

     

javaClassName – Java类的标准名称

     

returnType –注册的Java函数的返回类型。该值可以是pyspark.sql.types.DataType对象或DDL格式的类型字符串。


我的问题:

我想为Spark 2.3+建立一个包含大量UDF的库,这些库都用Java编写并且都可以从PySpark / Python访问。

阅读上面链接的文档似乎表明,类和Java UDF函数之间存在一个一对一的映射(可从PySpark中的Spark-SQL调用)。 因此,如果我说10个Java UDF函数,则需要创建10个公共Java类,每个类具有1个UDF,以使其可从PySpark / SQL调用。

这正确吗?

我可以创建1个公共Java类并将多个不同的UDF放入1类中,并使所有UDF在Spark 2.3中可从PySpark调用吗?

此帖子没有提供任何 Java 示例代码来帮助解答我的问题。看起来一切都在Scala中。我想要Java中的所有内容。 我需要扩展一个类或实现接口来用Java吗? 任何从PySpark-SQL调用的示例Java代码链接都将受到赞赏。

Spark: How to map Python with Scala or Java User Defined Functions?

2 个答案:

答案 0 :(得分:2)

  

因此,如果我说10个Java UDF函数,则需要创建10个公共Java类,每个类具有1个UDF,以使它们可从PySpark / SQL调用。

     

这正确吗?

是的,这是正确的。但是,您可以:

答案 1 :(得分:1)

下面非常简单的Java / Python / Pyspark代码示例可能对某人有帮助,我让它可以在Spark 2.3.1和Java 1.8上针对可从Python调用的Java UDF进行工作。

请注意,这种方法对我来说非常麻烦,因为每个Java UDF都需要一个单独的Java类。因此,对于50个离散的Java UDF = 50个单独的公共Java类! 理想的情况是,如果单个公共Java类可以包含多个单独的Java UDF,并且全部打包在一个JAR文件中,则将是理想的。 I,我还是不知道该怎么做。

欢迎提出改进建议! 谢谢

// Java 8 code 
package com.yourdomain.sparkUDF;

import org.apache.spark.api.java.*;
import org.apache.spark.SparkConf;
import org.apache.spark.sql.*;
import org.apache.spark.sql.api.java.UDF0;
import org.apache.spark.sql.api.java.UDF1;
import org.apache.spark.sql.types.DataTypes;


public final class JavaUDFExample 
        implements UDF0<String> {
    @Override
    public String call() throws Exception {
        return java.util.UUID.randomUUID().toString();
    }
}
// end of Java code
// make a jar file from above including all referenced jar Spark libraries

# PySPark Python code below
from pyspark.sql import SparkSession
from pyspark     import SparkConf, SparkContext
from pyspark.sql import HiveContext
from pyspark.sql.types import IntegerType
from pyspark.sql.types import StringType


spark = SparkSession.builder.appName("Java UDF Example").getOrCreate() 

df = spark.read.json(r"c:\temp\temperatures.json")
df.createOrReplaceTempView("citytemps")

spark.udf.registerJavaFunction("getGuid", "com.yourdomain.sparkUDF.JavaUDFExample", StringType())

spark.sql("SELECT getguid() as guid, * FROM citytemps").show()
# end of PySpark-SQL Python code

DOS shell script to run on local Spark:

spark-submit --jars c:\dir\sparkjavaudf.jar python-udf-example.py