Spark在处理数据的时候,会将数据都加载到内存再做处理吗?
对于Spark的初学者,往往会有一个疑问:Spark(如SparkRDD、SparkSQL)在处理数据的时候,会将数据都加载到内存再做处理吗?
很显然,答案是否定的!
对该问题产生疑问的根源还是对Spark计算模型理解不透彻。
对于Spark RDD,它是一个分布式的弹性数据集,不真正存储数据。如果你没有在代码中调用persist或者cache算子,Spark是不会真正将数据都放到内存里的。
此外,还要考虑persist/cache的缓存级别,以及对什么进行缓存(比如是对整张表生成的DataSet缓存还是列裁剪之后生成的DataSet缓存)(关于Spark RDD的特性解析参考《Spark RDD详解》
既然Spark RDD不存储数据,那么它内部是如何读取数据的呢?其实Spark内部也实现了一套存储系统:BlockManager。为了更深刻的理解Spark RDD数据的处理流程,先抛开BlockManager本身原理,从源码角度阐述RDD内部函数的迭代体系。
我们都知道RDD算子最终会被转化为shuffle map task和result task,这些task通过调用RDD的iterator方法获取对应partition数据,而这个iterator方法又会逐层调用父RDD的iterator方法获取数据(通过重写scala.collection.iterator的hasNext和next方法实现)。主要过程如下:
首先看ShuffleMapTask和ResultTask中runTask方法的源码:
关键看这部分处理逻辑:
rdd.iterator(partition, context)
getOrCompute方法会先通过当前executor上的BlockManager获取指定blockId的block,如果block不存在则调用computeOrReadCheckpoint,如果要处理的RDD没有被checkpoint或者materialized,则接着调用compute方法进行计算。
compute方法是RDD的抽象方法,由继承RDD的子类具体实现。
以WordCount为例:
sc.textFile(input)
.flatMap(line => line.split(" "))
.map(word => (word, 1))
.reduceByKey(_ + _)
.saveAsTextFile(output)
textFile会构建一个HadoopRDD
flatMap/map会构建一个MapPartitionsRDD
reduceByKey触发shuffle时会构建一个ShuffledRDD
saveAsTextFile作为action算子会触发整个任务的执行
以flatMap/map产生的MapPartitionsRDD实现的compute方法为例:
override def compute(split: Partition, context: TaskContext): Iterator[U] =
f(context, split.index, firstParent[T].iterator(split, context))
底层调用了parent RDD的iterator方法,然后作为参数传入到了当前的MapPartitionsRDD。而f函数就是对parent RDD的iterator调用了相同的map类函数以执行用户给定的函数。
所以,这是一个逐层嵌套的rdd.iterator方法调用,子RDD调用父RDD的iterator方法并在其结果之上调用Iterator的map函数以执行用户给定的函数,逐层调用直到调用到最初的iterator(比如上述WordCount示例中HadoopRDD partition的iterator)。
而scala.collection.Iterator的map/flatMap方法返回的Iterator就是基于当前Iterator重写了next和hasNext方法的Iterator实例。比如,对于map函数,结果Iterator的hasNext就是直接调用了self iterator的hasNext,next方法就是在self iterator的next方法的结果上调用了指定的map函数。
flatMap和filter函数稍微复杂些,但本质上一样,都是通过调用self iterator的hasNext和next方法对数据进行遍历和处理。
所以,当我们调用最终结果iterator的hasNext和next方法进行遍历时,每遍历一个数据元素都会逐层调用父层iterator的hasNext和next方法。各层的map函数组成一个pipeline,每个数据元素都经过这个pipeline的处理得到最终结果。
这也是Spark的优势之一,map类算子整个形成类似流式处理的pipeline管道,一条数据被该链条上的各个RDD所包裹的函数处理。
再回到WordCount例子。HadoopRDD直接跟数据源关联,内存中存储多少数据跟读取文件的buffer和该RDD的分区数相关(比如buffer*partitionNum,当然这是一个理论值),saveAsTextFile与此类似。MapPartitionsRDD里实际在内存里的数据也跟partition数有关系。ShuffledRDD稍微复杂些,因为牵扯到shuffle,但是RDD本身的特性仍然满足(记录文件的存储位置)。
说完了Spark RDD,再来看另一个问题:Spark SQL对于多表之间join操作,会先把所有表中数据加载到内存再做处理吗?
当然,肯定也不需要!
具体可以查看Spark SQL针对相应的Join SQL的查询计划,以及在之前的文章《Spark SQL如何选择join策略》中,针对目前Spark SQL支持的join方式,任何一种都不要将join语句中涉及的表全部加载到内存。即使是Broadcast Hash Join也只需将满足条件的小表完整加载到内存。
推荐文章:
通过spark.default.parallelism谈Spark谈并行度
Spark为什么只有在调用action时才会触发任务执行呢(附算子优化和使用示例)?
关注微信公众号:大数据学习与分享,获取更对技术干货
Spark在处理数据的时候,会将数据都加载到内存再做处理吗?的更多相关文章
- [WP8.1UI控件编程]Windows Phone大数据量网络图片列表的异步加载和内存优化
11.2.4 大数据量网络图片列表的异步加载和内存优化 虚拟化技术可以让Windows Phone上的大数据量列表不必担心会一次性加载所有的数据,保证了UI的流程性.对于虚拟化的技术,我们不仅仅只是依 ...
- Tomcat启动时加载数据到缓存---web.xml中listener加载顺序(例如顺序:1、初始化spring容器,2、初始化线程池,3、加载业务代码,将数据库中数据加载到内存中)
最近公司要做功能迁移,原来的后台使用的Netty,现在要迁移到在uap上,也就是说所有后台的代码不能通过netty写的加载顺序加载了. 问题就来了,怎样让迁移到tomcat的代码按照原来的加载顺序进行 ...
- js 鼠标滚动到某屏时,加载那一屏的数据,仿京东首页楼层异步加载模式
js用处:在做商城时,首页图片太多,严重影响首页打开速度,所以我们需要用到异步加载楼层.js名称:鼠标滚动到某屏时,加载那一屏的数据,仿京东首页楼层模式js解释:1.用于商城的楼层内容异步加载,滚动条 ...
- Tomcat启动时加载数据到缓存---web.xml中listener加载顺序(优先初始化Spring IOC容器)
JavaWebSpringTomcatCache 最近用到在Tomcat服务器启动时自动加载数据到缓存,这就需要创建一个自定义的缓存监听器并实现ServletContextListener接口,并且 ...
- Highcharts 基本曲线图;Highcharts 带有数据标签曲线图表;Highcharts 异步加载数据曲线图表
Highcharts 基本曲线图 实例 文件名:highcharts_line_basic.htm <html> <head> <meta charset="U ...
- python数据可视化-matplotlib入门(7)-从网络加载数据及数据可视化的小总结
除了从文件加载数据,另一个数据源是互联网,互联网每天产生各种不同的数据,可以用各种各样的方式从互联网加载数据. 一.了解 Web API Web 应用编程接口(API)自动请求网站的特定信息,再对这些 ...
- html ajax请求 php 下拉 加载更多数据 (也可点击按钮加载更多)
<input type="hidden" class="total_num" id="total" value="{$tot ...
- EF如何操作内存中的数据以及加载相关联表的数据:延迟加载、贪婪加载、显示加载
之前的EF Code First系列讲了那么多如何配置实体和数据库表的关系,显然配置只是辅助,使用EF操作数据库才是每天开发中都需要用的,这个系列讲讲如何使用EF操作数据库.老版本的EF主要是通过Ob ...
- EF如何操作内存中的数据和加载外键数据:延迟加载、贪婪加载、显示加载
EF如何操作内存中的数据和加载外键数据:延迟加载.贪婪加载.显示加载 之前的EF Code First系列讲了那么多如何配置实体和数据库表的关系,显然配置只是辅助,使用EF操作数据库才是每天开发中都需 ...
随机推荐
- Chrome标签整理
程序人生 设计素材类网站 关于生活 求职相关网站 Web前端 科技新闻相关网站 优秀资源内含丰富学习资料 项目实例视频资料等 面试简历相关 适合初学者自学的编程网站 国内优秀博客 由于平时经常浏览一些 ...
- python --装饰器通俗讲解
装饰器 什么是装饰器?:在不修改源代码和调用方式的基础上给其增加新的功能,多个装饰器可以装饰在同一个函数上 Python中的装饰器是你进入Python大门的一道坎; 装饰器特点: 不改变原函数原代码: ...
- 我用了半年的时间,把python学到了能出书的程度
Python难学吗?不难,我边做项目边学,过了半年就通过了出版社编辑的面试,接到了一本Python选题,并成功出版. 有同学会说,你有编程基础外带项目实践机会,所以学得快.这话不假,我之前的基础确实加 ...
- ThreadLocal全面解析,一篇带你入门
===================== 大厂面试题: 1.Java中的引用类型有哪几种? 2.每种引用类型的特点是什么? 3.每种引用类型的应用场景是什么? 4.ThreadLocal你了解吗 5 ...
- Unity3d开发中遇到的问题记录
安装Unity unity官方提供免费的community版本,功能健全,下载时还有Visual Studio,非常方便. 官方文档 Unity的官方文档非常权威!详尽!可靠!很多关于函数细节的疑惑都 ...
- Pytest(2)使用和调用方法
Pytest执行用例规则 Pytest在命令行中支持多种方式来运行和选择测试用例 1.对某个目录下所有的用例 pytest 2.对模块中进行测试 pytest test_mod.py 3.对文件夹进行 ...
- 【poj 1988】Cube Stacking(图论--带权并查集)
题意:有N个方块,M个操作{"C x":查询方块x上的方块数:"M x y":移动方块x所在的整个方块堆到方块y所在的整个方块堆之上}.输出相应的答案. 解法: ...
- 使用scrapy爬取jian shu文章
settings.py中一些东西的含义可以看一下这里 python的scrapy框架的使用 和xpath的使用 && scrapy中request和response的函数参数 & ...
- Codeforces Round #649 (Div. 2)
Codeforces Round #649 (Div. 2) -- WKL \(\mathcal{A}\)题: \(\mathrm{XXXXX}\) Greedy implementation *12 ...
- k8s二进制部署 - dashboard安装
配置资源清单rbac.yaml apiVersion: v1 kind: ServiceAccount metadata: labels: k8s-app: kubernetes-dashboard ...