大数据技术架构(组件)29——Spark:Memory Model(2)

news2025/5/26 5:09:11

2.1.8.5、Memory addressing

以上小节介绍了spark对堆的划分,根据使用目的不同,对堆进行了区域划分,并说明了spark1.6之前和之后使用的两种不同内存模型管理以及之间的区别,那么这里继续逐步分析,说到内存管理,spark是如何通过进行内存寻址,内存块是如何封装的,通过何种方式来组织管理这些内存块?

问1:如何进行内存寻址的?

答:这里需要再次回到Project Tungsten计划中,由于spark引入了Off-Heap内存模式,为了方便统一管理On-Heap和Off-Heap这两种模式,Tungsten引入了统一的地址表示形式,即通过MemoryLocation类来表示On-Heap或Off-Heap两种内存模式下的地址,该类中有两个属性obj和offset,当处于On-Heap模式下,通过使用obj(即为对象的引用)和64 bit的offset来表示内存地址,当处于Off-Heap模式下,直接使用64 bit的offset绝对地址来描述内存地址。而这个64bit 的offset在对外编码时,前13 bit用来表示Page Number,后51 bit用来表示对应的offset

问2:内存块是如何封装的?

答:在Project Tungsten内存管理中,会使用一块连续的内存空间来存储数据,通过MemoryBlock类对内存块进行封装。该类继承了MemoryLocation类,采用了组合复用方式,即指定了内存块的地址,也提供了内存块本身的内存大小

问3:如何组织管理内存块?

答:Project Tungsten采用了类似于操作系统的内存管理模式,使用Page Table方式(其实本质就是一个数组,从源码中就可以看出)来管理内存,内部以Page来管理存储内存块(通过MemoryBlock来封装),通过pageNumber找到对应的Page,Page内部会根据Off-Heap或On-Heap两种模式分别存储Page对应内存块的起始地址(或对象内偏移地址)

在spark中,数据是以分区进行处理的,而每个分区对应一个task,所以对于内存的组织和管理可以借助于TaskMemoryManager来理解,同时以上这些疑惑均可以在TaskMemoryManager类(该类对MemoryManager又做了一层封装)中找到解答。

源码实现-TaskMemoryManager

2.1.8.6、Memory Configuration

2.1.8.7、Tungsten Optimize-CPU

2.1.8.7.1 缓存感知计算Cache-aware computation

缓存感知计算通过使用L1/L2/L3 CPU缓存来提升速度,同时也可以处理超过寄存器大小的数据。Spark开发者们在做性能分析的时候发现大量的CPU时间会因为等待从内存中读取数据而浪费,所以在Tungsten项目中,通过设计了更加友好的缓存算法和数据结构,让spark花费更少的时间等待cpu从内存中读取数据,提供了更多的计算时间。

缓存感知计算的解析

网上有很多关于缓存感知的说明,都是以KV排序为例,那么笔者这里也使用同样的例子再结合自己的理解,尽量解释的通俗易通。

3.2 代码生成Code Generation

代码生成指的是在运行时,spark会动态生成字节码,而不需要通过解释器对原始数据类型进行打包,同时也避免了虚拟函数的调用。当然该技术的优势并不止于此,还包括了将中间数据从存储器移动到CPU寄存器;使用向量化技术,利用现代CPU功能加快了对复杂操作运行速度

这里以一个sql为例,可以通过explain来查看spark在哪些过程中使用了代码生成的功能。

当算子前面有一个*时,说明全阶段代码生成被启用,在下面的例子中,Exchange算子没有实现代码生成,这是因为这里会发生Shuffle,需要通过网络发送数据。

select count(1) from tmp.user where id='123'
== Physical Plan ==
*(2) HashAggregate(keys=[], functions=[count(1)])
+- Exchange SinglePartition
+- *(1) HashAggregate(keys=[], functions=[partial count(1)])
+- *(1) Project
+- *(1) Filter ((id#2882514 = 123))
+- HiveTableScan [id#23025141, HiveableRelation tmp.user.org.apachehadoop.hive.serde2.lazy.lazySimpleSerDe, [id#2802514]

2.1.8.8、Demo of Memory Divison

/usr/local/spark-current/bin/spark-submit \
--master yarn \
--deploy-mode client \
--executor-memory 1G \
--queue root.default \
--class my.Application \
--conf spark.ui.port=4052 \
--conf spark.port.maxRetries=188 \
--num-executors 2 \
--jars mongo-spark-connector_2.11-2.3.1.jar \
App.jar 20201118000000

这里配置两个Executor,每个Executor内存给1G

如图所示,spark申请到了两个Executor,每个Executor得到的Storage Memory内存分别为384.1MB(注意:这里Storage Memory其实就是Storage+Execution的总和内存),这里有一个疑惑,我们分配的是每个Executor内存为1G,为什么只得到384MB呢?这里给出具体的计算公式:

1、我们申请为1G内存,但是真正拿到内存会比这个少,这里涉及到一个Runtime.getRuntime.maxMemory 值的计算(UnifiedMemoryManager源码分析中提到过),Runtime.getRuntime.maxMemory对应的值才是程序能够使用的最大内存,上面也提到了堆划分了Eden,Survivor,Tenured区域,所以该值计算公式为:

ExecutorMemory = Eden + 2 * Survivor + Tenured = 1GB = 1073741824 字节

systemMemory = Runtime.getRuntime.maxMemory = Eden + Survivor + Tenured = 954437176.888888888888889 字节

//org.apache.spark.memory.UnifiedMemoryManager(这里讨论的还是动态内存模型)
private def getMaxMemory(conf: SparkConf): Long = {
    val systemMemory = conf.getLong("spark.testing.memory", Runtime.getRuntime.maxMemory)
    val reservedMemory = conf.getLong("spark.testing.reservedMemory"
        if (conf.contains("spark.testing")) 0 else RESERVED_SYSTEM_MEMORY_BYTES)
    val usableMemory = systemMemory - reservedMemory
    val memoryFraction = conf.getDouble("spark.memory.fraction", 0.6)
    //这里即获取最大的内存值
    (usableMemory * memoryFraction).toLong
}

2、基于Spark的动态内存模型设计,其中有300MB的预留内存,因此剩余可用内存为总申请得到的内存-预留内存

reservedMemory = 300MB = 314572800字节

usableMemory = systemMemory - reservedMemory = 954437176.888888888888889 - 314572800 = 639864376.888888888888889字节

3、Spark Web UI界面上虽然显示的是Storage Memory,但其实是Execution+Storage内存,即该部分占用60%比例Storage + Execution = usableMemory * 0.6 = 639864376.888888888888889 * 0.6 = 383918626.133333333333333 字节

4、通过第三步骤即可看出实际的内存分配情况了,注意:web ui界面得到的结果计算是除于1000转换得到的值。

2.1.8.9、Optimize Configuration

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/334973.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CTFshow菜狗杯-misc-wp(详解 脚本 过程 全)

首先感谢ctf平台和各位出题的大佬其次感谢各位读者,对我的支持( •̀ ω •́ )y 有什么问题和建议可以私聊我废话不多话开启你们的旅程吧 这个也是我这几天才看 一些见解和思路分享给你们希望你们在旅途中玩的开心,学的开心✌( •̀ ω •́ )y杂项签到…

opencv+python物体检测【03-模仿学习】

仿照练习:原文链接 步骤一:准备图片 正样本集:正样本集为包含“识别物体”的灰度图,一般大于等于2000张,尺寸不能太大,尺寸太大会导致训练时间过长。 负样本集:负样本集为不含“识别物体”的…

无公网IP环境快解析实现医美ERP外网访问

现阶段,借助医学手段让人们变美逐渐成为时尚,医美走进公众生活的步伐也在不停加快,整个医美行业总体处于蓬勃发展之势,因此医美行业ERP需求量也不断增加。医美管理软件系统涵盖HIS、进销存、CRM、CallCenter、经营报表等模块&…

【王道数据结构】第七章| 查找 | 树

目录 一、查找 1、查找概念 2、顺序查找 3、折半查找 4、分块查找 二、树 1、B树 2、B树的基本操作 3、B树 4、散列查找及其性能分析 5、散列查找及性能分析 一、查找 1、查找概念 查找:在数据集合中寻找满足某种条件的数据元素的过程称为查找。查找…

当ChatGPT遇到前端开发

目录 一、ChatGPT是什么? 二、怎么注册使用ChatGPT? 1、注册账号 2.完成 ChatGPT 手机号码验证 3、登录 ChatGPT 账号并开始使用 三、当ChatGPT遇到前端开发 四、深思总结 AIGC 作画带给人们的惊艳感觉还未散去,ChatGPT 又来刺激人类脆…

leetcode 困难 —— N 皇后, N皇后 II,八皇后(简单递归)

(不知道为啥总是给这种简单的递归设为困难题,虽然优化部分很不错,但是题目太好过了) 题目: 按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个…

java 自定义json解析注解 复杂json解析 工具类

java 自定义json解析注解 复杂json解析 工具类 目录java 自定义json解析注解 复杂json解析 工具类1.背景2、需求-各式各样的json一、一星难度json【json对象中不分层】二、二星难度json【json对象中出现层级】三、三星难度json【json对象中存在数组】四、四星难度json【json对象…

【Selenium学习】Selenium 八大定位法

1.1 ID定位HTML Tag 的 id 属性值是唯一的,故不存在根据 id 定位多个元素的情况。下面以在百度首页搜索框输入文本“python”为例。搜索框的 id 属性值为“kw”,如图1.1所示:代码如下,“find_element_by_id”方法已废弃&#xff0…

基于nodejs+vue的健身房课程预约平台

本系统主要实现了首页、个人中心、用户管理、教练管理、会员卡管理、购买会员管理、课程类型管理、课程信息管理、课程购买管理、场地信息管理、场地预约管理、系统管理,用户:首页、个人中心、购买会员管理、课程购买管理、场地预约管理,教练:首页、个人…

睿创转债,声迅转债上市价格预测

睿创转债基本信息转债名称:睿创转债,评级:AA,发行规模:15.6469亿元。正股名称:睿创微纳,今日收盘价:47.45元,转股价格:40.09元。当前转股价值 转债面值 / 转…

树生成工具泛型接口 TreeNode

1、定义泛型接口 // 实现接口需要传入两个参数&#xff0c;第一个T 为节点中的id&#xff0c;第二个R 为节点&#xff0c;TreeNode。 public interface TreeNode<T, R extends TreeNode<T, R>> {/*** 获取节点id** return 树节点id*/T id();/*** 获取该节点的父节…

读书笔记//《数据分析:企业的贤内助》

数据分析师是个杂家——作者陈哲。 为什么写这本书&#xff1f; 懂得再多知识却不会用&#xff0c;原因是缺少通往思路、方法和技能的两条路径——项目流程和项目应用&#xff08;案例&#xff09; —————————— 数据分析师的晋升空间 &#xff08;见第2章&#xff0…

NLP模型检查英语语法错误

当NLP模型产生了语法错误&#xff0c;怎么办&#xff1f;比如&#xff0c;He wants that you send him an email.没关系&#xff0c;现在可以像小时候的英语老师&#xff0c;改作文一样简单。只要装上一个专门纠正语法错误的库就可以&#xff0c;还是毫秒钟就可揪出来的那种。这…

【shell】awk、sed、sort是什么?怎么用?

目录 一、AWK 干什么用的&#xff1f; 使用起来有什么条件&#xff1f; 怎么使用&#xff1f; 二、sed 功能&#xff1f; sed怎样读取数据&#xff1f; 怎样调用sed &#xff1f; 三、sort 功能是什么&#xff1f; 命令有哪些&#xff1f; 本文只讲解了一些简略的知…

“千年之恋”注册页面制作

“千年之恋”注册页面制作一、实验名称&#xff1a;二、实验日期&#xff1a;三、实验目的&#xff1a;四、实验内容&#xff1a;五、实验步骤&#xff1a;六、实验结果&#xff1a;七、源程序&#xff1a;八、心得体会&#xff1a;一、实验名称&#xff1a; “千年之恋”注册…

算法导论—SAT、NP、NPC、NP-Hard问题

算法导论—SAT、NP、NP-Hard、NPC问题SAT 问题基本定义问题复杂性P、NP、NP-Hard、NP-Complete&#xff08;NPC&#xff09;证明NP-Hard关系图NP问题的概念约化的定义NPC问题NP-Hard问题SAT 问题基本定义 SAT 问题 (Boolean satisfiability problem, 布尔可满足性问题,SAT): 给…

C++之完美转发、移动语义(forward、move函数)

完美转发1. 在函数模板中&#xff0c;可以将自己的参数“完美”地转发给其它函数。所谓完美&#xff0c;即不仅能准确地转发参数的值&#xff0c;还能保证被转发参数的左、右值属性不变。2. C11标准引入了右值引用和移动语义&#xff0c;所以&#xff0c;能否实现完美转发&…

「敏捷架构」敏捷架构:规模化敏捷开发的策略

与流行的看法相反&#xff0c;架构是敏捷软件开发工作的一个重要方面&#xff0c;就像传统的工作一样&#xff0c;并且是扩展敏捷方法以满足现代组织的现实需求的关键部分。但是&#xff0c;敏捷专家的架构方式与传统主义者的方式略有不同。本文讨论以下问题&#xff1a; 迈向敏…

Acer传奇Go电脑开机自动安装软件卡死怎么重装系统?

Acer传奇Go电脑开机自动安装软件卡死怎么重装系统&#xff1f;一些用户在网络上下载安装了一些恶意软件之后&#xff0c;导致电脑中了病毒。每次开机联网之后&#xff0c;有很多的软件就会自动开始下载&#xff0c;占满你的桌面&#xff0c;这个情况导致电脑直接卡死了&#xf…

前端知识点复盘

组件和jsx <body><div id"root"></div><script type"text/babel">const root ReactDOM.createRoot(document.getElementById("root"))class App extends React.Component {render() {return (<div> <h1>s…