flink深入研究(05) 算子operator

flink的整个数据处理流程是由一个个operator组成的,数据从源头开始传递给一个个operator进行链式处理,每一个处理逻辑就是一个operator,一个operator包含一个输入、一个处理逻辑、一个输出,operator是在TaskManager的slot中执行的,一个slot就是一个线程,一个operator只能在一个slot中执行,一个slot中可以运行多个operator(同一个job任务),flink会进行优化将多个operator放在一个slot中运行,它能减少线程之间的切换,减少消息的序列化/反序列化,减少数据在缓冲区的交换,减少了延迟的同时提高整体的吞吐量。根据我们之前给出的示例,我们来看看都有哪些operator,

source operator

DataStreamSource<String> text = env.socketTextStream("localhost", port, "\n")

transform operator

// 计算数据
		DataStream<WordWithCount> windowCount = text.flatMap(new FlatMapFunction<String, WordWithCount>() {
			public void flatMap(String value, Collector<WordWithCount> out) throws Exception {
				String[] splits = value.split(" ");
				for (String word : splits) {
					out.collect(new WordWithCount(word, 1L));
				}
			}
		})// 打平操作,把每行的单词转为<word,count>类型的数据
				.keyBy("word")// 针对相同的word数据进行分组
				.timeWindow(Time.seconds(8), Time.seconds(1))// 指定计算数据的窗口大小和滑动窗口大小
				.sum("count");

sink operator

// 把数据打印到控制台
windowCount.print();

flink的执行流程总是以source operator开头,sink operator结尾,中间夹杂一些transform operator。

下面是运行逻辑图:

flink运行图片
flink运行示意图

这个示例中flink将source、flatmap、window、sum、sink合并成一个chain放在同一个slot中运行(如果这里的并行度不一样,那么就不会放在一个chain中,具体例子可以看下面的参考文档),那么什么条件下slot会组合成一个chain呢?

1、上下游的并行度一致

2、下游节点的入度为1 (也就是说下游节点没有来自其他节点的输入)

3、上下游节点都在同一个 slot group 中(下面会解释 slot group)

4、下游节点的 chain 策略为 ALWAYS(可以与上下游链接,map、flatmap、filter等默认是ALWAYS)

5、上游节点的 chain 策略为 ALWAYS 或 HEAD(只能与下游链接,不能与上游链接,Source默认是HEAD)

6、两个节点间数据分区方式是 forward(一对一,没有shuffle)

7、用户没有禁用 chain

多个operator可以组成一个chain,可以作为一个新的operator,不同的operator可以运行在同一个slot中。

参考文档

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章