Apache Hive propose de nombreuses fonctions intégrées pour le traitement des données. Lorsque ces fonctions ne couvrent pas votre logique métier, comme les transformations de chaînes personnalisées, le chiffrement des données ou les calculs spécifiques à un domaine, développez une fonction définie par l'utilisateur (UDF).
Types d'UDF
Apache Hive prend en charge trois types d'UDF :
| Type | Nom complet | Comportement |
|---|---|---|
| UDF | Fonction scalaire définie par l'utilisateur | Mappage un-à-un : lit une ligne et renvoie une valeur unique |
| UDTF | Fonction tabulaire définie par l'utilisateur | Renvoie plusieurs lignes pour chaque entrée ; seul type capable de renvoyer plusieurs champs |
| UDAF | Fonction d'agrégation définie par l'utilisateur | Mappage plusieurs-à-un : agrège plusieurs lignes en une seule valeur de sortie ; utilisée avec GROUP BY |
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
Un cluster E-MapReduce (EMR) avec accès SSH. Consultez la rubrique Connexion à un cluster
Le kit de développement Java (JDK) installé
Apache Maven installé et configuré
Un environnement de développement intégré (IDE) pour le développement Java
Développement du code UDF
Cette section détaille la création d'une UDF simple qui ajoute le suffixe :HelloWorld à une chaîne de caractères en entrée.
1. Créer un projet Maven
Dans votre IDE, créez un nouveau projet Maven avec les coordonnées suivantes. Adaptez les valeurs groupId et artifactId pour qu'elles correspondent à votre organisation et au nom de votre projet.
<groupId>org.example</groupId>
<artifactId>hiveudf</artifactId>
<version>1.0-SNAPSHOT</version>
2. Ajouter la dépendance Hive
Ajoutez la dépendance suivante à votre fichier pom.xml :
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>2.3.7</version>
<exclusions>
<exclusion>
<groupId>org.pentaho</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
3. Implémenter la classe UDF
Créez une classe qui étend org.apache.hadoop.hive.ql.exec.UDF et implémentez la méthode evaluate(). Le nom de la classe est libre ; cet exemple utilise MyUDF.
package org.example;
import org.apache.hadoop.hive.ql.exec.UDF;
public class MyUDF extends UDF {
public String evaluate(final String s) {
if (s == null) { return null; }
return s + ":HelloWorld";
}
}
4. Générer le fichier JAR
Dans le répertoire contenant le fichier pom.xml, exécutez la commande suivante :
mvn clean package -DskipTests
Le fichier JAR généré, nommé hiveudf-1.0-SNAPSHOT.jar, se trouve dans le répertoire target.
Déploiement et enregistrement de l'UDF
1. Transférer le JAR vers votre cluster
Utilisez un client de transfert de fichiers sécurisé SSH pour télécharger le fichier hiveudf-1.0-SNAPSHOT.jar dans le répertoire racine de votre cluster EMR.
2. Télécharger le JAR sur HDFS
Connectez-vous à votre cluster via SSH.
-
Téléchargez le fichier JAR sur le système de fichiers distribué Hadoop (HDFS) :
hadoop fs -put hiveudf-1.0-SNAPSHOT.jar /user/hive/warehouse/ -
Vérifiez que le téléchargement a réussi :
hadoop fs -ls /user/hive/warehouse/La sortie attendue est la suivante :
Found 1 items -rw-r--r-- 1 xx xx 2668 2021-06-09 14:13 /user/hive/warehouse/hiveudf-1.0-SNAPSHOT.jar
3. Enregistrer l'UDF dans Hive
Ouvrez l'interface CLI de Hive :
hive
Enregistrez l'UDF en tant que fonction permanente :
create function myfunc as "org.example.MyUDF" using jar "hdfs:///user/hive/warehouse/hiveudf-1.0-SNAPSHOT.jar";
Dans cette commande :
| Paramètre | Description |
|---|---|
myfunc |
Nom de la fonction utilisé dans les requêtes |
org.example.MyUDF |
Nom qualifié complet de la classe contenue dans le JAR |
hdfs:///user/hive/warehouse/hiveudf-1.0-SNAPSHOT.jar |
Chemin HDFS vers le fichier JAR |
Si l'enregistrement réussit, la sortie ressemble à ceci :
Added [/private/var/folders/2s/wzzsgpn13rn8rl_0fc4xxkc00000gp/T/40608d4a-a0e1-4bf5-92e8-b875fa6a1e53_resources/hiveudf-1.0-SNAPSHOT.jar] to class path
Added resources: [hdfs:///user/hive/warehouse/myfunc/hiveudf-1.0-SNAPSHOT.jar]
4. Tester l'UDF
Appelez l'UDF dans une requête de la même manière que n'importe quelle fonction intégrée :
select myfunc("abc");
La sortie attendue est la suivante :
OK
abc:HelloWorld
Pour confirmer que la fonction est enregistrée, exécutez :
SHOW FUNCTIONS LIKE '*myfunc*';
Dépannage
La commande create function échoue avec une erreur « class not found »
Assurez-vous que le nom de classe dans l'instruction create function correspond exactement au nom qualifié complet de la classe dans votre JAR, y compris le préfixe du package. Par exemple, si votre classe est MyUDF dans le package org.example, la référence doit être org.example.MyUDF, et non MyUDF.
L'UDF renvoie null pour toutes les entrées
Vérifiez la logique de gestion des valeurs nulles dans la méthode evaluate(). L'exemple d'implémentation renvoie null lorsque l'entrée est null. Si votre fonction doit gérer les valeurs null différemment, mettez à jour la méthode en conséquence.