一、概述

Flink 提供的存储服务包括内存管理服务和文件管理服务,TaskManager 启动时也会初始化 I/O 管理组件 IOManager,负责将数据输出到磁盘并将其读取回来以及内存管理组件 MemoryManager 负责协调内存使用。

二、内存管理

Flink 为了让用户更好的调整内存分配,达到资源的合理分配,在 Flink1.10 引入了 TaskManager 的内存管理,后续在 Flink1.11 版本引入了 JobManager 的内存管理,用户可以通过配置的方式合理的分配资源。不管是 TaskManager 还是 JobManager 都是单独的 JVM 进程,共用一套内存模型抽象(TaskManager 的内存模型更加复杂), Flink 从一开始就选择了使用自主的内存管理,避开了 JVM 内存管理在大数据场景下的问题,提升了计算效率。

2.1. 架构设计

Flink 的 JVM 的进程总内存(Total Process Memory) 包含了 Flink 总内存(Total Flink Memory) 和运行 Flink 的 JVM 特定内存(JVM Specific Memory),Flink 将内存划分成不同的区域,实现了更加精准地内存控制。

内存

2.2. 实现

MemorySegment 就是 Flink 的内存抽象。默认情况下一个 MemorySegment 可以被看做是一个 32kb 的内存块的抽象。NetworkBuffer 是对 MemorySegment 的封装。Flink 在各个 TaskManager 之间传递数据时,使用的是这一层的抽象。

三、文件系统

3.1.概述

Flink 通过 IOManager 管理磁盘 I/O 过程,提供了同步和异步两种写模式,又进一步区分了 block、buffer 和 buk 三种读写方式,在底层,flink 将文件 I/O 抽象为 FileIOChannle,封装了底层实现。

Flink 通过 org.apache.flink.core.fs.FileSystem 类拥有自己的文件系统抽象。这种抽象提供了一组通用操作,并为各种类型的文件系统实现提供了最低限度的保证。

为了支持广泛的文件系统,FileSystem 的可用操作集非常有限。例如,不支持追加和修改现有文件。文件系统由文件系统方案来标识,如 File://hdfs:// 等。
FileSystem 连接器提供了对 Flink 文件系统抽象所支持的文件系统中的分区文件进行访问,FileSystem 连接器允许从本地或分布式文件系统进行读写 (Flink支持的抽象文件系统)。

https://blog.csdn.net/u010772882/article/details/125590872

FileChannelManager 创建文件并创建响应的channel,同时定义 FileChannelInputView 作为数据写入的入口 IOManager 定义了统一的channel 创建入口,可以生成的统一的 writer。

3.2. 使用场景

3.2.1. 状态后端存储

FsStateBackend 运行时所需要的 State 数据保存在 TaskManger 的内存中,执行检查点的时候,会把 State 的快照数据保存到配置的文件系统中,可以使用分布式文件系统或本地文件系统,如使用 HDFS 的路径为 hdfs://namenode:40010/flink/checkpoints,使用本地文件系统的路径为 file:///data/flink/checkpoints

3.2.2. 容错

  1. checkpoint
  2. savepoint

3.2.3.溢出

在 MemorySegment 中如果因为内存空间不足,无法申请到更多的内存区域来存储对象时,Flink 会将 MemorySegment 中的数据溢写到本地文件系统(SSD/HDD)中。当再次需要操作数据时,会直接从磁盘中读取数据保证系统不会因为内存不足而导致 OOM (Out Of Memory,超出内存空问),影响整个系统的稳定运行。

3.3. 实现