Usare una funzione definita dall'utente Java con Apache Hive in HDInsight

Informazioni su come creare una funzione definita dall'utente (UDF) basata su Java che funzioni con Apache Hive. La UDF Java di questo esempio converte una tabella di stringhe di testo in caratteri minuscoli.

Prerequisiti

Ambiente di test

L'ambiente usato per questo articolo è un computer che esegue Windows 10. I comandi sono stati eseguiti in un prompt dei comandi e i vari file sono stati modificati con blocco note. Modificare di conseguenza per l'ambiente.

Da un prompt dei comandi immettere i comandi seguenti per creare un ambiente di lavoro:

IF NOT EXIST C:\HDI MKDIR C:\HDI
cd C:\HDI

Creare una UDF Java di esempio

  1. Creare un nuovo progetto Maven immettendo il comando seguente:

    mvn archetype:generate -DgroupId=com.microsoft.examples -DartifactId=ExampleUDF -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    

    Questo comando crea una directory denominata exampleudf, che contiene il progetto Maven.

  2. Dopo aver creato il progetto, eliminare la exampleudf/src/test directory creata come parte del progetto immettendo il comando seguente:

    cd ExampleUDF
    rmdir /S /Q "src/test"
    
  3. Aprire pom.xml immettendo il comando seguente:

    notepad pom.xml
    

    Sostituire quindi la voce esistente <dependencies> con il codice XML seguente:

    <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>
    

    Queste voci specificano le versioni di Hadoop e Hive incluse in HDInsight 3.6. È possibile trovare informazioni sulle versioni di Hadoop e Hive fornite con HDInsight dal documento relativo al controllo delle versioni dei componenti di HDInsight .

    Aggiungere una sezione <build> prima della riga </project> alla fine del file. Questa sezione deve contenere il seguente 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>
    

    Queste voci definiscono la modalità di realizzazione del progetto. In particolare, la versione di Java usata dal progetto e il modo in cui creare un file uberjar per la distribuzione nel cluster.

    Salvare il file dopo avere apportato le modifiche.

  4. Immettere il comando seguente per creare e aprire un nuovo file ExampleUDF.java:

    notepad src/main/java/com/microsoft/examples/ExampleUDF.java
    

    Copiare e incollare il codice Java seguente nel nuovo file. Chiudere quindi il file.

    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();
        }
    }
    

    Questo codice implementa una funzione definita dall'utente che accetta un valore stringa e restituisce una versione in lettere minuscole della stringa.

Compilare e installare la UDF

Nei comandi seguenti sostituire sshuser con il nome utente effettivo, se diverso. Sostituire mycluster con il nome effettivo del cluster.

  1. Compilare e creare il pacchetto della funzione definita dall'utente immettendo il comando seguente:

    mvn compile package
    

    Questo comando compila e impacchetta la UDF nel file exampleudf/target/ExampleUDF-1.0-SNAPSHOT.jar.

  2. Usare il scp comando per copiare il file nel cluster HDInsight immettendo il comando seguente:

    scp ./target/ExampleUDF-1.0-SNAPSHOT.jar sshuser@mycluster-ssh.azurehdinsight.net:
    
  3. Connettersi al cluster usando SSH immettendo il comando seguente:

    ssh sshuser@mycluster-ssh.azurehdinsight.net
    
  4. Dalla sessione SSH aperta copiare il file JAR nell'archiviazione HDInsight.

    hdfs dfs -put ExampleUDF-1.0-SNAPSHOT.jar /example/jars
    

Utilizzare la UDF da Hive

  1. Avviare il client Beeline dalla sessione SSH immettendo il comando seguente:

    beeline -u 'jdbc:hive2://localhost:10001/;transportMode=http'
    

    Questo comando presuppone che sia stato utilizzato il valore predefinito di admin per l'account di accesso del cluster.

  2. Una volta arrivati al prompt jdbc:hive2://localhost:10001/> , immettere il comando seguente per aggiungere la UDF a Hive ed esporla come una funzione.

    ADD JAR wasbs:///example/jars/ExampleUDF-1.0-SNAPSHOT.jar;
    CREATE TEMPORARY FUNCTION tolower as 'com.microsoft.examples.ExampleUDF';
    
  3. Utilizzare la UDF per convertire i valori recuperati da una tabella in stringhe con lettere minuscole.

    SELECT tolower(state) AS ExampleUDF, state FROM hivesampletable LIMIT 10;
    

    Questa query seleziona lo stato dalla tabella, converte la stringa in lettere minuscole e quindi le visualizza insieme al nome non modificato. L'output appare simile al seguente testo:

    +---------------+---------------+--+
    |  exampleudf   |     state     |
    +---------------+---------------+--+
    | california    | California    |
    | pennsylvania  | Pennsylvania  |
    | pennsylvania  | Pennsylvania  |
    | pennsylvania  | Pennsylvania  |
    | colorado      | Colorado      |
    | colorado      | Colorado      |
    | colorado      | Colorado      |
    | utah          | Utah          |
    | utah          | Utah          |
    | colorado      | Colorado      |
    +---------------+---------------+--+
    

Risoluzione dei problemi

Quando si esegue il processo Hive, potrebbe verificarsi un errore simile al testo seguente:

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.

Questo problema potrebbe essere causato dalle terminazioni di riga nel file di Python. Molti editor di Windows usano per impostazione predefinita CRLF come terminazione di riga, mentre le applicazioni Linux prevedono in genere LF.

È possibile usare le istruzioni di PowerShell seguenti per rimuovere i caratteri CR prima di caricare il file in 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)

Passaggi successivi

Per informazioni su altre modalità di utilizzo di Apache Hive, vedere Cosa sono Apache Hive e HiveQL in Azure HDInsight.

Per altre informazioni sulle UDF di Hive, vedere la sezione Apache Hive Operators and User-Defined Functions (Operatori e funzioni definite dall’utente di Apache Hive) del wiki di Hive all’indirizzo apache.org.