最小延迟的 Flink 最佳配置
Flink optimal configuration for minimum Latency
对于 Flink streaming / Flink stateful function,众所周知 setBufferTimeout
到较小的值(例如 5ms)会产生 'best' 延迟体验。在优化 Flink 流或有状态函数作业中的延迟时,必须注意的其他推荐配置值是什么(设置、重置、修改……)?
End-to-end 延迟受很多因素影响。忽略事件被 Flink 摄取之前累积的延迟,这留下了这些问题需要考虑:
- 网络缓冲区超时
- 序列化
- 对象重用
- 水印延迟(用于适应 out-of-order 事件)
- auto-watermarking区间
- 状态访问(状态后端依赖)
- 垃圾收集
- 计时器
- 聚合(例如,开窗)
- 交易汇
- 检查点
- 背压
利用运营商链。避免不必要地使用 keyBy 和更改并行度。在适当的地方使用 reinterpretAsKeyedStream
。
以上几点将有助于避免不必要的序列化,但您也应该注意优化序列化。使用缓慢的序列化程序会产生巨大的影响,就像使用复杂的、深度嵌套的集合类型一样,而使用更简单的方法就可以做到。
您应该始终启用对象重用。默认情况下,Flink 会防御性地复制对象,这些对象会沿着运算符链向下传递。启用对象重用时,请记住它 不安全 到
- 记住跨函数调用的输入对象引用或
- 修改输入对象
如果你避开这两点,你可能
- 修改一个输出对象并再次发出它
如果您使用的是事件时间处理,最佳情况是能够依赖升序时间戳,并相应地生成水印(零延迟)。如果您正在使用窗口,执行 pre-aggregation 将避免负载峰值,因为 windows 已关闭,配置较短的 auto-watermarking 间隔将有助于最大限度地减少延迟。
FsStateBackend 将状态作为堆上的对象进行维护,然后这些对象将受到 GC 的约束。此状态后端具有最好的平均延迟,但您需要仔细调整垃圾收集器以避免 GC 停顿。虽然总体上慢得多,但 RocksDB 状态后端可能有更好的 worst-case 延迟,特别是如果你需要 运行 每个任务管理器有许多任务槽。使用 FsStateBackend,每个 TM 一个插槽将使 GC 的范围更小,这有助于减少延迟。
避免同时触发多个计时器。安排 windows 不同的键在不同的时间触发。
请记住,事务接收器的下游消费者将经历由检查点间隔控制的延迟。
如果您不需要 exactly-once 保证,请通过配置检查点使用 CheckpointConfigInfo.ProcessingMode.AT_LEAST_ONCE
.
来禁用检查点屏障对齐
在某些情况下,未对齐的检查点非常有用。
最后,尽一切可能避免背压。给工作 more-than-adequate 资源。不要在你的用户函数中做任何阻塞 i/o。尽量避免数据倾斜(热键)。
对于 Flink streaming / Flink stateful function,众所周知 setBufferTimeout
到较小的值(例如 5ms)会产生 'best' 延迟体验。在优化 Flink 流或有状态函数作业中的延迟时,必须注意的其他推荐配置值是什么(设置、重置、修改……)?
End-to-end 延迟受很多因素影响。忽略事件被 Flink 摄取之前累积的延迟,这留下了这些问题需要考虑:
- 网络缓冲区超时
- 序列化
- 对象重用
- 水印延迟(用于适应 out-of-order 事件)
- auto-watermarking区间
- 状态访问(状态后端依赖)
- 垃圾收集
- 计时器
- 聚合(例如,开窗)
- 交易汇
- 检查点
- 背压
利用运营商链。避免不必要地使用 keyBy 和更改并行度。在适当的地方使用 reinterpretAsKeyedStream
。
以上几点将有助于避免不必要的序列化,但您也应该注意优化序列化。使用缓慢的序列化程序会产生巨大的影响,就像使用复杂的、深度嵌套的集合类型一样,而使用更简单的方法就可以做到。
您应该始终启用对象重用。默认情况下,Flink 会防御性地复制对象,这些对象会沿着运算符链向下传递。启用对象重用时,请记住它 不安全 到
- 记住跨函数调用的输入对象引用或
- 修改输入对象
如果你避开这两点,你可能
- 修改一个输出对象并再次发出它
如果您使用的是事件时间处理,最佳情况是能够依赖升序时间戳,并相应地生成水印(零延迟)。如果您正在使用窗口,执行 pre-aggregation 将避免负载峰值,因为 windows 已关闭,配置较短的 auto-watermarking 间隔将有助于最大限度地减少延迟。
FsStateBackend 将状态作为堆上的对象进行维护,然后这些对象将受到 GC 的约束。此状态后端具有最好的平均延迟,但您需要仔细调整垃圾收集器以避免 GC 停顿。虽然总体上慢得多,但 RocksDB 状态后端可能有更好的 worst-case 延迟,特别是如果你需要 运行 每个任务管理器有许多任务槽。使用 FsStateBackend,每个 TM 一个插槽将使 GC 的范围更小,这有助于减少延迟。
避免同时触发多个计时器。安排 windows 不同的键在不同的时间触发。
请记住,事务接收器的下游消费者将经历由检查点间隔控制的延迟。
如果您不需要 exactly-once 保证,请通过配置检查点使用 CheckpointConfigInfo.ProcessingMode.AT_LEAST_ONCE
.
在某些情况下,未对齐的检查点非常有用。
最后,尽一切可能避免背压。给工作 more-than-adequate 资源。不要在你的用户函数中做任何阻塞 i/o。尽量避免数据倾斜(热键)。