O Flink SQL oferece suporte às funções de janela TUMBLE, HOP e SESSION com base no tempo de evento ou no tempo de processamento.
Funções de janela
O Flink SQL permite agregações sobre janelas infinitas sem definir janelas explicitamente nas instruções SQL. Também é possível agregar dados em uma janela específica. Por exemplo, para contar usuários que clicaram em uma URL no minuto anterior, defina uma janela que colete os dados de clique do último minuto e calcule o resultado.
O Flink SQL suporta agregações de janela e agregações over. Este tópico aborda as agregações de janela. Essas agregações utilizam dois atributos de tempo — tempo de evento e tempo de processamento — e oferecem suporte às funções de janela TUMBLE, HOP e SESSION.
As agregações de janela (TUMBLE, HOP e SESSION) combinadas com as funções LAST_VALUE, FIRST_VALUE ou TopN podem gerar resultados imprecisos devido aos mecanismos de acionamento da janela ou a latências.
Atributos de tempo
O Flink SQL suporta dois atributos de tempo: tempo de evento e tempo de processamento. O comportamento da janela varia conforme o atributo utilizado.
-
Tempo de evento: geralmente corresponde ao timestamp incorporado em um registro.
A janela se fecha quando a marca d'água ultrapassa o horário de término. A saída é gerada apenas quando os dados de fechamento chegam. Em uma única subtarefa, a marca d'água aumenta monotonicamente. Com múltiplas subtarefas ou tabelas de origem, o Flink utiliza o valor mínimo da marca d'água.
ImportanteSe existirem registros fora de ordem ou se uma subtarefa ou partição não tiver dados, a marca d'água não avança e a janela pode não fechar. Para resolver isso, especifique um deslocamento de marca d'água para dados fora de ordem e garanta que todas as subtarefas e partições recebam fluxo de dados. Caso uma partição esteja ociosa, adicione
table.exec.source.idle-timeout: 10sao campo Other Configuration em Parameters, na aba Configuration da página Deployments. Consulte Configuration para obter detalhes sobre os parâmetros.Após o processamento dos dados com GROUP BY, operações JOIN entre dois fluxos de dados ou nós de janela OVER, a propriedade de marca d'água é perdida e o tempo de evento não pode mais ser usado para janelas.
-
Tempo de processamento: horário do relógio do sistema no momento em que o Flink processa um evento.
O Flink gera o tempo de processamento, que não existe nos dados brutos; portanto, defina explicitamente uma coluna de tempo de processamento.
NotaComo o tempo de processamento depende da velocidade de chegada dos eventos e da ordem de processamento, os resultados de reprocessamento podem variar entre execuções.
Agregações de janela em cascata
Após a conclusão de uma agregação de janela, a coluna rowtime perde seu atributo de tempo de evento. Utilize funções auxiliares como TUMBLE_ROWTIME, HOP_ROWTIME ou SESSION_ROWTIME para recuperar max(rowtime) da janela e usá-lo como o novo rowtime. O valor retornado equivale a window_end - 1, é do tipo TIMESTAMP e mantém o atributo rowtime. Por exemplo, para a janela [00:00, 00:15), o valor retornado é 00:14:59.999.
O exemplo abaixo aplica uma janela tumbling de 1 hora sobre uma janela tumbling de 1 minuto:
CREATE TEMPORARY TABLE user_clicks(
username varchar,
click_url varchar,
eventtime varchar,
ts AS TO_TIMESTAMP(eventtime),
WATERMARK FOR ts AS ts - INTERVAL '2' SECOND -- Define a watermark for rowtime.
) with (
'connector'='sls',
...
);
CREATE TEMPORARY TABLE tumble_output(
window_start TIMESTAMP,
window_end TIMESTAMP,
username VARCHAR,
clicks BIGINT
) with (
'connector'='datahub' -- Simple Log Service allows you to export only VARCHAR-type DDL statements. Therefore, DataHub is used to store data.
...
);
CREATE TEMPORARY VIEW one_minute_window_output AS
SELECT
TUMBLE_ROWTIME(ts, INTERVAL '1' MINUTE) as rowtime, -- Use TUMBLE_ROWTIME as the aggregation time of the level-two window.
username,
COUNT(click_url) as cnt
FROM user_clicks
GROUP BY TUMBLE(ts, INTERVAL '1' MINUTE),username;
BEGIN statement set;
INSERT INTO tumble_output
SELECT
TUMBLE_START(rowtime, INTERVAL '1' HOUR),
TUMBLE_END(rowtime, INTERVAL '1' HOUR),
username,
SUM(cnt)
FROM one_minute_window_output
GROUP BY TUMBLE(rowtime, INTERVAL '1' HOUR), username;
END;
Resultados intermediários
Os dados intermediários de janela consistem em estado com chave e dados de timer, cada um armazenado em backends diferentes. Escolha uma combinação adequada às características do seu job:
|
Armazenamento para estado com chave |
Armazenamento para timers |
|
Memória |
|
|
Memória |
|
|
Memória |
|
|
Arquivo |
Os timers servem principalmente para acionar janelas expiradas. Armazene-os na memória para obter o melhor desempenho. Se houver muitos timers ou pouca memória disponível, utilize o RocksDBStateBackend para armazená-los em um arquivo RocksDB.