Todos os produtos
Search
Central de documentação

Realtime Compute for Apache Flink:UDAFs Java

Última atualização: Nov 03, 2026

Uma função de agregação definida pelo usuário (UDAF) reduz várias linhas de entrada a um único valor de saída (mapeamento de muitos para um). Use UDAFs quando as funções de agregação integradas, como SUM ou MAX, não atenderem à sua lógica de agregação.

Para mais informações sobre funções definidas pelo usuário no Flink, consulte Funções definidas pelo usuário.

Funções definidas pelo usuário e ASI_UDX_Demo estão hospedados em sites de terceiros e podem apresentar lentidão ou indisponibilidade ocasional.

Funcionamento

A UDAF usa um acumulador para armazenar o estado intermediário da agregação. Para cada grupo de linhas com a mesma chave GROUP BY, o runtime executa três métodos em sequência:

  1. createAccumulator() — cria um novo acumulador com o estado inicial.

  2. accumulate(acc, ...) — atualiza o acumulador para cada linha de entrada.

  3. getValue(acc) — retorna o resultado final após o processamento de todas as linhas.

Por exemplo, se uma tabela tiver uma coluna numérica e você precisar da soma cumulativa dos valores 1, 2 e 3 no mesmo grupo:

  • O runtime chama createAccumulator() uma vez para inicializar o acumulador com sum = 0.

  • Em seguida, executa accumulate() para cada linha, atualizando sum para 1, depois 3 e, por fim, 6.

  • Por último, chama getValue() para retornar o resultado final.

A saída varia conforme a ativação do mini-batch:

  • Sem mini-batch (padrão): gera uma saída por linha — 1, 3, 6.

  • Com mini-batch ativado: retorna apenas o resultado final — 6. A quantidade de saídas intermediárias depende das configurações do mini-batch e da distribuição dos dados.

Para configurar o mini-batch, consulte Optimize Flink SQL.

Métodos obrigatórios

Método

Finalidade

createAccumulator()

Retorna um novo acumulador com estado inicial

accumulate(acc, ...)

Atualiza o acumulador com uma linha de entrada

getValue(acc)

Retorna o resultado agregado final

Outros métodos podem ser necessários dependendo do caso de uso:

Método

Finalidade

retract(acc, ...)

Permite retrair uma mensagem gerada por um operador upstream

merge(acc, iterable)

Habilita a otimização de agregação em dois estágios (local-global)

Criar uma UDAF

O Realtime Compute for Apache Flink oferece um projeto de demonstração de UDF (ASI_UDX_Demo) com ambiente de desenvolvimento pré-configurado, eliminando a necessidade de configuração manual.

O projeto de demonstração inclui implementações de exemplo para funções escalares definidas pelo usuário (UDSFs), UDAFs e funções de tabela definidas pelo usuário (UDTFs).

Pré-requisitos

Antes de começar, verifique se você tem:

  • IntelliJ IDEA instalado

  • Maven instalado

  • Ambiente de desenvolvimento Java configurado

Etapas

  1. Baixe e descompacte o ASI_UDX_Demo na sua máquina local. A pasta descompactada ASI_UDX-main contém:

    • pom.xml — configuração do projeto Maven, incluindo coordenadas, dependências e regras de build.

    • \ASI_UDX-main\src\main\java\ASI_UDAF\ASI_UDAF.java — implementação de exemplo da UDAF.

  2. No IntelliJ IDEA, selecione File > Open e escolha a pasta ASI_UDX-main.

  3. Abra o arquivo pom.xml no diretório \ASI_UDX-main\ e configure as dependências. O arquivo já inclui a dependência mínima para o Flink 1.12:

    • Se o job não exigir dependências adicionais, pule para a próxima etapa.

    • Caso precise de mais dependências, adicione-as ao pom.xml.

    <dependencies>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-table-common</artifactId>
            <version>1.12.7</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    Use a versão secundária mais recente da versão principal do Apache Flink correspondente à sua versão do Ververica Runtime (VVR). Para consultar o mapeamento entre versões do VVR e do Flink, veja Overview.

  4. Edite o arquivo \ASI_UDX-main\src\main\java\ASI_UDAF\ASI_UDAF.java e implemente sua lógica de agregação. O exemplo abaixo faz uma soma cumulativa:

    package ASI_UDAF;
    
    import org.apache.flink.table.functions.AggregateFunction;
    
    import java.util.Iterator;
    
    public class ASI_UDAF{
        public static class AccSum{
            public long sum;
        }
    
        public static class MySum extends AggregateFunction<Long, AccSum>{
    
            @Override
            public Long getValue(AccSum acSum){
                return acSum.sum;
            }
    
            @Override
            public AccSum createAccumulator(){
                AccSum acCount= new AccSum();
                acCount.sum=0;
                return acCount;
            }
    
            public void accumulate(AccSum acc,long num){
                acc.sum += num;
            }
    
            /**
            * Supports retracting a message generated by an upstream operator.
            */
            public void retract(AccSum acc,long num){
                acc.sum -= num;
            }
    
            /**
            * Supports local-global two-stage aggregate optimization.
            */
            public void merge(AccSum acc,Iterable<AccSum> it){
                Iterator<AccSum> iter=it.iterator();
                while(iter.hasNext()){
                    AccSum accSum=iter.next();
                    if(null!=accSum){
                        acc.sum+=accSum.sum;
                    }
                }
            }
        }
    }
  5. No diretório onde está o pom.xml, execute:

    mvn package -Dcheckstyle.skip

    O empacotamento da UDAF será bem-sucedido quando o arquivo ASI_UDX-1.0-SNAPSHOT.jar aparecer em \ASI_UDX-main\target\.

Usar uma UDAF

Há duas formas de usar uma UDAF em jobs SQL. A tabela a seguir resume as principais diferenças:

Aspecto

Método 1: UDAF registrada

Método 2: JAR no nível do job

Escopo

Disponível em múltiplos jobs

Apenas no job específico

Como registrar

Registre pela página de gerenciamento de UDF

Faça upload do JAR em Additional dependency files no job

Como chamar no SQL

Chame pelo nome registrado (sem necessidade de CREATE TEMPORARY FUNCTION)

Defina um alias com CREATE TEMPORARY FUNCTION … AS 'fully.qualified.ClassName'

Reutilização

Alta — ideal para lógicas de negócio compartilhadas

Baixa — vinculada a um único job

Método 1: Usar uma UDAF registrada (recomendado)

Registre a UDAF uma única vez e reutilize-a em vários jobs. Para instruções de registro, consulte Gerencie UDFs.

Após registrá-la como ASI_UDAF$MySum, chame-a diretamente no SQL:

CREATE TEMPORARY TABLE ASI_UDAF_Source (
  a BIGINT NOT NULL
) WITH (
  'connector' = 'datagen'
);

CREATE TEMPORARY TABLE ASI_UDAF_Sink (
  sum  BIGINT
) WITH (
  'connector' = 'print'
);

INSERT INTO ASI_UDAF_Sink
SELECT `ASI_UDAF$MySum`(a)
FROM ASI_UDAF_Source;

Método 2: Fazer upload de um JAR para um job específico

Na página Data Studio > ETL do Flink, envie o pacote JAR pela opção Additional dependency files, em More configurations. Em seguida, defina um alias de função temporária no SQL do job.

Esse JAR fica restrito ao job em questão e não pode ser compartilhado com outros jobs.

Supondo que a função temporária se chame mysum:

CREATE TEMPORARY TABLE ASI_UDAF_Source (
  a   BIGINT
) WITH (
  'connector' = 'datagen'
);

CREATE TEMPORARY TABLE ASI_UDAF_Sink (
  sum  BIGINT
) WITH (
  'connector' = 'print'
);

CREATE TEMPORARY FUNCTION `mysum` AS 'ASI_UDAF.ASI_UDAF$MySum'; -- Create the temporary function mysum.

INSERT INTO ASI_UDAF_Sink
SELECT `mysum`(a)
FROM ASI_UDAF_Source;

Executar o job

Após desenvolver e implantar o job SQL, acesse Operation Center > Job O&M. Localize o job desejado e clique em Start na coluna Operation.

Com o job em execução, a UDAF agregará o campo a da tabela ASI_UDAF_Source e gravará a soma cumulativa em ASI_UDAF_Sink.

Próximos passos

  • Gerencie UDFs — registre e gerencie UDAFs para reutilização em diferentes jobs.

  • Optimize Flink SQL — configure o mini-batch para controlar a emissão de resultados intermediários.

  • Overview — identifique a versão do Apache Flink compatível com sua versão do VVR.