Spark 内存管理之Tungsten

xiaoxiao2021-02-27  271

Tungsten项目概述

Tungsten号称Spark有史以来最大的改动,其致力于提升Spark程序对内存和CPU的利用率,使性能达到硬件的极限,主要工作包含以下三个方面

Memory Management and Binary Processing: leveraging application semantics to manage memory explicitly and eliminate the overhead of JVM object model and garbage collection。Cache-aware computation: algorithms and data structures to exploit memory hierarchy。Code generation: using code generation to exploit modern compilers and CPUs。

大致的内容如下

Memory Management and Binary Processing: off-heap管理内存,降低对象的开销和消除JVM GC带来的延时。Cache-aware computation: 优化存储,提升CPU L1/ L2/L3缓存命中率。Code generation: 优化Spark SQL的代码生成部分,提升CPU利用率。

上述第一点和内存管理相关,是本篇文章关注的重点。

为什么Tungsten关注内存和CPU

从硬件角度,网路带宽和磁盘读写都有大幅度提升,例如10Gbps的网络设备和SSD,使用SSD存储数据的公司在逐步增多,并且价格在可接受范围。从软件角度,Spark做了许多降低网络传输和磁盘IO方面的工作,例如就近执行、序列化等。此外,databricks的研究也表明CPU是主要的瓶颈,参考Spark Performance Analysis。

Spark中JVM的不足

运行在JVM之上的程序,依赖JVM管理内存及回收垃圾,但会存在两个显著问题

Java对象空间开销大 以UTF-8编码的字符串abcd为例,仅存储字符串信息需要4 bytes,然而使用Java的String存储则需要48 bytes,使用jol打印出String的内部占用(参考Java Object Layout(jol) ),如下

OFFSET SIZE TYPE DESCRIPTION VALUE 0 12 (object header) N/A 12 4 char[] String.value N/A 16 4 int String.hash N/A 20 4 int String.hash32 N/A Instance size: 24 bytes 使用jol打印出abcd占用空间大小,如下java.lang.String@213214d1d footprint: COUNT AVG SUM DESCRIPTION 1 24 24 [C 1 24 24 java.lang.String 2 48 (total)

GC带来的时间开销 full gc会stop the world,增加程序耗时,甚至可能出现假死情况,并且这种情况没有日志输出,给问题排查带来一定难度。

基于以上考虑,Tungsten项目优化内存的使用,使用off-heap方式管理内存,不再依赖JVM,避免了存储的额外开销及GC的影响。

Tungsten内存管理

off-heap

off-heap是指类似C语言的方式,直接向OS申请及释放的内存。JVM提供了sun.misc.Unsafe API实现上述操作(参考Understanding sun.misc.Unsafe),Spark对应的代码如下 上图中Platform类是对sun.misc.Unsafe的简单封装,返回的内存地址和内存大小封装为MemoryBlock。

off-heap内存管理

以BytesToBytesMap为例介绍上面申请的MemoryBlock的使用。 Spark 内存管理之BytesToBytesMap

总结

介绍Tungsten中内存管理相关部分。

参考: Project Tungsten: Bringing Apache Spark Closer to Bare Metal Java Object Layout(jol) Understanding sun.misc.Unsafe

转载请注明原文地址: https://www.6miu.com/read-3165.html

最新回复(0)