O Apache Hive oferece diversas funções integradas para processamento de dados. Quando essas funções não atendem à sua lógica — como transformações personalizadas de strings, criptografia de dados ou cálculos específicos de domínio —, crie uma função definida pelo usuário (UDF).
Tipos de UDF
O Apache Hive é compatível com três tipos de UDFs:
|
Tipo |
Nome completo |
Comportamento |
|
UDF |
Função escalar definida pelo usuário |
Mapeamento um para um: lê uma linha e retorna um valor |
|
UDTF |
Função com valor de tabela definida pelo usuário |
Retorna várias linhas por entrada; único tipo capaz de retornar múltiplos campos |
|
UDAF |
Função de agregação definida pelo usuário |
Mapeamento muitos para um: agrega várias linhas em um único valor de saída; usada com |
Pré-requisitos
Antes de começar, verifique se você tem:
Um cluster E-MapReduce (EMR) com acesso SSH. Consulte Fazer login em um cluster
Java Development Kit (JDK) instalado
Apache Maven instalado e configurado
Um ambiente de desenvolvimento integrado (IDE) para Java
Desenvolver o código da UDF
Esta seção demonstra a criação de uma UDF simples que acrescenta :HelloWorld ao final de uma string de entrada.
1. Criar um projeto Maven
No IDE, crie um novo projeto Maven com as coordenadas abaixo. Ajuste groupId e artifactId para corresponder à sua organização e ao nome do projeto.
<groupId>org.example</groupId>
<artifactId>hiveudf</artifactId>
<version>1.0-SNAPSHOT</version>
2. Adicionar a dependência do Hive
Adicione a seguinte dependência ao arquivo 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. Implementar a classe da UDF
Crie uma classe que estenda org.apache.hadoop.hive.ql.exec.UDF e implemente o método evaluate(). O nome da classe é livre; este exemplo usa 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. Gerar o arquivo JAR
No diretório que contém o arquivo pom.xml, execute:
mvn clean package -DskipTests
O arquivo JAR gerado, hiveudf-1.0-SNAPSHOT.jar, ficará disponível no diretório target.
Implantar e registrar a UDF
1. Transferir o JAR para o cluster
Use o SSH Secure File Transfer Client para enviar o arquivo hiveudf-1.0-SNAPSHOT.jar para o diretório raiz do cluster EMR.
2. Enviar o JAR para o HDFS
Faça login no cluster via SSH.
-
Envie o JAR para o Hadoop Distributed File System (HDFS):
hadoop fs -put hiveudf-1.0-SNAPSHOT.jar /user/hive/warehouse/ -
Verifique se o envio foi bem-sucedido:
hadoop fs -ls /user/hive/warehouse/Saída esperada:
Found 1 items -rw-r--r-- 1 xx xx 2668 2021-06-09 14:13 /user/hive/warehouse/hiveudf-1.0-SNAPSHOT.jar
3. Registrar a UDF no Hive
Abra a CLI do Hive:
hive
Registre a UDF como função permanente:
create function myfunc as "org.example.MyUDF" using jar "hdfs:///user/hive/warehouse/hiveudf-1.0-SNAPSHOT.jar";
Neste comando:
|
Parâmetro |
Descrição |
|
|
Nome da função usado nas consultas |
|
|
Nome totalmente qualificado da classe no JAR |
|
|
Caminho do JAR no HDFS |
Se o registro for bem-sucedido, a saída será semelhante a:
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. Testar a UDF
Chame a UDF em uma consulta assim como qualquer função integrada:
select myfunc("abc");
Saída esperada:
OK
abc:HelloWorld
Para confirmar o registro da função, execute:
SHOW FUNCTIONS LIKE '*myfunc*';
Solução de problemas
O comando create function falha com erro de classe não encontrada
Certifique-se de que o nome da classe na instrução create function corresponda exatamente ao nome totalmente qualificado da classe no JAR, incluindo o prefixo do pacote. Por exemplo, se a classe for MyUDF no pacote org.example, a referência deve ser org.example.MyUDF, e não apenas MyUDF.
A UDF retorna null para todas as entradas
Revise a lógica de tratamento de nulos no método evaluate(). A implementação de exemplo retorna null quando a entrada é null. Caso a função deva tratar valores null de maneira diferente, atualize o método conforme necessário.