flink性能优化记录

性能分析

火焰图

开启火焰图,识别出了潜在的瓶颈,结合实际的代码进行分析,查看这些热点函数的实现,寻找可以优化的地方,比如减少循环次数、优化数据结构、减少同步操作

jvm

  1. jstack 分析线程状态
    jstack
    gc占用时间过多

  2. jstat 查看 gc信息
    jstat

  3. jmap 内存分析
    jmap -histo 113478 > map
    map
    对象实例过多,异常增长,怀疑内存泄漏

优化记录

算法优化

基于火焰图,减少系统调用函数

序列化优化

xuliehua
基于实现,选择性能更佳的序列化框架

算子优化

算子合并,减少序列化开销

数据结构优化

减少吞吐量、序列化开销

内存优化

基于jmap监控结果,解决存在的内存泄露问题

IO优化

  1. 减少IO次数
  2. kafka 攒批写配置优化
  3. redis pipeline的方式来提高性能

配置优化

选择合适的 GC 算法

Flink 主要在 JVM 上运行,因此选择合适的垃圾回收器是非常关键的。以下是一些常见的 GC 算法:

  • G1 GC(Garbage-First Garbage Collector):推荐用于大多数生产环境。它可以在低延迟和高吞吐量之间取得平衡。
  • CMS GC(Concurrent Mark-Sweep):适用于低延迟需求高的场景,但在堆内存较大的情况下可能表现不佳。
  • ZGC(Z Garbage Collector):适用于低延迟、高吞吐量需求的场景,但需要使用较新的 JDK 版本(JDK 11 及以上)。
  • Shenandoah GC:另一个低延迟的 GC 选项,适用于 JDK 8 和 JDK 11。

    设置 JVM 参数

    根据选择的 GC 算法设置合适的 JVM 参数。例如,使用 G1 GC 时,可以使用以下参数:
    1
    2
    3
    4
    5
    6
    -XX:+UseG1GC
    -XX:MaxGCPauseMillis=200
    -XX:InitiatingHeapOccupancyPercent=45
    -XX:G1ReservePercent=10
    -XX:ConcGCThreads=4
    -XX:ParallelGCThreads=4

这些参数可以根据实际情况进行调整。

调整堆内存大小

为 Flink 配置足够的堆内存,但不要过大,以免导致长时间的 Full GC。一般来说,可以使用以下参数来设置堆内存大小:

1
2
-Xms4G
-Xmx4G

确保 -Xms 和 -Xmx 设置为相同的值,以避免堆大小的动态调整带来的额外开销。

调整堆外内存

Flink 也使用堆外内存进行一些操作,特别是网络通信和 RocksDB 状态后端。如果使用 RocksDB,可以通过以下参数来限制堆外内存的使用:

1
-XX:MaxDirectMemorySize=8G

Flink 提供了一些配置选项,可以帮助优化 GC 性能:

  • taskmanager.memory.framework.off-heap.size:设置框架使用的堆外内存大小。
  • taskmanager.memory.managed.size:设置托管内存的大小,这部分内存将用于内部的内存管理和缓存。

    监控和分析 GC 日志

    启用 GC 日志可以帮助分析和优化垃圾回收性能。使用以下 JVM 参数启用 GC 日志:
    1
    2
    3
    4
    5
    6
    7
    -XX:+PrintGCDetails
    -XX:+PrintGCDateStamps
    -XX:+PrintGCTimeStamps
    -XX:+PrintAdaptiveSizePolicy
    -XX:+PrintGCApplicationStoppedTime
    -XX:+PrintPromotionFailure
    -Xloggc:/path/to/gc.log

使用工具如 GCViewer、GCEasy 或 GC Log Analyzer 来分析 GC 日志,找出潜在的性能问题。

避免 Full GC

尽量避免 Full GC,因为 Full GC 会导致长时间的暂停。以下是一些避免 Full GC 的策略:

  • 减少对象分配:优化代码,减少短生命周期对象的分配。
  • 使用 Flink 的对象复用机制:Flink 提供了对象复用选项,可以减少垃圾回收的压力。
  • 增大新生代内存:适当增加新生代内存,减少对象进入老年代的频率。

    调整并发 GC 线程数

    根据机器的 CPU 核心数调整并发 GC 线程数,可以通过以下参数设置:
    1
    2
    -XX:ConcGCThreads=4
    -XX:ParallelGCThreads=4

定期重启任务

对于长时间运行的流处理任务,可能会积累一些内存碎片,导致 GC 性能下降。定期重启任务可以帮助清理这些碎片。

使用分层存储

如果数据状态较大,可以考虑使用分层存储(如 RocksDB)来减少堆内存压力。RocksDB 可以将大部分数据存储在磁盘上,减少对堆内存的需求。