Utilización de una función definida por el usuario de Java con Apache Hive en HDInsight
Aprenda cómo crear una función basada en Java y definida por el usuario (UDF) que funcione con Apache Hive. La función de Java definida por el usuario de este ejemplo convierte una tabla de cadenas de texto a caracteres en minúscula.
Requisitos previos
Un clúster de Hadoop en HDInsight. Consulte Introducción a HDInsight en Linux.
Apache Maven correctamente instalado según Apache. Maven es un sistema de compilación de proyectos de Java.
El esquema de URI para el almacenamiento principal de clústeres. Esto sería wasb:// para Azure Storage,
abfs://
para Azure Data Lake Storage Gen2 o adl:// para Azure Data Lake Storage Gen1. Si se habilita la transferencia segura para Azure Storage, el identificador URI seríawasbs://
. Consulte también el artículo acerca de la transferencia segura.Un editor de texto o IDE de Java
Importante
Si crea los archivos de Python en un cliente Windows, debe usar un editor que emplee LF como final de línea. Si no está seguro de si el editor usa LF o CRLF, vea la sección Solución de problemas para conocer los pasos a seguir para quitar el carácter CR.
Entorno de prueba
El entorno usado en este artículo fue un equipo donde se ejecuta Windows 10. Los comandos se ejecutaron en un símbolo del sistema, y los distintos archivos se editaron con el Bloc de notas. Realice las modificaciones según corresponda en su entorno.
Desde un símbolo del sistema, escriba los siguientes comandos para crear un entorno de trabajo:
IF NOT EXIST C:\HDI MKDIR C:\HDI
cd C:\HDI
Crear una función de Java definida por el usuario de ejemplo
Utilice el comando siguiente para crear un nuevo proyecto de Maven:
mvn archetype:generate -DgroupId=com.microsoft.examples -DartifactId=ExampleUDF -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
Este comando crea un directorio denominado
exampleudf
, que contiene el proyecto de Maven.Una vez creado el proyecto, elimine el directorio
exampleudf/src/test
que se creó como parte del proyecto. Para ello, escriba el siguiente comando:cd ExampleUDF rmdir /S /Q "src/test"
Especifique el siguiente comando para abrir
pom.xml
:notepad pom.xml
Reemplace la entrada
<dependencies>
existente por el siguiente código XML:<dependencies> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>2.7.3</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-exec</artifactId> <version>1.2.1</version> <scope>provided</scope> </dependency> </dependencies>
Estas entradas especifican la versión de Hadoop y Hive incluida con el clúster de HDInsight 3.6. Puede encontrar información sobre las versiones de Hadoop y Hive proporcionadas con HDInsight en el artículo ¿Cuáles son los diferentes componentes de Hadoop disponibles con HDInsight? .
Agregue una sección
<build>
antes de la línea</project>
al final del archivo. Esta sección debe contener el siguiente XML:<build> <plugins> <!-- build for Java 1.8. This is required by HDInsight 3.6 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <!-- build an uber jar --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.1</version> <configuration> <!-- Keep us from getting a can't overwrite file error --> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer"> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"> </transformer> </transformers> <!-- Keep us from getting a bad signature error --> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
Estas entradas definen cómo compilar el proyecto. Específicamente, la versión de Java que el proyecto usa y cómo compilar un archivo uberjar para implementarlo en el clúster.
Guarde el archivo una vez hechos los cambios.
Escriba el comando siguiente para crear un archivo
ExampleUDF.java
y abrirlo:notepad src/main/java/com/microsoft/examples/ExampleUDF.java
Luego, copie y pegue el código Java siguiente en el nuevo archivo. y ciérrelo.
package com.microsoft.examples; import org.apache.hadoop.hive.ql.exec.Description; import org.apache.hadoop.hive.ql.exec.UDF; import org.apache.hadoop.io.*; // Description of the UDF @Description( name="ExampleUDF", value="returns a lower case version of the input string.", extended="select ExampleUDF(deviceplatform) from hivesampletable limit 10;" ) public class ExampleUDF extends UDF { // Accept a string input public String evaluate(String input) { // If the value is null, return a null if(input == null) return null; // Lowercase the input string and return it return input.toLowerCase(); } }
Este código implementa una función definida por el usuario que acepta un valor de cadena y devuelve una versión en minúsculas de esta.
Compilación e instalación de la función definida por el usuario
En los siguientes comandos, reemplace sshuser
por el nombre de usuario real, si es distinto. Reemplace mycluster
por el nombre de clúster real.
Escriba el siguiente comando para compilar y empaquetar la función definida por el usuario:
mvn compile package
Este comando compila y empaqueta la función definida por el usuario en el archivo
exampleudf/target/ExampleUDF-1.0-SNAPSHOT.jar
.Use el comando
scp
para copiar el archivo en el clúster de HDInsight. Para ello, escriba el siguiente comando:scp ./target/ExampleUDF-1.0-SNAPSHOT.jar sshuser@mycluster-ssh.azurehdinsight.net:
Conéctese al clúster mediante SSH con el comando siguiente:
ssh sshuser@mycluster-ssh.azurehdinsight.net
Desde la sesión de SSH abierta, copie el archivo .jar en el almacenamiento de HDInsight.
hdfs dfs -put ExampleUDF-1.0-SNAPSHOT.jar /example/jars
Uso de la función definida por el usuario desde Hive
Escriba el siguiente comando desde la sesión de SSH para iniciar el cliente de Beeline:
beeline -u 'jdbc:hive2://localhost:10001/;transportMode=http'
Este comando supone que usó el valor predeterminado de admin para la cuenta de inicio de sesión del clúster.
Una vez alcanzado el aviso
jdbc:hive2://localhost:10001/>
, escriba lo siguiente para agregar la función definida por el usuario a Hive y exponerla como una función.ADD JAR wasbs:///example/jars/ExampleUDF-1.0-SNAPSHOT.jar; CREATE TEMPORARY FUNCTION tolower as 'com.microsoft.examples.ExampleUDF';
Use la función definida por el usuario para convertir los valores recuperados de una tabla a cadenas de minúsculas.
SELECT tolower(state) AS ExampleUDF, state FROM hivesampletable LIMIT 10;
Esta consulta selecciona el estado de la tabla, convierte la cadena a minúsculas y, a continuación, las muestra junto con el nombre sin modificar. La salida es similar al siguiente texto:
+---------------+---------------+--+ | exampleudf | state | +---------------+---------------+--+ | california | California | | pennsylvania | Pennsylvania | | pennsylvania | Pennsylvania | | pennsylvania | Pennsylvania | | colorado | Colorado | | colorado | Colorado | | colorado | Colorado | | utah | Utah | | utah | Utah | | colorado | Colorado | +---------------+---------------+--+
Solución de problemas
Al ejecutar el trabajo de Hive, es posible que se produzca un error similar al texto siguiente:
Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: [Error 20001]: An error occurred while reading or writing to your custom script. It may have crashed with an error.
Este problema puede deberse a los finales de línea del archivo de Python. De forma predeterminada, muchos editores de Windows usan CRLF como final de línea, pero las aplicaciones Linux normalmente esperan caracteres LF.
Puede usar las siguientes instrucciones de PowerShell para quitar los caracteres CR antes de cargar el archivo en HDInsight:
# Set $original_file to the Python file path
$text = [IO.File]::ReadAllText($original_file) -replace "`r`n", "`n"
[IO.File]::WriteAllText($original_file, $text)
Pasos siguientes
Para conocer otras formas de trabajar con Hive, consulte Uso de Apache Hive con HDInsight.
Para más información sobre las funciones definidas por el usuario de Hive, consulte la sección Apache Hive Operators and User-Defined Functions (Operadores de Apache Hive y funciones definidas por el usuario) de la wiki de Hive en apache.org.