Flink-内存管理

首先,此篇文章原版是大神zhisheng写的,我只是学习zhisheng并且做一个记录自己总结一下,水平一般

  1. Flink是如何管理内存的
    大多数的对象都是存储到内存中,而flink有着自己独特的管理内存的方式

Flink 将对象序列化为固定数量的预先分配的内存段,⽽不是直接把对象放在堆内存
上。它的 DBMS ⻛格的排序和连接算法尽可能多地对这个⼆进制数据进⾏操作,以
此将序列化和反序列化开销降到最低。如果需要处理的数据多于可以保存在内存中
的数据,Flink 的运算符会将部分数据溢出到磁盘

flink自主管理内存有以下好处

  • 内存安全执⾏和⾼效的核外算法 由于分配的内存段的数量是固定的,因此监控
    剩余的内存资源是⾮常简单的。在内存不⾜的情况下,处理操作符可以有效地将更
    ⼤批的内存段写⼊磁盘,后⾯再将它们读回到内存。因此,OutOfMemoryError 就
    有效的防⽌了。
  • 减少垃圾收集压⼒ 因为所有⻓⽣命周期的数据都是在 Flink 的管理内存中以⼆进
    制表示的,所以所有数据对象都是短暂的,甚⾄是可变的,并且可以重⽤。短⽣命
    周期的对象可以更有效地进⾏垃圾收集,这⼤⼤降低了垃圾收集的压⼒。现在,预
    先分配的内存段是 JVM 堆上的⻓期存在的对象,为了降低垃圾收集的压⼒,Flink
    社区正在积极地将其分配到堆外内存。这种努⼒将使得 JVM 堆变得更⼩,垃圾收集
    所消耗的时间将更少。
  • 节省空间的数据存储 Java 对象具有存储开销,如果数据以⼆进制的形式存储,
    则可以避免这种开销。
  • ⾼效的⼆进制操作和缓存敏感性 在给定合适的⼆进制表示的情况下,可以有效
    地⽐较和操作⼆进制数据。此外,⼆进制表示可以将相关值、哈希码、键和指针等
    相邻地存储在内存中。这使得数据结构通常具有更⾼效的缓存访问模式。

Flink-内存管理

  1. Flink 如何分配内存?

Flink TaskManager 是由⼏个内部组件组成的:actor 系统(负责与 Flink master 协
调)、IOManager(负责将数据溢出到磁盘并将其读取回来)、
MemoryManager(负责协调内存使⽤

MemoryManager 负责将 MemorySegments 分配、计算和分发给数据处理操作符,例如 sort 和 join 等操作符.MemorySegment 是 Flink 的内存分配单元,由常规 Java 字节数组⽀持(默认⼤⼩为 32 KB)。MemorySegment 通过使⽤ Java 的unsafe ⽅法对其⽀持的字节数组提供⾮常有效的读写访问。

在TaskManager启动时,MemoryManager会被分配一次,当TaskManager关闭时,MemoryManager也会被销毁.在 TaskManager 的整个⽣命周期中,MemorySegment 是重⽤的,⽽不会被垃圾收集的。在初始化 TaskManager 的所有内部数据结构并且已启动所有核⼼服务之后,MemoryManager 开始创建 MemorySegments。默认情况下,服务初始化后,70% 可⽤的 JVM 堆内存由 MemoryManager 分配(也可以配置全部)。剩余的 JVM 堆内存⽤于在任务处理期间实例化的对象,包括由⽤户定义的函数创建的对象.

  1. Flink如何序列化对象
    Flink 包含⾃⼰的⾃定义序列化框架,以便控制数据的⼆进制表示。这⼀点很重要,因为对⼆进制数据进⾏操作需要对序列化布局有准确的了解.此外,根据在⼆进制数据上执⾏的操作配置序列化布局可以显著提升性能。Flink 的序列化机
    制利⽤了这⼀特性,即在执⾏程序之前,要序列化和反序列化的对象的类型是完全已知的。

Flink 使⽤ TypeInformation 表示每种数据类型
Flink-内存管理

Flink-内存管理