Ventana de Ingreso (Ingreso ventana)
window join
Ellos compartirán la misma key
y en los mismos elementos de la ventana acoplados entre sí dos corrientes. dispensador de ventana puede ser utilizado para definir estas ventanas, y se evaluó según los dos elementos de flujo.
El elemento se transfiere entonces a tanto definida por el usuario JoinFunction
o FlatJoinFunction
donde el usuario puede emitir los resultados satisfacen la condición de unión.
el uso general se puede resumir de la siguiente manera:
stream.join(otherStream)
.where(<KeySelector>)
.equalTo(<KeySelector>)
.window(<WindowAssigner>)
.apply(<JoinFunction>)
Algunas instrucciones sobre la semántica:
- Creación de elementos de las dos corrientes se comporta como un par combinación de
inner-join
elementos que significa que si una corriente de elementos que no desean conectarse con otra corriente del elemento correspondiente, no se emitirá el elemento. - Estos elementos no se incorporen a ser la mayor marca de tiempo (aún en la ventana correspondiente) como un sello de tiempo. Por ejemplo, [5, 10) resultará en un límite de ventana tiene un elemento de conexión 9 como su sello de tiempo.
En la siguiente sección, vamos a describir el uso de diferentes tipos de escenarios cuando algunos ejemplares window join
de comportamiento.
El caer de la ventana de Ingreso
En la ejecución Tumbling Window Join
, todos tienen un común key
y públicas Tumbling Window Join
elementos se combinan en pares por el acoplamiento, y se transmite a JoinFunction
o FlatJoinFunction
. Porque se comporta como un inner join
, no se emitirá tumbling window
ningún elemento en una corriente de elementos de otra corriente!
Como se muestra, definimos un tamaño de 2 ms Tumbling Window
, la ventana está en la forma de [0,1], [2,3], .... La figura muestra dos a dos combinaciones de todos los elementos en cada ventana, la ventana se transmitirán a la JoinFunction. Tenga en cuenta que, en la ventana de flip [6,7], ya que los elementos sean conectados y se unieron con naranja ⑥ elemento no existe en la corriente de verde, y por lo tanto no emite ningún contenido.
import org.apache.flink.streaming.api.windowing.assigners.SlidingEventTimeWindows;
import org.apache.flink.streaming.api.windowing.time.Time;
...
val orangeStream: DataStream[Integer] = ...
val greenStream: DataStream[Integer] = ...
orangeStream.join(greenStream)
.where(elem => /* select key */)
.equalTo(elem => /* select key */)
.window(TumblingEventTimeWindows.of(Time.milliseconds(2)))
.apply { (e1, e2) => e1 + "," + e2 }
Ventana corredera de Ingreso
Realizado Sliding Window Join
, todos con un común key
y públicas Sliding Window
elementos se agrupan en pares conectados por, y se pasan a JoinFunction
o FlatJoinFunction
. En la corriente Sliding Window
en una corriente Flujo No se emitirán sin elementos de otros elementos!
Tenga en cuenta que algunos elementos pueden ser conectados en una ventana deslizante, pero no se pueden conectar en otra ventana deslizante!
En este ejemplo, se utiliza el tamaño de la ventana deslizante de 2 ms 1 ms de tiempo de deslizamiento, a fin de llegar ventana [1,0] deslizante, [0,1], [1,2], [2,3], ... . Elementos de conexión por debajo del eje x se transmite a cada uno de los elementos JoinFunction ventana deslizante. Aquí también se puede ver, por ejemplo, cómo una naranja y verde ② ③ combinado en la ventana [2,3], pero no estaban vinculados a la verde ③ en la ventana [1,2].
import org.apache.flink.streaming.api.windowing.assigners.SlidingEventTimeWindows;
import org.apache.flink.streaming.api.windowing.time.Time;
...
val orangeStream: DataStream[Integer] = ...
val greenStream: DataStream[Integer] = ...
orangeStream.join(greenStream)
.where(elem => /* select key */)
.equalTo(elem => /* select key */)
.window(SlidingEventTimeWindows.of(Time.milliseconds(2) /* size */, Time.milliseconds(1) /* slide */))
.apply { (e1, e2) => e1 + "," + e2 }
Ventana de la sesión de Ingreso
Realizar Session Window Join
el mismo tiempo, tener una "combinación" satisface las condiciones de sesión key
de todos los elementos se pueden conectar entre sí de dos en dos en combinación, y se transmite a JoinFunction
o FlatJoinFunction
. Ejecuta de nuevo inner join
, por lo que si hay un Session Window Join
sólo contiene los elementos de una corriente, que no emitirá ninguna salida!
A continuación, se define un Session Window Join
conector, en el que el intervalo entre cada sesión de al menos 1 ms. Hay tres sesiones, dos sesión anterior, dos corrientes se transmiten al elemento de acoplamiento JoinFunction. En una tercera sesión, ningún elemento de flujo verde, y ⑧ ⑨ no están conectados!
import org.apache.flink.streaming.api.windowing.assigners.EventTimeSessionWindows;
import org.apache.flink.streaming.api.windowing.time.Time;
...
val orangeStream: DataStream[Integer] = ...
val greenStream: DataStream[Integer] = ...
orangeStream.join(greenStream)
.where(elem => /* select key */)
.equalTo(elem => /* select key */)
.window(EventTimeSessionWindows.withGap(Time.milliseconds(1)))
.apply { (e1, e2) => e1 + "," + e2 }
Intervalo de Join (Intervalo de Ingreso)
Interval Join
El público key
elemento de unión las dos corrientes (que ahora se conocen como A y B), el elemento B y el flujo de la corriente primaria que tiene un sello de tiempo A sello de tiempo es un intervalo de tiempo relativo .
Esto también puede expresarse como más formal b.timestamp ∈ [a.timestamp + lowerBound; a.timestamp + upperBound]
oa.timestamp + lowerBound <= b.timestamp <= a.timestamp + upperBound
Donde A y B son elementos de A y B, que comparten un común key
. Mientras el límite inferior es siempre menor o igual que el límite superior, los límites inferior y superior que puede ser negativo o positivo. Interval Join
La ejecución actual solamente inner joins
. Se transmite al par de elementos ProcessJoinFunction
, mayor serán asignados marcas de tiempo de dos elementos (a través de ProcessJoinFunction.Context
acceso).
Nota: Interval Join
Actualmente sólo es compatible con la hora del evento.
En el ejemplo anterior, las dos corrientes serán "naranja" y "verde" están conectados entre sí, el límite inferior -2 ms, el límite superior es +1 milisegundos. Por defecto, estos límites están incluidos, pero .lowerBoundExclusive()
, y .upperBoundExclusive
se pueden aplicar para cambiar el comportamiento.
notación más formal utilizado de nuevo, esto se traducirá en orangeElem.ts + lowerBound <= greenElem.ts <= orangeElem.ts + upperBound
como se muestra en un triángulo.
import org.apache.flink.streaming.api.functions.co.ProcessJoinFunction;
import org.apache.flink.streaming.api.windowing.time.Time;
...
val orangeStream: DataStream[Integer] = ...
val greenStream: DataStream[Integer] = ...
orangeStream
.keyBy(elem => /* select key */)
.intervalJoin(greenStream.keyBy(elem => /* select key */))
.between(Time.milliseconds(-2), Time.milliseconds(1))
.process(new ProcessJoinFunction[Integer, Integer, String] {
override def processElement(left: Integer, right: Integer, ctx: ProcessJoinFunction[Integer, Integer, String]#Context, out: Collector[String]): Unit = {
out.collect(left + "," + right);
}
});
});
Lectura sugerida:
https://ci.apache.org/projects/flink/flink-docs-release-1.9/dev/stream/operators/joining.html
https://github.com/perkinls/flink-local-train
https://yq.aliyun.com/users/ohyfzrwxmb3me?spm=a2c4e.11153940.0.0.763648d5EoX4bX