问题描述
对于Flink流/ Flink有状态功能,已知将setBufferTimeout
设置为较小的值(例如5ms)将提供“最佳”延迟体验。在针对Flink流或有状态功能作业的延迟进行优化时,还必须注意(设置,重置,修改..)其他建议配置值是什么?
解决方法
端到端延迟受许多因素影响。忽略Flink吸收事件之前产生的延迟,这使这些问题得以考虑:
- 网络缓冲区超时
- 序列化
- 对象重用
- 加水印延迟(用于解决乱序事件)
- 自动加水印间隔
- 状态访问(取决于状态后端)
- 垃圾收集
- 计时器
- 聚合(例如窗口化)
- 交易接收器
- 检查点
- 背压
利用运营商链。避免不必要地使用keyBy和更改并行性。在适当的地方使用reinterpretAsKeyedStream
。
以上几点将有助于避免不必要的序列化,但是您还应注意优化序列化。使用慢速序列化程序可能会产生巨大影响,就像使用复杂的,深度嵌套的集合类型(这样做会更简单)一样,也会产生巨大的影响。
您应该始终启用对象重用。默认情况下,Flink防御性地制作沿操作员链传递的对象的副本。启用对象重用时,请记住
不安全- 记住跨函数调用的输入对象引用或
- 修改输入对象
如果您避免这两点,则可能
- 修改输出对象,然后再次发射
如果使用事件时间处理,则最佳情况是能够依靠具有递增的时间戳,并相应地生成水印(零延迟)。如果您正在开窗,则进行预聚合将避免在关闭窗口时造成负载峰值,并且配置较短的自动加水印间隔将有助于最大程度地减少延迟。
FsStateBackend将状态保持为堆上的对象,然后将对象置于GC之下。此状态后端具有最佳的平均延迟,但是您将需要仔细调整垃圾回收器,以避免GC停顿。尽管总体上要慢得多,但RocksDB状态后端可能具有更好的最坏情况延迟,尤其是在每个任务管理器需要运行许多任务插槽的情况下。使用FsStateBackend,每个TM一个插槽将使GC的范围变小,从而有助于减少延迟。
避免同时触发多个计时器。安排窗口以使不同的键在不同的时间触发。
请记住,事务接收器的下游使用者将经历由检查点间隔控制的延迟。
如果您不需要一次保证,可以通过将检查点配置为使用CheckpointConfigInfo.ProcessingMode.AT_LEAST_ONCE
来禁用检查点屏障对齐。
最后,请尽一切可能避免背压。给工作提供足够多的资源。不要在用户功能中进行任何阻塞I / O。尝试避免数据偏斜(热键)。