web-dev-qa-db-fra.com

Impossible d'utiliser un UDF permanent Hive existant à partir de Spark SQL

J'ai déjà enregistré un UDF avec Hive. Il est permanent et non TEMPORARY. Cela fonctionne en ligne droite.

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

J'ai spark configuré pour utiliser la métastore Hive. La configuration fonctionne car je peux interroger les tables Hive. Je peux voir l'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.                                |
+-------------------------------------------+

Cependant, je ne peux pas utiliser l'UDF dans une instruction sql;

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"

Si j'essaie d'enregistrer l'UDF avec spark (en contournant le métastore), il ne parvient pas à l'enregistrer, ce qui suggère qu'il existe déjà.

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

J'utilise Spark 2.0, Hive metastore 1.1.0. L'UDF est scala, mon spark code du pilote est python).

Je suis perplexe.

  • Ai-je raison de supposer que Spark peut utiliser des FDU permanents définis par les métastores?
  • Suis-je en train de créer correctement la fonction dans la ruche?
24
Rob Cowie

Le problème est Spark 2.0 n'est pas en mesure d'exécuter les fonctions dont les fichiers JAR sont situés sur HDFS.

Spark SQL: Thriftserver incapable d'exécuter un Hive UDTF enregistré

Une solution consiste à définir la fonction comme une fonction temporaire dans Spark avec chemin jar pointant vers un chemin de nœud Edge local. Ensuite, appelez la fonction de la même manière Spark = travail.

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