随着 Flink K8s 化以及实时集群迁移完成,有赞越来越多的 Flink 实时任务运行在 K8s 集群上,Flink K8s 化提升了实时集群在大促时弹性扩缩容能力,更好的降低大促期间机器扩缩容的成本。同时,由于 K8s 在公司内部有专门的团队进行维护, Flink K8s 化也能够更好的减低公司的运维成本。
不过当前 Flink K8s 任务资源是用户在实时平台端进行配置,用户本身对于实时任务具体配置多少资源经验较少,所以存在用户资源配置较多,但实际使用不到的情形。比如一个 Flink 任务实际上 4 个并发能够满足业务处理需求,结果用户配置了 16 个并发,这种情况会导致实时计算资源的浪费,从而对于实时集群资源水位以及底层机器成本,都有一定影响。基于这样的背景,本文从 Flink 任务内存以及消息能力处理方面,对 Flink 任务资源优化进行探索与实践。
一、Flink 计算资源类型与优化思路
1.1 Flink 计算资源类型
一个 Flink 任务的运行,所需要的资源我认为能够分为 5 类:
- 内存资源
- 本地磁盘(或云盘)存储
- 依赖的外部存储资源。比如 HDFS、S3 等(任务状态/数据),HBase、MySQL、Redis 等(数据)
- CPU 资源
- 网卡资源
目前 Flink 任务使用最主要的还是内存和 CPU 资源,本地磁盘、依赖的外部存储资源以及网卡资源一般都不会是瓶颈,所以本文我们是从 Flink 任务的内存和 CPU 资源,两个方面来对 Flink 实时任务资源进行优化。
1.2 Flink 实时任务资源优化思路
对于 Flink 实时任务资源分析思路,我们认为主要包含两点:
- 一是从任务内存视角,从堆内存方面对实时任务进行分析。
- 另一方面则是从实时任务消息处理能力入手,保证满足业务方数据处理需求的同时,尽可能合理使用 CPU 资源。
之后再结合实时任务内存分析所得相关指标、实时任务并发度的合理性,得出一个实时任务资源预设值,在和业务方充分沟通后,调整实时任务资源,最终达到实时任务资源配置合理化的目的,从而更好的降低机器使用成本。
1.2.1 任务内存视角
那么如何分析 Flink 任务的堆内存呢?这里我们是结合 Flink 任务 GC 日志来进行分析。GC 日志包含了每次 GC 堆内不同区域内存的变化和使用情况。同时根据 GC 日志,也能够获取到一个 Taskmanager 每次 Full GC 后,老年代剩余空间大小。可以说,获取实时任务的 GC 日志,使我们进行实时任务内存分析的前提。
GC 日志内容分析,这里我们借助开源的 GC Viewer 工具来进行具体分析,每次分析完,我们能够获取到 GC 相关指标,下面是通过 GC Viewer 分析一次 GC 日志的部分结果:
上面通过 GC 日志分析出单个 Flink Taskmanager 堆总大小、年轻代、老年代分配的内存空间、Full GC 后老年代剩余大小等,当然还有很多其他指标,相关指标定义可以去 Github 具体查看。
这里最重要的还是Full GC 后老年代剩余大小这个指标,按照《Java 性能优化权威指南》这本书 Java 堆大小计算法则,设 Full GC 后老年代剩余大小空间为 M,那么对的大小建议 3 ~ 4倍 M,新生代为 1 ~ 1.5 倍 M,老年代应为 2 ~ 3 倍 M,当然,真实对内存配置,你可以按照实际情况,将相应比例再调大些,用以防止流量暴涨情形。
所以通过 Flink 任务的 GC 日志,我们可以计算出实时任务推荐