Spark内存管理之钨丝计划

1. 钨丝计划的产生的原因 
2. 钨丝计划内幕详解 

一:“钨丝计划”产生的本质原因 
1, Spark作为一个一体化多元化的(大)数据处理通用平台,性能一直是其根本性的追求之一,Spark基于内存迭代(部分基于磁盘迭代)的模型极大的满足了人们对分布式系统处理性能的渴望,但是有Spark是采用Scala+ Java语言编写的所以运行在了JVM平台,当然JVM是一个绝对伟大的平台,因为JVM让整个离散的主机融为了一体(网络即OS),但是JVM的死穴GC反过来限制了Spark(也就是说平台限制了Spark),所以Tungsten聚焦于CPU和Memory使用,以达到对分布式硬件潜能的终极压榨!

对内存的使用: 

On-Heap:对象在JVM堆中。 
Off-Heap:在JVM堆外从OS层面分配内存,不受JVM管理。

2, 对Memory的使用,Tungsten使用了Off-Heap(堆外内存),也就是在JVM之外的内存空间(这就好像C语言对内存的分配、使用和销毁),是系统级别的,此时Spark实现了自己的独立的内存管理,就避免了JVM的GC引发的性能问题,其实还包含避免序列化和反序列化。

3, 对于Memory管理方面一个至关重要的内容Cache,Tungsten提出了Cache-aware computation,也就是说使用对缓存友好的算法和数据结构来完成数据的存储和复用;

4, 对于CPU而言,Tungsten提出了Code Generation,其首先在Spark SQL使用,通过Tungsten要把该功能普及到Spark的所有功能中;

总结:Tungsten的内存管理机制独立于JVM,所以Spark操作数据的时候具体操作的是Binary Data,而不是JVM Object!!!而且还免去了序列化和反序列化的过程!!!!!

二:“钨丝计划”内幕详解 
1, 内存管理方面:Spark使用了sun.misc.Unsafe来进行Off-heap级别的内存分配、指针使用及内存释放;Spark为了统一管理Off-Heap和On-heap而提出了Page。

2, 如果是On-heap的方式,本身是有一个64bit的Object的引用和一个64bit的在Object中的OffSet来指定具体数据的。如果是Off-Heap那么就是一个指针直接指向数据。 
Off-Heap:采用C语言的方式,所以指针直接指向数据实体。 
On-heap: 堆内内存空间的时候,GC的时候对堆内结果的重新组织。

3, On-heap:如果在运行的时候分配Java Object对象,它的地址是不可以改变,JVM对内存管理的负担是远远大于实用Off-Heap方式,因为GC的时候会对heap进行相应的重组。

4, Spark进行了一层抽象,访问数据的时候可能在堆内也可能在堆外,提供了管理器,管理器可以根据数据在堆内还是在堆外进行具体的寻址,但是从程序运行的角度或者框架的角度来看,是看不见是堆内还是堆外,管理器会完成具体地址和寻址到具体数据的映射过程。

5, Page会针对堆外内存和堆内内存两种情况进行具体的适配。 


6, Page在寻址的时候具体包括两部分,一个是什么样的Page,另一个就是OffSet。 


7, 如果在Off-heap下,内存就直接是一个64bit的long的指针来指向具体数据。 


8,如果是On-heap下,也就是堆内的情况下,则就会有两部分,一部分是64bit的Object的引用,另外一部分是64bit的Object内的Offset来表示我们具体的数据。 
这时候在翻译两种不同情况的时候,就要注意该怎么寻址了。 
Off-Heap:如果是一个指针直接指向数据结构。 
On-heap: GC会导致heap的重新组织。而重组之后要确保Object的地址是不变的。 
Page是一个Table。 
Page Table的方式来进行内存管理。把内存分为很多页。页只是一个单位,和分配数组差不多,具体实现是通过TaskMemoryManager对内存进行管理的,具体是靠allocatePage来分配页。 

内存寻址: 
1. 在哪一页,也就是在那个Page. 
2. 就是Page的具体偏移。 
内存寻址的工作方式: 
Off-heap:那么内存直接就是用一个64bit的long的指针来指向我们的数据。 
On-heap:那就是堆内,包含两部分,一部分是64bit的引用,另外一部分是64bit的Object的OffSet来表示我们的具体数据。 
地址本身和数据本身之间有一个映射,也就是所谓的逻辑地址,将逻辑地址映射到实际的物理地址,这个是钨丝计划内部的管理机制。 
由于逻辑地址是一个64bit的长整数,它前面的13个bit是第几页,后面的51bit就表示在页内的偏移。

所以寻址的方式就是先找到那个page,然后根据后面的51bit,所以加上偏移量,就找到了具体的数据在内存的物理地址。 
MemoryLocation:封装了两种逻辑地址寻址的方式。

/**
* A memory location. Tracked either by a memory address (with off-heap allocation),
* or by an offset from a JVM object (in-heap allocation).
*/
public class MemoryLocation {
  1. allocatePage:分配内存页,添加到Page table中,然后去使用它。 
    TaskMemoryManager来管理Page,还有管理Off-heap和On-heap的方式
/**
* Allocate a block of memory that will be tracked in the MemoryManager's page table; this is
* intended for allocating large blocks of Tungsten memory that will be shared between operators.
*
* Returns `null` if there was not enough memory to allocate the page. May return a page that
* contains fewer bytes than requested, so callers should verify the size of returned pages.
*/
public MemoryBlock allocatePage(long size, MemoryConsumer consumer) {
if (size > MAXIMUM_PAGE_SIZE_BYTES) {
throw new IllegalArgumentException(
"Cannot allocate a page with more than " + MAXIMUM_PAGE_SIZE_BYTES + " bytes");
}
2.  cache aware computation机制:

主要是基于内存的计算,进行的一种优化的方式,CPU Cache的时候l1,l2,l3,速度是不同的,那我们提供的cache的一些友好的数据结构,就可以提高cache的命中率。

3.  提高cache的命中率,怎么做的?

设计了自己的数据结构,以前要命中具体的cache的时候,其实采用遍历的方式,现在加了一个指针不需要遍历,数据要找命中的cache指针的位置已经指向了具体的位置。这个时候查询的方式就按照Key和Point对的方式,这时候就不需要遍历随机访问了。

4.  Code Generation机制:

把已有的代码变成本地的字节,不需要很多的抽象和匹配等。

总结: 

Spark内存管理之钨丝计划的更多相关文章

  1. Spark内存管理机制

    Spark内存管理机制 Spark 作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中扮演着非常重要的角色.理解 Spark 内存管理的基本原理,有助于更好地开发 Spark 应用程序和进行 ...

  2. Apache Spark 内存管理详解(转载)

    Spark 作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中扮演着非常重要的角色.理解 Spark 内存管理的基本原理,有助于更好地开发 Spark 应用程序和进行性能调优.本文旨在梳理出 ...

  3. 【Spark-core学习之八】 SparkShuffle & Spark内存管理

    [Spark-core学习之八] SparkShuffle & Spark内存管理环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 ...

  4. spark 源码分析之十五 -- Spark内存管理剖析

    本篇文章主要剖析Spark的内存管理体系. 在上篇文章 spark 源码分析之十四 -- broadcast 是如何实现的?中对存储相关的内容没有做过多的剖析,下面计划先剖析Spark的内存机制,进而 ...

  5. spark内存管理详解

    Spark 作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中扮演着非常重要的角色.理解 Spark 内存管理的基本原理,有助于更好地开发 Spark 应用程序和进行性能调优.本文旨在梳理出 ...

  6. spark内存管理器--MemoryManager源码解析

    MemoryManager内存管理器 内存管理器可以说是spark内核中最重要的基础模块之一,shuffle时的排序,rdd缓存,展开内存,广播变量,Task运行结果的存储等等,凡是需要使用内存的地方 ...

  7. Spark(四十六):Spark 内存管理之—OFF_HEAP

    存储级别简介 Spark中RDD提供了多种存储级别,除去使用内存,磁盘等,还有一种是OFF_HEAP,称之为 使用JVM堆外内存 https://github.com/apache/spark/blo ...

  8. Spark 内存管理

    Spark 内存管理 Spark 执行应用程序时, 会启动 Driver 和 Executor 两种 JVM 进程 Driver 负责创建 SparkContext 上下文, 提交任务, task的分 ...

  9. spark内存管理分析

    前言 下面的分析基于对spark2.1.0版本的分析,对于1.x的版本可以有区别. 内存配置 key 默认 解释 spark.memory.fraction 0.6 spark可以直接使用的内存大小系 ...

随机推荐

  1. Linux中SFTP命令

    sftp和ftp是两种协议是不同的,sftp是ssh内含的协议,只要sshd服务器启动了,它就可用,它本身不需要ftp服务器启动. 1.常用登陆方式: 格式:sftp <user>@< ...

  2. Android开发之AsyncTask的使用

    Android API 3时引进了AsyncTask,也叫异步任务.使用它可以很方便的更新主线程中的UI,使用它比Handler.Thread更简单.由于AsyncTask是抽象类,要使用它首先要创建 ...

  3. [转]SpringMVC中使用Interceptor拦截器

    SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那 ...

  4. Java – How to add days to current date

    1. Calendar.add Example to add 1 year, 1 month, 1 day, 1 hour, 1 minute and 1 second to the current ...

  5. Sql 查询当天、本周、本月记录

    --查询当天: select * from info where DateDiff(dd,datetime,getdate())=0 --查询24小时内的: select * from info wh ...

  6. 如何分析Java程序中的死锁

    使用下面方式:产生java的Thread Dump信息 windows平台上:ctrl+break 或者 ctrl+(fn+b)键 Linux平台上:kill -3 pid (查找程序进程id -&g ...

  7. idea没有代码自动提示功能和包自动引入不了问题

    idea没有代码自动提示功能和包自动引入不了问题 原因:节电模式 File -> Power Save Mode (被勾选了) 处理方法: File -> Power Save Mode ...

  8. RDD转换DataFrame

    Spark SQL有两种方法将RDD转为DataFrame. 1. 使用反射机制,推导包含指定类型对象RDD的schema.这种基于反射机制的方法使代码更简洁,而且如果你事先知道数据schema,推荐 ...

  9. 基于prometheus监控k8s集群

    本文建立在你已经会安装prometheus服务的基础之上,如果你还不会安装,请参考:prometheus多维度监控容器 如果你还没有安装库k8s集群,情参考: 从零开始搭建基于calico的kuben ...

  10. Ubuntu java install & config

    im:http://jingyan.baidu.com/article/08b6a591cb06f114a8092209.html http://www.cnblogs.com/zknublx/p/5 ...