Flink 原理与实现:内存管理.docxVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
Flink 原理与实现:内存管理 Flink 并不是将大量对象存在堆上,而是将对象都序列化到一个预安排的内存块上,这个内存块叫做 MemorySegment,它代表了一段固定长度的内存(默认大小为 32KB),也是 Flink 中最小的内存安排单元,并且供应了格外高效的读写方法。你可以把 MemorySegment 想象成是为 Flink 定制的 java.nio.ByteBuffer。它的底层可以是一个一般的 Java 字节数组(byte[]),也可以是一个申请在堆外的 ByteBuffer。每条记录都会以序列化的方式存储在一个或多个MemorySegment中。 Flink 中的 Worker 名叫 TaskManager,是用来运转用户代码的 JVM 进程。TaskManager 的堆内存次要被分成了三个部分: Network Buffers:?肯定数量的32KB大小的 buffer,次要用于数据的网络传输。在 TaskManager 启动的时候就会安排。默认数量是 2048 个,可以通过 taskmanager.network.numberOfBuffers 来配置。(阅读这篇文章了解更多Network Buffer的管理) Memory Manager Pool:?这是一个由 MemoryManager 管理的,由众多MemorySegment组成的超大集合。Flink 中的算法(如 sort/shuffle/join)会向这个内存池申请 MemorySegment,将序列化后的数据存于其中,使用完后释放回内存池。默认情况下,池子占了堆内存的 70% 的大小。 Remaining (Free) Heap:?这部分的内存是留给用户代码以及 TaskManager 的数据结构使用的。由于这些数据结构一般都很小,所以基本上这些内存都是给用户代码使用的。从GC的角度来看,可以把这里看成的重生代,也就是说这里次要都是由用户代码生成的短期对象。 留意:Memory Manager Pool 次要在Batch模式下使用。在Steaming模式下,该池子不会预安排内存,也不会向该池子恳求内存块。也就是说该部分的内存都是可以给用户代码使用的。不过社区是打算在 Streaming 模式下也能将该池子利用起来。 Flink 接受类似 DBMS 的 sort 和 join 算法,直接操作二进制数据,从而使序列化/反序列化带来的开销达到最小。所以 Flink 的内部实现更像 C/C++ 而非 Java。假如需要处理的数据超出了内存限制,则会将部分数据存储到硬盘上。假如要操作多块MemorySegment就像操作一块大的连续内存一样,Flink会使用规律视图(AbstractPagedInputView)来便利操作。下图描述了 Flink 如何存储序列化后的数据到内存块中,以及在需要的时候如何将数据存储到磁盘上。 从上面我们能够得出 Flink 乐观的内存管理以及直接操作二进制数据有以下几点好处: 削减GC压力。显而易见,由于全部常驻型数据都以二进制的方式存在 Flink 的MemoryManager中,这些MemorySegment一直呆在老年月而不会被GC回收。其他的数据对象基本上是由用户代码生成的短生命周期对象,这部分对象可以被 Minor GC 快速回收。只需用户不去创建大量类似缓存的常驻型对象,那么老年月的大小是不会变的,Major GC也就永久不会发生。从而有效地降低了垃圾回收的压力。另外,这里的内存块还可以是堆外内存,这可以使得 JVM 内存更小,从而加速垃圾回收。 避开了OOM。全部的运转时数据结构和算法只能通过内存池申请内存,保证了其使用的内存大小是固定的,不会由于运转时数据结构和算法而发生OOM。在内存吃紧的情况下,算法(sort/join等)会高效地将一大批内存块写到磁盘,之后再读回来。因而,OutOfMemoryErrors可以有效地被避开。 节省内存空间。Java 对象在存储上有很多额外的消耗(如上一节所谈)。假如只存储实际数据的二进制内容,就可以避开这部分消耗。 高效的二进制操作 缓存友好的计算。二进制数据以定义好的格式存储,可以高效地比较与操作。另外,该二进制方式可以把相关的值,以及hash值,键值和指针等相邻地放进内存中。这使得数据结构可以对高速缓存更友好,可以从 L1/L2/L3 缓存获得功能的提升(下文会具体解释)。 为 Flink 量身定制的序列化框架 目前 Java 生态圈供应了众多的序列化框架:Java serialization, Kryo, Apache Avro 等等。但是 Flink 实现了本人的序列化框架。由于在 Flink 中处理的数据流通常是同一类型,由于数据集对象的类型固定,对于数据集

文档评论(0)

bob157641554 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档