美文网首页
Flink内存模型详解

Flink内存模型详解

作者: 专职掏大粪 | 来源:发表于2020-05-06 13:11 被阅读0次

Flink 1.9内存模型

TaskManager 的堆内存主要被分成了三个部分:

NetworkBuffers: 一定数量的32KB大小的 MemorySegment,主要用于数据的网络传输。在 TaskManager 启动的时候就会分配。默认数量是 2048 个(NetworkBuffers),可以通过taskmanager.network.numberOfBuffers 来配置(注意,对于 Network Buffers,这一部分内存是在堆外(off-heap)进行分配的)

MemoryManager Pool: 由MemoryManager管理的,并由众多MemorySegment组成的超大集合.MemoryManager 负责将 MemorySegments 分配、计算和分发给数据处理Operator,例如 Batch模式下的sort / shuffle / join 等。Flink 中的算法(如 sort / shuffle / join)会向这个内存池申请 MemorySegment,将序列化后的数据存于其中,使用完后释放回内存池。默认情况下,池子占了堆内存的 70% 的大小。

注意MemoryManager 这一部分内存可以配置在堆上,也可以配置在堆外)


注意:Memory Manager Pool 主要在Batch模式下使用。在 Steaming 模式下,该池子不会预分配内存,也不会向该池子请求内存块。也就是说该部分的内存都是可以给用户代码使用的。


Remaining(Free) Heap: 这部分的内存是留给用户代码以及 TaskManager 的数据结构使用的。因为这些数据结构一般都很小,所以基本上这些内存都是给用户代码使用的。从 GC 的角度来看,可以把这里看成的新生代,也就是说这里主要都是由用户代码生成的短期对象。

▼MemorySegment

Flink并不是将大量对象存在堆上,而是将对象都序列化到一个预分配的内存块上,这个内存块叫做MemorySegment,它代表了一段固定长度的内存(默认大小为32KB),也是 Flink 中最小的内存分配单元,并且提供了非常高效的读写方法(Java 的 unsafe) 。你可以把MemorySegment想象成是为 Flink定制的java.nio.ByteBuffer。它的底层可以是一个普通的 Java字节数组(byte[]),也可以是一个申请在堆外的ByteBuffer。每条记录都会以序列化的形式存储在一个或多个MemorySegment中。MemorySegments 在TaskManager 启动时分配一次,并在 TaskManager 关闭时销毁。因此,在 TaskManager的整个生命周期中,MemorySegment 是重用的,而不会被垃圾收集的。在初始化 TaskManager的所有内部数据结构并且已启动所有核心服务之后,MemoryManager 开始创建MemorySegments。为了在更大的连续内存块上操作多个MemorySegment,Flink 使用了实现 Java 的 java.io.DataOutput 和 java.io.DataInput接口的逻辑视图。

Flink 1.10内存模型

NetworkBuffers:

使用Direct Memory

用于数据传输缓冲

特点:

同一Task Excutor内各slot之间没有隔离

需要多少有作业拓扑决定,不足时导致任务失败

MemoryManager:

使用Native Memory

用于RockesDBStateBackend和Batch 0prator (sort 和 join 等操作符)

HeapStateBackend or 无状态 可以将Memory memory内存设置为0,防止浪费资源

参考

https://mp.weixin.qq.com/s/K65OjUNM1Wf8Z5H9GS4zbg

https://mp.weixin.qq.com/s/ZTN9AaUFvhrRBz-WC-6a0A

https://mp.weixin.qq.com/s/ltzPIdJWOR_drnambp0XcQ

相关文章

网友评论

      本文标题:Flink内存模型详解

      本文链接:https://www.haomeiwen.com/subject/fqmightx.html