flink bufferTime缓冲区

1,870 阅读2分钟

今天在调试代码,关于timeWindow的例子,发现把timeWindow的相关代码注释掉了,发送一个数据,也会延迟很久才会进行计算。 如下代码

		env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
		DataStream<Tuple2<String, String>> map = env.socketTextStream("192.xxx.xxx.xxx", 9000)
				.map(new MapFunction<String, Tuple2<String, String>>() {
					@Override
					public Tuple2<String, String> map(String s) throws Exception {
						return new Tuple2<String, String>(s.split(",")[0], s.split(",")[1]);
					}
				});
		map.keyBy(0)
			.map(new MapFunction<Tuple2<String, String>, Object>() {
				@Override
				public Object map(Tuple2<String, String> value) throws Exception {
					return value;
				}
			}).print();
		env.execute("TestOrderMain");

以上代码没有用到window窗口,按理说是进来一条数据,应该马上就会执行一条数据,结果表现为:

  • 第一段map算子逻辑拿上会执行
  • 第二段keyby后的map算子逻辑代码会不定时延迟一会才会执行

然后一直一脸懵逼的发呆,突然在眼神游离之时就看到了这行代码

		env.setBufferTimeout(60*1000);

翻译成中文是缓存超时时间,冥冥之中感觉自己找到了,然后就疯狂google相关文档,整理为知识点以备不时之需。

控制执行时间

默认的,element在网络传输时不是一个个单独传输的(这会导致不必要的网络流量),而是缓存后传输

缓存(是在设备间传输的实际单位)的大小可以在Flink的配置文件中设置

ps:目前在配置文件中只找到该关于缓存的配置,若有不对,请及时指出

# The amount of memory going to the network stack. These numbers usually need 
# no tuning. Adjusting them may be necessary in case of an "Insufficient number
# of network buffers" error. The default min is 64MB, teh default max is 1GB.
# 
# taskmanager.network.memory.fraction: 0.1
# taskmanager.network.memory.min: 64mb
# taskmanager.network.memory.max: 1gb

尽管该方法有益于优化吞吐量,他会在stream到达不够快时导致执行时间方面的问题。为了控制吞吐量和执行时间,你可以在执行环境(或独立的Operator)中调用env.setBufferTimeout(timeoutMillis)来设置等待装满buffer的最大等待时间,在这个时间过后,不管buffer是否已满,它都会自动发出。该默认超时时间是100ms。

下例是设置API的用法:

LocalStreamEnvironment env = StreamExecutionEnvironment.createLocalEnvironment();
env.setBufferTimeout(timeoutMillis);

env.genereateSequence(1,10).map(new MyMapper()).setBufferTimeout(timeoutMillis);

要最大化吞吐量,设置setBufferTimeout(-1)来去除超时时间,则buffer仅在它满后才会被flush。要最小化执行时间,设置timeout为一个接近0的数字(如5ms或10ms)。应当避免设置Timeout为0,因为它会造成严重的性能下降。

最后设置为5ms解决了该问题