1. Connect
DataStream有两个connect方法:
public <R> ConnectedStreams<T, R> connect(DataStream<R> dataStream)
public <R> BroadcastConnectedStream<T, R> connect(BroadcastStream<R> broadcastStream)
前者是与普通DataStream连接,多用于把两个流合并;后者是与一个BroadcastStream连接,多用于受管理数据流的控制
ConnectedStream
该流主要包含两类操作:
- flatMap
public <R> SingleOutputStreamOperator<R> flatMap( CoFlatMapFunction<IN1, IN2, R> coFlatMapper)
CoFlatMapFunction包含两个方法,flatMap1和flatMap2,分别用于flatmap两个输入流的元素,两者互不相关。如果要使得两个流的数据发生关系,则要对ConnectedStream作keyby,然后使用Keyed status来暂存和处理数据
- process
public <R> SingleOutputStreamOperator<R> process(CoProcessFunction<IN1, IN2, R> coProcessFunction)
与CoFlatMapFunction类似,CoProcessFunction包含两个方法,processElement1和processElement2,分别用于process两个输入流的元素,两者互不相关。如果要使得两个流的数据发生关系,则要对ConnectedStream作keyby,然后使用Keyed status来暂存和处理数据
此外还提供了TimerService,可以在元素来临时注册定时器,由watermark来触发事件。
BroadcastConnectedStream
该流只包含process操作:
- process
public <OUT> SingleOutputStreamOperator<OUT> process(final BroadcastProcessFunction<IN1, IN2, OUT> function)
与CoProcessFunction类似,BroadcastProcessFunction包含两个方法,processElement和processBroadcastElement,分别用于process数据流的元素和广播流的元素,两者互不相关。如果要使得两个流的数据发生关系,则要使用BroadcastState
2. Join
DataStream的Join操作:
dataStream1.join(dataStream2)
.where(keySelector1)
.equalTo(keySelector2)
.window(win)
.apply(new JoinFunction<T1, T2, T> / FlatJoinFunction<T1, T2, T> function)
也就是两个流的数据必须:从数据中提取key,只有相同key的元素才能join;并且必须是在窗口中的元素才能join,且连接的方式是类似“Inner Join(内连接)”,也就是必须两个流都有这个key的元素才能join,且两个流中相同key的元素会两两执行function的操作。
- JoinFunction
该类包含一个方法OUT join(IN1 first, IN2 second) ,表示每两个流中的元素生成一个out元素
- FlatJoinFunction
该类包含一个方法void join (IN1 first, IN2 second, Collector<OUT> out) ,表示每两个流中的元素可生成多个out元素
3. CoGroup
DataStream的CoGroup操作:
dataStream1.coGroup(dataStream2)
.where(keySelector1)
.equalTo(keySelector2)
.window(win)
.apply(new CoGroupFunction<T1, T2, T> function)
与join十分类似,也就是两个流的数据必须:从数据中提取key,只有相同key的元素才能coGroup;并且必须是在窗口中的元素才能coGroup。但不同的是coGroup后的数据并不是两两作用function,而是将同一个window内两个流中所有相同key的数据都放到一起处理:
- CoGroupFunction
该类包含一个方法void coGroup(Iterable<IN1> first, Iterable<IN2> second, Collector<O> out) ,first、second分别表示window内两个流中具有相同key的元素,注意如果某个流在window内没有该key的元素,则可能为空。因此可以使用此方法实现“Left Join(左连接)”、“Right Join(右连接)”、“Full Join(全连接)”等语义,当然也能够兼容实现Join中实现的“Inner Join(内连接)”功能,只是没必要这么复杂。CoGroup比Join功能更为强大
4. Interval Join
DataStream的Interval Join操作:
dataStream1.keyBy(keySelector1)
.intervalJoin(dataStream2.keyBy(keySelector2))
.between(Time.milliseconds(-2), Time.milliseconds(1))
.process (new ProcessJoinFunction<Integer, Integer, String> function)
与普通Join不同的是,并不是在window内的元素join,而是dataStream1中元素与其前后若干时间区间的dataStream2的元素join
- ProcessJoinFunction
该类包含一个方法void processElement(IN1 left, IN2 right, Context ctx, Collector<OUT> out) ,与FlatJoinFunction功能类似,只是多了ctx可以用于查询left、right、out的时间戳,并且可以产生side output
总结:
相同点:
都是将两个流合成一个流不同点:
Connect:两个流的数据不一定要发生关系,可以各自单独处理、单独输出,但是输出的结果会合并成一个流。也可以使一个流不输出数据,而仅仅作为另一个流的控制状态。如果要使两个流的数据发生关系,则必须使用state
Join/CoGroup:两个流之间的数据会发生某种关联,需要对两个流的数据抽取key,并且加窗,将窗内的同key数据进行处理,共同生成新的流元素