[关闭]
@marlin 2016-08-17T15:14:24.000000Z 字数 1049 阅读 5148

Flink长时间运行出现gc异常

flink gc 性能


flink在使用中经常被用在流处理场景上,比如每30秒计算一次180秒窗口数据的统计结果,又可能最终需要计算的结果不是简单的汇总值,而是需要在全量数据上进行反复计算才能得到的结果。在这种场景下,flink就可能出现性能瓶颈问题:

  1. 数据倾斜,比如需要计算的数据按key进行group后,某个key的数据量占所有数据流量的20%;
  2. 计算周期,如果计算周期过短,会导致计算任务堆积

由于flink会将task的并行运行在多个slot(即thread)上,那么当对数据进行keyby后,相同key会由且只由该slot进行处理,那么该key上数据量很大时,处理该key数据的thread就会承担很大的压力,又这部分用户代码逻辑会运行在jvm之上,这就可能会对gc造成影响。

另外一个有重要影响的因素是snapshot,由于flink使用的默认checkpoint机制是MemoryStateBacked,这种snapshot方式是将state信息(包括:kv state和window中的values、trigger等)通过调用snapshot方法获取,并通过akka的message发送给jobmanager(master),并将其保存在master的内存中。这种方法的限制:1.每个独立的state默认不能超过5MB;2.就算抛开state大小限制,这个状态信息也不能超过akka一个frame的大小;3.最后所有状态信息的累积不能超过jobmanager内存大小。这种state的机制可以用在1.开发和调试中;2.job中只有很小的状态信息。

当job具有很大的状态信息、长时间的窗口或存在高可用的需求时,应该选用FsStateBackendRocksDBStateBackend对状态进行存储。

由于flink性能测试集群中错误地使用了MemoryStateBacked,并且给了很长的时间窗口。在数据倾斜[1]大数据流量[2]大窗口[3]的情况下,系统在运行一段时间之后爆出了gc问题。在这种情况下,使得对数据倾斜问题没能合理分析。暂时给出一半的结论,即在不使用snapshot时,同时gc选用g1gc策略,内存使用情况是周期性的,随着gc进行,内存中的累计数据会增多,当到一定程度后,gc会把累计数据做一次清空,之后循环这个过程,整体jvm内存使用情况是锯齿状。同时猜测另一半结论:当把state存储的方式改成上述两种之一后,整体的gc情况应该是类似的。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注