文档章节

Flink 幕后之内存管理

moyiguke
 moyiguke
发布于 01/21 10:52
字数 1087
阅读 28
收藏 0

Flink 幕后之内存管理

引言

目前很多大数据处理框架,例如Hadoop、Spark、Storm、Flink等。它们都基于JVM语言开发(java or scala),运行在JVM上。为了加速合并或者排序(基于磁盘的方式通常要慢一些),需要将数据加载到内存中,由于数据量巨大,对内存是不小的压力。

数据存储最简单的做法是将封装成对象直接存储到如List或者Map这样的数据结构中。这种做法会引发两个问题。一个问题是数据规模大,需要创建的对象非常多(数据加上存储的数据结构,它们将耗费大量的内存),可能引发OOM。另一个问题是GC,源源不断的数据需要被处理,对象持续产生并需要被销毁,对GC来说是不小的压力。

鉴于JVM自带的GC无法满足高效稳定的流处理,Flink建立了一套自己的内存管理体系。

类图

Flink-memorymanager-diagram

MemorySegment

MemorySegment是Flink管理内存的最小单位,是内存的抽象。MemorySegment有两种实现,堆(HeapMemorySegment、基于JVM内存),非堆(HybridMemorySegment、混合,可使用JVM内存或者直接内存)。

用户可以通过配置决定使用哪一种,参数“taskmanager.memory.off-heap”默认false,使用堆;设置为true,使用非堆。

MemorySegment的实现做了一些优化。

  1. MemorySegment使用了较为底层的“sun.misc.Unsafe“。这里有一个典型的操作非堆的方式:将内存地址存储到address字段中,后续的通过index、offset的定位来读写数据。这种类C的写法,可以减少不必要的拷贝操作。
  2. 在Flink运行过程中,仅有一种MemorySegment实现类被加载(根据上述的配置),这样有利于JIT编译器的预热,通过使方法内连(method-inline)的方式降低调用的开销。

MemoryPool创建流程

flink-memory-manager-init-seq

MemoryPool

MemoryPool负责管理MemorySegment,例如创建、销毁、获取、重用等。

MemoryPool在初始化的时候,创建了空的ArrayDeque,之后申请内存加入到ArrayDeque中。内存申请有两种:new byte[segmentSize] -- 堆内存、ByteBuffer.allocateDirect(segmentSize) -- 直接内存。(SegmentSize由配置"taskmanager.memory.segment-size"指定,默认32kb) 。这两种不同类型的内存,在使用之前会由MemorySegmentFactory.wrapXXXHeapMemory包装一次,统一抽象成MemorySegment。

MemoryPool的生命周期很长,从TaskManager创建直至销毁。所以在任务执行期间它占用的内存(Segment)不会释放,而是通过回收来重复使用。MemoryPool通过减少对象的创建和回收,大大降低了GC压力。

需要注意的是:Flink不是将所有的对象都写入到MemoryPool管理的内存中。默认的,Flink分配70%的内存给MemoryManager。执行过程中还需要一些内存,例如用户实现的自定义函数,在函数中创建的对象存储在堆中,由JVM的GC机制管理。

序列化

Flink在内存管理之外,还有一套自己的序列化体系。在执行的过程中,数据对象通过序列化转换成字节,或者字节反序列化成对象。

以简单的ETL任务距离,抽取 --> 过滤 --> 存储,对象类型是提前预知的,调用对象的序列化即可。若用户需要加上自己的处理,抽取 --> 过滤 --> 转换 --> 存储。在转换的过程中,会引入Flink"未知"的对象类型。为了解决这种场景,Flink提供了一种基于反射的类型提取。用户需要提供TypeInformation来告知Flink类型信息,Flink根据类型自动选择合适的序列化方式。

创建TypeInformation:

TypeInformation<List<CommonLogBean>> typeInformation =
    TypeInformation.of(new TypeHint<List<CommonLogBean>>() {});

总结

Flink构建了一套特有的内存管理体系,降低了OOM的风险以及GC的负载,另外提供了智能高效的序列化方式。它们功能构成了高效的流处理基础。

重要参考

[flink-memory-manager]https://flink.apache.org/news/2015/05/11/Juggling-with-Bits-and-Bytes.html

© 著作权归作者所有

共有 人打赏支持
moyiguke
粉丝 13
博文 12
码字总数 20088
作品 0
杭州
程序员
私信 提问
作为一个编程新手,我再也不怕Flink迷了我的眼!

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由kyledong发表于云+社区专栏 使用 Flink 编写处理逻辑时,新手总是容易被林林总总的概念所混淆: 为什么 Flink 有那么多的类...

腾讯云+社区
2018/09/11
0
0
Flink技术源码解析(一):Flink概述与源码研读准备

一、前言 Apache Flink作为一款高吞吐量、低延迟的针对流数据和批数据的分布式实时处理引擎,是当前实时处理领域的一颗炙手可热的新星。关于Flink与其它主流实时大数据处理引擎Storm、Spark...

binggozhan
2018/06/06
0
0
Apache Flink和Apache Spark有什么异同?它们的发展前景分别怎样?

============================= object WordCount { def main(args: Array[String]) {val env = new SparkContext("local","wordCount")val data = List("hi","how are you","hi")val dataSe......

justlpf
2018/05/12
0
0
Apache 流框架 Flink,Spark Streaming,Storm对比分析(1)

此文已由作者岳猛授权网易云社区发布。 欢迎访问网易云社区,了解更多网易技术产品运营经验。 1.Flink架构及特性分析 Flink是个相当早的项目,开始于2008年,但只在最近才得到注意。Flink是原...

网易云社区
2018/10/31
0
0
Apache 流框架 Flink,Spark Streaming,Storm对比分析(一)

本文由 网易云 发布 1.Flink架构及特性分析 Flink是个相当早的项目,开始于2008年,但只在最近才得到注意。Flink是原生的流处理系统,提供high level的API。Flink也提供 API来像Spark一样进行...

wangyiyungw
2018/05/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

网站漏洞检测之WordPress 5.0.0 修复方案

2019年正月刚开始,WordPress最新版本存在远程代码注入获取SHELL漏洞,该网站漏洞影响的版本是wordpress5.0.0,漏洞的产生是因为image模块导致的,因为代码里可以进行获取目录权限,以及文件...

网站安全
41分钟前
0
0
MySql 优化 group by 语句

默认情况下,Mysql 对所有 group by 的字段进行排序,如果查询包括 group by ,用户想要避免排序结果的消耗。可以指定 order by null 禁止排序。 mysql> EXPLAIN select * from sys_log gro...

嘴角轻扬30
今天
9
0
Linux分区&格式化&文件系统&LVM&扩容

硬件 磁盘由 盘片组、主轴马达、机械臂、磁头、驱动芯片和电路、接口等构成 2. 磁盘的分割 每个盘片很多同心圆分割为磁道 Trace 一组盘片的同径磁道叫做一个柱面 Cylinder 每个磁道又被分为很...

可数局部基
今天
5
0
刷leetcode第705题- 设计哈希集合

这个我可能做的不是很符合题意,虽然AC了,但是没有去用到hash函数之类的方式。同样使用了位运算来搞定这一切,简单易懂。上代码如下: typedef char MyHashSet;/** Initialize your data ...

锟斤拷烫烫烫
今天
4
0
【spring】- springmvc 工作原理

核心:前端控制器:DispatcherServlet 功能:MVC设计模式中的Controller角色,掌控全局 类图 原理 本质是将DispatcherServlet及关联的Spring上下文环境的初始化工作织入Servlet的生命周期内,...

ZeroneLove
今天
11
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部