无法使用Spark SQL中的现有Hive永久UDF

时间:2016-08-18 16:52:24

标签: apache-spark hive apache-spark-sql udf

我以前在hive中注册了一个UDF。它不是永久性的TEMPORARY。它直线工作。

CREATE FUNCTION normaliseURL AS 'com.example.hive.udfs.NormaliseURL' USING JAR 'hdfs://udfs/hive-udfs.jar';

我已经配置了使用hive Metastore的spark。配置正常,因为我可以查询配置单元表。我可以看到UDF;

In [9]: spark.sql('describe function normaliseURL').show(truncate=False)
+-------------------------------------------+
|function_desc                              |
+-------------------------------------------+
|Function: default.normaliseURL             |
|Class: com.example.hive.udfs.NormaliseURL  |
|Usage: N/A.                                |
+-------------------------------------------+

但是我不能在sql语句中使用UDF;

spark.sql('SELECT normaliseURL("value")')
AnalysisException: "Undefined function: 'default.normaliseURL'. This function is neither a registered temporary function nor a permanent function registered in the database 'default'.; line 1 pos 7"

如果我尝试使用spark注册UDF(绕过Metastore),则无法注册它,表明它已经存在。

In [12]: spark.sql("create function normaliseURL as 'com.example.hive.udfs.NormaliseURL'")
AnalysisException: "Function 'default.normaliseURL' already exists in database 'default';"

我正在使用Spark 2.0,hive Metastore 1.1.0。 UDF是scala,我的火花驱动程序代码是python。

我很难过。

  • 我是否认为Spark可以利用Metastore定义的永久UDF?
  • 我是否在hive中正确创建了该功能?

3 个答案:

答案 0 :(得分:2)

问题是Spark 2.0无法执行其JAR位于HDFS上的函数。

Spark SQL: Thriftserver unable to run a registered Hive UDTF

一种解决方法是将函数定义为Spark作业中的临时函数,其中jar路径指向本地边缘节点路径。然后在同一个Spark作业中调用该函数。

CREATE TEMPORARY FUNCTION functionName as 'com.test.HiveUDF' USING JAR '/user/home/dir1/functions.jar'

答案 1 :(得分:0)

函数无法在select中调用directly(如sql server)。

你必须创建一些类似oracle的虚拟表。

CREATE TABLE dual (dummy STRING);

在路径'/path/to/textfile/dual.txt'中加载本地数据'覆盖到表dual;

SELECT normaliseURL('value') from dual;

SELECT * from normaliseURL('value')

答案 2 :(得分:0)

它将适用于纱线环境上的火花,但是建议你不要在hdfs中使用spark-shell --jars <path-to-your-hive-udf>.jar,而是在本地使用。