Realtime Compute for Apache Flink admite dos tipos de agregación de ventanas: la agregación de ventanas agrupadas y la agregación mediante funciones con valores de tabla (TVF) de ventanas. Este tema aborda su sintaxis, los escenarios en los que la agregación TVF de ventanas vuelve al modo sin TVF y la compatibilidad con flujos de actualización en los distintos tipos de ventanas.
Elección entre las dos sintaxis
|
Agregación de ventanas agrupadas |
Agregación TVF de ventanas |
|
|
Operador |
|
|
|
Funciones de ventana |
TUMBLE, HOP, SESSION |
TUMBLE, HOP, CUMULATE, SESSION |
|
Estado |
Obsoleto |
Recomendado |
|
Optimizaciones de rendimiento |
No |
Sí |
|
Compatibilidad con |
No |
Sí |
|
Top-N de ventanas tras la agregación |
No |
Sí |
|
Compatibilidad con flujos de actualización |
Sí (VVR) |
Sí (VVR, todos los tipos de ventanas) |
Utilice la agregación TVF de ventanas. Admite todos los tipos de ventanas de la agregación de ventanas agrupadas más CUMULATE, incluye optimizaciones de rendimiento y GROUPING SETS, y permite aplicar Top-N de ventanas sobre los resultados de la agregación.
Agregación de ventanas agrupadas (obsoleta)
La agregación de ventanas agrupadas define las ventanas en la cláusula GROUP BY. Corresponde al operador GroupWindowAggregation y es compatible con las funciones de ventana TUMBLE, HOP y SESSION.
Para consultar la sintaxis, ejemplos y detalles de las funciones, consulte Group window aggregation.
Cambio de comportamiento en VVR 11.x para la agregación de ventanas agrupadas
A partir de VVR 11.x (Flink 1.20), el sistema ya no reescribe automáticamente la agregación de ventanas agrupadas (sintaxis obsoleta) en un plan de ejecución de agregación TVF de ventanas.
En VVR 8.x, el sistema reescribía automáticamente la sintaxis obsoleta en el nuevo plan de ejecución de sintaxis, lo que habilitaba la optimización de agregación en dos fases Local-Global. A partir de VVR 11.x, esta reescritura automática dejó de ser el comportamiento predeterminado; la sintaxis obsoleta conserva su plan de ejecución física original.
Impacto: Los trabajos que utilizan la sintaxis obsoleta ya no se benefician automáticamente de la optimización de agregación en dos fases. El rendimiento puede degradarse en escenarios con grandes volúmenes de datos o desequilibrio en la distribución de datos.
Migre la agregación de ventanas agrupadas a la agregación TVF de ventanas (nueva sintaxis). Para conocer las condiciones que activan la optimización de agregación en dos fases, consulte Local-Global optimization for window aggregation.
Compatibilidad con el comportamiento anterior
Si la migración no es posible de inmediato, habilite el siguiente parámetro para restaurar el comportamiento de VVR 8.x:
|
Parámetro |
Descripción |
Valor predeterminado |
|
|
Habilita la reescritura automática de la sintaxis obsoleta a la nueva sintaxis, lo que activa la optimización de agregación en dos fases. |
false (desde VVR 11.x) |
Ejemplo de configuración (agregar a los parámetros del trabajo):
table.optimizer.window-rewrite-enabled: true
Este parámetro sirve únicamente como medida de compatibilidad transitoria durante las actualizaciones. La sintaxis obsoleta podría perder la compatibilidad con la reescritura en versiones futuras. Migre a la nueva sintaxis lo antes posible.
Agregación TVF de ventanas
La agregación TVF de ventanas define las ventanas mediante una cláusula GROUP BY que incluye las columnas window_start y window_end generadas por window TVFs. Corresponde al operador WindowAggregate y es compatible con las funciones de ventana TUMBLE, HOP, CUMULATE y SESSION.
A diferencia de la agregación en tablas continuas, la agregación TVF de ventanas no produce resultados intermedios, sino solo un resultado final al cierre de cada ventana. Los datos de estado intermedio se limpian automáticamente.
Para consultar la sintaxis, ejemplos y detalles de las funciones, consulte Window TVF aggregation.
Sintaxis de TVF de ventanas SESSION: VVR 11.x frente a VVR 8.x
La sintaxis de TVF de ventanas SESSION varía entre versiones de VVR. Actualice a VVR 11.1 o posterior para utilizar la sintaxis con todas las funciones disponibles.
VVR 11.x (Flink 1.20)
SESSION(TABLE data [PARTITION BY(keycols, ...)], DESCRIPTOR(timecol), gap)
|
Parámetro |
Descripción |
|
|
Una tabla con una columna de atributo de tiempo |
|
|
(Opcional) Columnas utilizadas para particionar los datos antes de aplicar la ventana de sesión |
|
|
La columna de atributo de tiempo asignada a las ventanas de sesión |
|
|
El intervalo de tiempo máximo entre dos eventos dentro de la misma sesión |
VVR 8.x (Flink 1.17)
SESSION(TABLE data, DESCRIPTOR(timecol), gap)
|
Parámetro |
Descripción |
|
|
Una tabla con una columna de atributo de tiempo |
|
|
La columna de atributo de tiempo asignada a las ventanas de sesión |
|
|
El intervalo de tiempo máximo entre dos eventos dentro de la misma sesión |
VVR 8.x no es compatible conPARTITION BY. Los campos de partición se infieren implícitamente de la cláusulaGROUP BY.
Comparación de sintaxis SESSION: VVR 11.x frente a VVR 8.x
|
VVR 11.x |
VVR 8.x |
|
|
Sintaxis |
|
|
|
Especificación del campo de partición |
Explícita — mediante |
Implícita — mediante la cláusula |
|
Restricciones del campo de partición |
Ninguna |
Debe estar en |
|
Uso independiente de |
Compatible |
Debe usarse con |
|
Combinación de función de ventana con agregación |
Compatible |
No compatible — la agregación debe coincidir con los campos de partición |
Los siguientes ejemplos son equivalentes. Ambos utilizan item como campo de partición.
-- The Bid table schema (used in all examples below)
> desc Bid;
+-------------+------------------------+------+-----+--------+---------------------------------+
| name | type | null | key | extras | watermark |
+-------------+------------------------+------+-----+--------+---------------------------------+
| bidtime | TIMESTAMP(3) *ROWTIME* | true | | | `bidtime` - INTERVAL '1' SECOND |
| price | DECIMAL(10, 2) | true | | | |
| item | STRING | true | | | |
+-------------+------------------------+------+-----+--------+---------------------------------+
-- VVR 11.x: partition field declared explicitly in SESSION()
> SELECT window_start, window_end, item, SUM(price) AS total_price
FROM TABLE(
SESSION(TABLE Bid PARTITION BY item, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES))
GROUP BY item, window_start, window_end;
-- VVR 8.x: partition field inferred from GROUP BY
> SELECT window_start, window_end, item, SUM(price) AS total_price
FROM TABLE(
SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES))
GROUP BY item, window_start, window_end;
|
VVR 11.x |
VVR 8.x |
|
|
Particionamiento de ventanas SESSION |
|
|
|
Agregación y combinación de ventanas |
Se admite la combinación directa (por ejemplo, |
Los campos de agregación deben coincidir con los campos de partición de la ventana (por ejemplo, |
Cuándo la agregación TVF de ventanas vuelve al modo sin TVF
Cuando una consulta incluye una TVF de ventanas pero no cumple las condiciones para combinar la TVF con la agregación, el sistema vuelve a un plan de ejecución sin TVF.
Si una consulta no combinable utiliza el tiempo de procesamiento como atributo de tiempo, la columna de tiempo de procesamiento se materializa y se usa como atributo de tiempo de las ventanas creadas. Esto provoca que la marca de agua de la tabla de origen afecte los resultados de la agregación: las ventanas pueden cerrarse antes de lo esperado y los datos tardíos pueden descartarse, igual que ocurre con las ventanas de tiempo de evento. Evite los patrones siguientes para prevenir esta situación.
La TVF de ventanas y la instrucción de agregación no se pueden combinar cuando se cumple alguna de las siguientes condiciones:
-
Filtrado o cálculo sobre campos de tiempo de ventana. Se filtra o modifica
window_start,window_endowindow_timeantes de la agregación.-- Filtering on window_start > SELECT window_start, window_end, item, SUM(price) AS total_price FROM (SELECT item, price, window_start, window_end FROM TABLE( SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES)) WHERE window_start >= TIMESTAMP '2020-04-15 08:06:00.000') GROUP BY item, window_start, window_end; -- Arithmetic on window_start > SELECT window_start, window_end, item, SUM(price) AS total_price FROM (SELECT item, price, window_start + (INTERVAL '1' SECOND) AS window_start, window_end FROM TABLE( SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES))) GROUP BY item, window_start, window_end; -- Type casting on window_start > SELECT window_start, window_end, item, SUM(price) AS total_price FROM (SELECT item, price, CAST(window_start AS varchar) AS window_start, window_end FROM TABLE( SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES))) GROUP BY item, window_start, window_end; -
Se utiliza una TVF de ventanas junto con una función con valores de tabla definida por el usuario (UDTF).
> SELECT window_start, window_end, category, SUM(price) AS total_price FROM (SELECT category, price, window_start, window_end FROM TABLE( SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES)), LATERAL TABLE(category_udtf(item)) AS T(category)) GROUP BY category, window_start, window_end; -
A la cláusula
GROUP BYle faltawindow_startowindow_end.> SELECT window_start, item, SUM(price) AS total_price FROM TABLE( SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES)) GROUP BY item, window_start; Se utiliza una función de agregación definida por el usuario (UDAF) de Python.
-
GROUPING SETS,CUBEoROLLUPagrupan por separado porwindow_startowindow_end.> SELECT item, SUM(price) AS total_price FROM TABLE( SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES)) GROUP BY GROUPING SETS((item), (window_start), (window_end)); > SELECT item, SUM(price) AS total_price FROM TABLE( SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES)) GROUP BY CUBE (item, window_start, window_end); > SELECT item, SUM(price) AS total_price FROM TABLE( SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES)) GROUP BY ROLLUP (item, window_start, window_end); -
Se aplica una función de agregación a
window_start,window_endowindow_time.> SELECT window_start, window_end, item, SUM(price) AS total_price, MAX(window_end) AS max_end FROM TABLE( SESSION(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '5' MINUTES)) GROUP BY item, window_start, window_end;
Compatibilidad con flujos de actualización
La siguiente tabla muestra la compatibilidad con flujos de actualización según la función de ventana y la sintaxis.
|
Función de ventana |
Sintaxis anterior (GroupWindowAggregation) — VVR |
Sintaxis anterior (GroupWindowAggregation) — Apache Flink |
Nueva sintaxis (WindowAggregate) — VVR |
Nueva sintaxis (WindowAggregate) — Apache Flink |
|
TUMBLE |
Sí |
Sí |
Sí |
No |
|
HOP |
Sí |
Sí |
Sí |
No |
|
SESSION |
Sí |
Sí |
Sí |
Sí (Apache Flink 1.19 y posteriores) |
|
CUMULATE |
N/A |
N/A |
Sí (VVR 8.0.6 y posteriores) |
No |
En la sintaxis anterior, la compatibilidad con flujos de actualización es idéntica tanto si se usa VVR como Apache Flink. En la nueva sintaxis, solo el operador WindowAggregate de VVR admite flujos de actualización para todas las funciones de ventana. VVR selecciona automáticamente entre los operadores GroupWindowAggregation y WindowAggregate según el flujo de entrada.
Para conocer las diferencias entre la función de ventana SESSION en VVR y Apache Flink, consulte Queries .
Optimización Local-Global para la agregación de ventanas
La agregación de ventanas admite la optimización de agregación en dos fases Local-Global. Cuando está habilitada, el optimizador divide una agregación de ventanas de fase única en:
Local Aggregate: realiza una preagregación parcial antes de la redistribución de datos, lo que reduce la cantidad de datos transferidos por la red.
Global Aggregate: realiza la agregación final después de la redistribución y genera los resultados.
Deben cumplirse las seis condiciones siguientes para que esta optimización surta efecto.
Condición 1: La estrategia de fase de agregación permite dos fases
table.optimizer.agg-phase-strategy está establecido en AUTO (predeterminado) o TWO_PHASE. Establecerlo en ONE_PHASE deshabilita la optimización de dos fases.
Condición 2: La ventana utiliza tiempo de evento
La ventana debe utilizar tiempo de evento (rowtime). Las ventanas de tiempo de procesamiento no son compatibles.
Condición 3: El tipo de ventana no es SESSION
Los tipos de ventana TUMBLE, HOP y CUMULATE son compatibles. Las ventanas SESSION no admiten la optimización de dos fases.
Condición 4: Todas las funciones de agregación admiten combinación parcial
Todas las funciones de agregación deben admitir la operación de combinación. Las funciones integradas como SUM, COUNT, MIN, MAX y AVG son compatibles. Las UDAF personalizadas deben implementar el método merge().
Condición 5: El flujo de entrada es de solo inserción y la ventana se puede convertir a formato TVF
Deben cumplirse todas las condiciones siguientes:
El flujo de entrada es de solo inserción.
table.exec.emit.early-fire.enabledestá establecido enfalse(predeterminado).table.exec.emit.late-fire.enabledestá establecido enfalse(predeterminado).Para ventanas HOP, la ventana debe estar alineada (el tamaño de la ventana debe ser divisible por el intervalo de deslizamiento).
Condición 6: La distribución de datos no satisface ya los requisitos de particionamiento
La distribución de datos de entrada no cumple todavía con los requisitos de particionamiento para la agregación. Si los datos ya están distribuidos por la clave de partición, el optimizador determina que no se necesita preagregación adicional y no genera un nodo Local Aggregate.
Referencia de parámetros
|
Parámetro |
Tipo |
Valor predeterminado |
Requisito |
|
|
Enum |
AUTO |
No debe ser ONE_PHASE |
|
|
Boolean |
false |
Debe ser false |
|
|
Boolean |
false |
Debe ser false |