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. [转] spring的普通类中如何取session和request对像

    在使用spring时,经常需要在普通类中获取session,request等对像.比如一些AOP拦截器类,在有使用struts2时,因为struts2有一个接口使用org.apache.struts2 ...

  2. Java 8 – How to format LocalDateTime

    Few examples to show you how to format java.time.LocalDateTime in Java 8. 1. LocalDateTime + DateTim ...

  3. Hibernate 连接访问多个数据库(含访问不同数据库的相同表)(转)

    利用hibernate访问不同数据库中的不同表或不同数据库中的相同表. 本人在开发过程中的解决方案,希望大家交流.一般用myEclipse工具会自动生成Hibernate的相关文件,大致有下面几类: ...

  4. js页面加载完后执行(document.onreadystatechange 和 document.readyState)

    js页面加载完后执行javascript(document.onreadystatechange 和 document.readyState) document.onreadystatechange ...

  5. 【小超_Android】2015最流行的android组件、工具、框架大全(兴许)

    2015.07.07 FlyRefresh 创意Replace的Android实现,非常cool. fab-toolbar Material Design风格的FAB工具栏效果 MaterialVie ...

  6. Java 泛型(Generics) 综述

    一. 引子 一般的类和方法.仅仅能使用详细类型:要么是基本类型.要么是自己定义类型.假设要编写能够应用于多种类型的代码,这样的刻板的限制对代码的束缚就会非常大. 多态算是一种泛化机制,但对代码的约束还 ...

  7. 【Unity】6.3 通过 C# 脚本创建和访问游戏对象

    分类:Unity.C#.VS2015 创建日期:2016-04-16 一.简介 在游戏开发过程中,脚本不但需要访问脚本所在的游戏对象的组件,还经常需要访问和控制真他游戏对象.另外,根据项目需求,还可能 ...

  8. InfoQ 趋势报告:架构和设计领域技术演变详解

    https://www.infoq.cn/article/R7lWXd0R4VFf3E0bB*38 本文概述了我们对当前“架构和设计”领域的看法,这个领域侧重于基础设施模式.技术框架模式的实现,以及软 ...

  9. .NET MVC5+ EF+AutoFac自动注入框架

    1.创建一个MVC系统 VIEW显示页面代码: <link href="~/Content/bootstrap.css" rel="stylesheet" ...

  10. 安装mysql提示3306端口已经被占用解决方案

    今天遇到的问题是这样的,之前已经安装过mysql了,一直用的好好的,但是今天开启服务时报异常,无法启动.为了省事,于是想到卸载重装,在安装的过程中发现3306已经被占用,这也是一开始服务无法启动的原因 ...