00:00
好,同学们,我们前面把咱们Spark靠的这个需求啊,咱们都给大家写完了,那么我们讲完这个需求之后啊,咱们整个Spark靠的内容呢也都结束了,那接下来呢,我们再把10SPA扣呢,做一个简单的课件梳理,并且呢对它做一个总结,好吧,同学们来呃,首先我们一块来看看,我们最开始给大家讲的呢是Spark,它是什么?其实啊,我们说了,它就是一个数据计算的一个引擎啊,它是一套框架,那么对于我们这个SPA学习来讲的话,我们一般会跟那个mapce做一个对比,所以在学习过当中,尤其是在最开始学习的时候,我们是给大家呢跟海杜op做了一个对比,为什么呢?他们都有自己的这种计算框架,都有自己的这种什么呢生态圈,所以呢,我们在对比的时候,经常会拿他们俩来做对比,但其实会稍微有点不同,因为海杜本呢,它是一个大数据的基础框架,里面包括计算,包括存储啊,对不对它都有,但是我们的Spark呢。
01:00
相对来说就单一的一些,它也有自己的生态圈啊,做什么图形计算呢,基于学习啊这些什么一些操作对不对,但是呢,它的主要核心呢,就是还是计算,所以存储功能对它来讲它是没有的,所以从这上面来讲的话,它其实是不太一样啊,不太一样。然后呢,我们在学习过程当中啊,我们先做了一个对比啊,然后呢,我们后来呢,给大家介绍了一下Spark和海多be之间该如何选择的问题,那其实并不是说你说老师这个Spark呢,是基于海op开发的,它里面把map reduce的计算过程做了优化,对不对啊,提升了它的效率,那是不是以后就全用Spark呢?其实我们说不是因为我们的海豆pay啊,它其实它的那个map就是你看的是面向一次性数据计算的,但是呢,它的功能啊非常稳定,而我们的18UG呢,它提升了它的数据的什么计算效率,可是他把数据放在内存当中,内存是有极限值的,当我数据量大的情况下,内存是不够用的,所以这样的话,Spark的计算是不够稳定的啊,它会因为内存的原因导致它计算失败,而且可能会大量的重试,也会影响性能,所以呢,我们去选择的话,要看实际的场景,并不是说谁好谁坏,没有这个区别。
02:11
那么我们接着往下啊,往下往下呢是我们Spark的核心模块,咱们说了,咱们主要讲的呢,是这个叫Spark call,后面呢会讲Spark circle和Spark streaming,还有Spark ML Le和Spark graph act,那这两个图形计算和基于学习呢,对于我们来讲,嗯,学习的门槛比较高啊,成本也比较大,所以这个我们暂时不作为学习内容啊。那么我们要讲的呢,就是三大块,SPA块,Spark circle和Spark streaming啊,后面的学习当中,我们再给大家介绍这两个啊,这是我们后面上硅谷的,呃,计划当中会把这两个加进去啊。然后接着往下啊,下面下面呢是我们给大家去什么呢?上手啊,快速上手,就是我们看看这个Spark是如何给大家使用起来的,那么在当前情况下,大家会发现我要创建maven项目啊,然后呢,增加skyla插件,说到这里我们要说一下,咱们Spark采用的是3.0的版本,那么它对应的skyla版本是2.12版本,这个版本之间的关系是非常大的,你不要弄错了,你弄错的话就有问题了,比方说咱们那个B包检测功能,这个在2.11版本,就是2.2版本之前,它的实验方式跟盖LA的2.12就不一样,而咱们的SPA的3.0呢,恰恰是针对于2.12来做开发的,那么所以呢,它的B包检测的源码就发生了改变,所以啊,这个是不一样的啊,这个同学们一定要区分开啊,老师我拿这个版本拿旧的盖行不行,其实是会有点问题的啊。
03:40
好了,然后下面呢,是增加我们的依赖关系啊,这个依赖关系,然后咱们接着往下,下面呢,我们就给大家演示了一个我们最基本的word count,那么这种word count对于大家来讲,我相信呢,学到现在是不是应该已经很轻松了,该LA你们学了很多种我们的world count。咱们学Spark呢,也有很多种方式,很多的算子可以实现word看对不对啊,就是我们现在回过头来看一看,你会发现当时写的代码其实比较简单对吧?可能当时学的时候,哎,老师为什么这么写呢?诶现在反过头来看一看,哦哦,这个代码这么写我能很清楚的就明白对不对,所以呢,具体的细节啊,我们再不再跟大家去说了啊,这里面会有一些方法呀,什么f map呀,Map呀,就是be呀这样的一些操作啊,然后呢,我们接着往下啊,往下往下嗯,往下呢,这边会有一个我们的运行环境啊,就是我们能够把最基本的案例呢跑通,但是我们得有一个环境,这个环境呢,它分这么几种,第一个本地模式,第二个独立部署模式,第三个我们的什么雅安模式,还有什么mes呀,K8S呀,这种Windows不同的这种环境,这个我们都可以把它配好啊,配好以后直接跑就行了,就是一个环境嘛,那么我们给大家演示的第一个就叫local模式,这个local模式啊,什么都不需要,就自己解缩就能用了,对吧,这叫local模式,然后呢。
04:59
你就可以呢,去提交一些我们的指令,然后呢去看看我们的结果就完了,这个主要的目的就是用来做测试用的啊,把一些我们的程序给它提交就OK了,然后下面呢是我们的三模式,三模式呢,其实啊,它就是意味着我们的资源和计算全都用Spark的,不用别人的对吧?那么我们的资源和计算全都用我们Spark的话,那所以呢就得有master和worker的概念,因为咱们其实在学完之后,你会发现有个叫driver和execuor,那么我们的driver和ex其实是跟计算相关的两个节点,而我们的worker和master它是跟资源相关的两个节点,所以啊这个稍微的会有点区别啊,然后接下来是解压缩,然后呢修改一些配置文件,然后做分发,分发以后一启动,启动以后,那么我们三台机器的这个节点,我们就能够看得到了,Master啊,Worker worker worker啊,诶不就知道了吗?然后呢,你去访问它,访问以后来提交应用,在提交之后它会在运行。
05:59
当中产生咱们的driver和ex啊,把计算对象给它创建出来。
06:05
然后接着往下啊,下面下面呢,是有些参数的说明,这个参数说明啊,什么杠杠master啊,什么我们的杠杠class呀,这个要了解啊,杠杠class就是我们自己写的那个程序的类,刚刚master呢,其实就是我们的运行环境了。然后呢,接着往下,下面叫历史服务,这个历史服务是为了通过我们的服务呢,查看我们程序,或者说我们作业的一个运行的过程啊,就曾经执行的作业啊,它当时的执行情况,我们想看一看就可以增加历史服务了,嗯,后面呢,还有呢,配置高可用啊,配置高可用的含义呢,就是说当我们的某个节点一旦出现问题的时候,不能让我们整个集群崩溃,所以呢,我们需要多提供几个节点来做备用啊,所以就有高可用的概念,这里面会用到咱们的主keepper,对吧。好,我们接着往下啊,下面下面呢是我们的雅安模式,雅安模式啊,其实就是把海杜当中的雅安的框架呢给它提起来,提起来以后我们只要去做一个关联,关联好之后能够跟雅安连接在一块儿的话,我们一提交就没有问题了,所以这个环境是我们在工作当中用的比较多的,雅安呢是一个专门的资源调度框架,它的功能非常的强大,而我们的18UG它的核心就是计算,所以他没有必要自己去整一个资源调度,对不对啊,所以它更多的呢是完成计算就可以了啊好,咱们再往下吧。
07:29
往下它也可以配置历史服务,没有任何的问题啊,OK,接着往下,呃,下面呢是K8S,包括后面那个Windows,这个咱们就不再细说了,嗯,咱们接着往下吧啊。好,往下以后呢,这是它的一个部署模式的对比,以及它的这个端口号,这个呢,同学们下来自己看一看啊,然后呢,往下来往下来下面呢就是一些概念了,什么运行架构是什么样子的,这个里面就有driver和那个ECU的概念了啊,然后核心组件咱们叫driver driver呢它是一个Spark的驱动器,我们的节点,它是来驱使整个作业开始执行的操作,所以呢,它里面可以将用户的程序转换成作业啊,也可以呢在ECU之间来调度咱们的任务啊,这个咱们后面呢会详细的来说。
08:14
然后呢,咱们的E呢,它就是真正干活的,它就是我们具体执行任务的那个操作啊,然后呢,接着往下,Master和worker这两个呢,其实是在我们独立部署模式当中,就是我们用Spark来做资源调度的时候会用到的节点啊,这个呢我们知道就行了啊,然后这个叫OB master OB master它是跟我们的雅有关系的,因为盐呢,它需要将我们的这个计算框架可插拔,那么就降低和计算框架的耦合性,那么这个OB case matter就起到了这样的作用啊,它可以将计算和资源呢进行解耦合,就是这个意思。然下面呢,是我们的核心概念叫exor和那个Co啊,Exor就是我的计算节点嘛,这个Co就是我们虚拟的CPU的核数,那么一个我们的计算节点可能会有多个C的,对不对,这是有可能的啊,然后下面呢,是我们的并行度,并行度呢,其实就是并行计算的意思,比方说我有两个CPU的核,那我同时就可以执行两个任务了,这就是并行度为二的意思啊,为什么呢?你有两个CPU核吗?可以执行两个我们的任务,叫并行度V2,但是你说了我只有一个我们的这个核的话,你有多个线程来执行的话,这个时候可能就叫并发了啊,就不叫并了啊,所以这是两回事儿,下面呢是有效无环图,这个有无环图呢,是在计算过程当中,它会有一个,就是怎么说呢,叫做多个计算的功能,比方说我们有一个扁平化功能,有一个我们的过滤功能,有个排序功能,他把这些功能呢,给它做了一个连接,比方说先做什么后做什么。所以啊,它有一。
09:54
这个图形在里面啊,它这里就形成了点和线啊,比方说点和线,点和线呢,它有个方向,这个方向表述的是我们程序执行的方向啊,但是呢,它不能形成环状图形,如果出现环状图形的话,可能就绕不出去了,就会出现问题,所以呢它就叫有效无环图,它用点和线啊来连接我们的步骤,然后呢,这根线是有方向的,而且不能形成环状,就叫dag啊,就这么个概念,有向无环图啊,它的主要目的就是为了做调度用。
10:24
然后呢,接着往下啊,下面下面呢是一个提交流程,这个我们在给大家讲解的过程当中,咱们说了,我们在执行过程当中,它会有两个不同的操作,一个是资源调度,一个是计算调度,那么资源调度和计算调度呢,是两根线啊,你走你的,我走我的,最终把两根线合二为一,对吧,你资源有了,你的计算的任务有了,把任务呢发给资源不就可以开始计算了吗?所以啊,最终是合二为一,这个流程我们现在就是简单看一看就可以了,我们后面会给大家详细的去讲啊,咱们看看源代码当中它的执行流程是什么样子的啊。
11:01
好了,接下来是我们雅恩的两种部署模式,一个叫客户端,一个叫集群模式,在工作当中是没有人去用那个客户端模式的,在我们做测试的时候,为了看一看我们的直营结果的话,会用这种兰模式啊,但是一般情况下都是用那个集群模式,它们俩的区别主要就在于那个driver运行的节点的位置是不一样的,这个咱们后面呢,也会给大家详细的去讲,好吧,嗯。好了,接下来呢,就是我们的核心编程,这个核心编程当中啊,其实就是把我们的几个核心的数据模型呢,咱们讲解了一下,一个叫RDD,一个叫累加器,一个叫广播变量啊,那么我们其实这三个我们的核心的数据结构和数据模型呢,其实我们主要讲的是RDD,因为累加器和变量它的景比较,那么加器是在我数值加数据加的过去增加使用加的,而广变量是为了分享数据,对吧,在多个任务之间分享一些大数据的时候,我们用广播变量是这么一个过程啊,所以呢,我们其实这个讲的是不多,时间不长啊,咱们主要讲的是RDD,因为我们真正在开发需求的时候,实现那些业务功能所使用到的API,其实都是由RDD帮咱们完成的,所以这个咱们讲的比较多一些。
12:21
那下面呢,就说了什么是RDD,咱们为了给大家讲这个呢,其实我们给大家画了很多的图形,对吧,让你理解一下什么是RDD,怎么理解是分布式计算,怎么理解它的计算过程啊,咱们说了RDD呢,跟那个IO非常的类似,它其实底层呢,就是我们的那种什么我们叫装饰的设计模式啊,而且呢,它是一个抽象类,所以啊,它代表的一个弹性呢,不可变,可分区里面的元素可并行计算的集合,这些概念我们在之前的讲解当中说了很多了,同学们下来呢,要多多去看一看,好好的去理解一下好不好,同学们。好了,那接下来下面呢,就是它的一些核心属性,比方说什么分区列表啊,计算函数啦,包括依赖关系,还有什么分区器啊,首选位置之类的这些属性这些,嗯,我们的操作呢,同学们下来呢再理解理解啊,如果不理解的话,希望同学们多问一问啊,就是你不能说老师啊,这个东西我没有理解,那没理解就没理解了,就过去了,那不行是吧,多问问老师好不好,嗯,来继续往下,下面呢是执行原理,就是我们从最开始的启动服务到最终的执行是什么样子的,我们这里通过画图的方式给大家说离一下,第一个先把集群启动好,第二个我们在执行过程当中把我们的资源申请好,把driver equ给它准备好,接下来我们通过RDD呢,把咱们的任务给它准备好,然后放到任务词当中,再从任务词中把任务取出来,发给不同的ECU来做计算,所以RDD的操作其实就在这个位置,他要对咱们的任务的调度做关联啊,然后呢,放到任务词当中,然后呢,再往。
13:58
加执形就可以了啊,然后呢,我们接下来是我们的一些RDD的创建,RDD的创建分几种不同的方式,那我们主要给大家讲的就是从文件中创建,或者说从内存中创建,对不对?什么paradise呀,Make RD呀,包括那个test file啊,这些方法呢,我相信都不难理解,学到现在了,大家应该都能够记得住了,对不对?那么问题就在于你怎么去理解它,还有呢,那个我们的分区数量啊,咱们的那个嗯,并行度怎么设定啊,这个东西都是我们在讲的过程中去给大家说过的啊,这个呢,同学们下来呢,好好看一看,我们这里不再细说了。
14:35
这里面就有个并行度和分区的概念,嗯,好,咱们接着往下吧,往下呢,有个叫算子的概念,这个咱们讲过了,所谓的算子啊,其实就是那个operator叫做操作,也称之为叫方法了,嗯,只不过呢,因为我们呀,这个RDD的这个方法呀,它涉及到一个分布式计算的概念,就是driver和eor的分布式操作,那这个时候跟普通的那个盖集合的方法有区别,为了区分它们,我们把它称之为叫算子啊,所以这个不要误会啊,这个不是算子,不是说什么多高大上的一个词,其实它就是一个方法,只不过为了跟那个盖LA集合的方法做区分,你比方说咱们的RDD有map吧,你死该了即可也有map呀,那你这个东西你就容易搞混呢,对不对,所以啊,咱把它称之为叫算子,可能就诶好明白一些,最起码能够区分开,这不挺好嘛,对吧,嗯。
15:27
那么我们R呢,根据它处理的这个数据的类型不一样,分成单子型双类么,里面就给家到了很多的方法,这个呢,方法太多了,我们就不再一个一个跟大家说了,我们说重点说什么呢?第一个就是那个沙uffle。啊,就是那个杀uffle,因为在我们后面的学习过程当中啊,咱们这边会有一个杀uffle操作,那么所谓的杀Le操作呢,其实就是将数据打乱重新组合,那么你为什么要重新组合呀?就是因为我要做汇总嘛,要做聚合统计嘛,那我就要打乱重新组合,而这个打乱重新组合它是有沙Le的,那么我们学到现在你就要明白,我们的沙uffle是一定要落盘的,为什么呢?因为你不落盘的话,你是不可能在内存中来等待数据的,你要在内存中等待,把这数据聚合好之后再往下做的话,内存不够,对不对?那所以我们应该在文件中等待,如果你在文件中等待的话,那么我们需要所有的。
16:27
分区的数据全部执行完毕才能往下执行,所以这样的话,就把咱们当前的程序呢,就分成两段啊,所以会有个分阶段的概念,分成两段的原因就是因为前面一段呢,如果不执行完,后面一段是不让你执行的,对不对?所以啊咱们分成了不同的阶段,这个我们正好后面呢也要提到这个阶段的概念,而每个阶段呢,它有自己的独立的任务啊,你这个阶段中的任务要全部执行完了,才在下一个阶段去执行,所以啊它是有这样的要求在里面的啊,所以这个沙uffle其实它会直接影响咱们作业的一个性能问题,你的沙uffle越慢,整个作业就越慢,如果要杀Le要是性能快的话,那么其实整个作业的执行性能就变快了。
17:10
好了,同学们,这个我说过了,咱们这个算子很多,咱们在做总结的时候,这个就不再去给大家去说了啊嗯,OK,咱们接着往下,呃,往下以后啊,咱们在这个地方有一个什么呢?有一几个关键的点,咱们说一下啊来咱们说一下,就是我们这个叫做,诶不是这个东西啊,咱往下。呃,往下有一个叫键子类型,这个键子类型的这些方法呀,其实它来自于我们的pair尔r DD function是那么一个类,并不是来自于RDD,它底层会有隐私转换,我们自己啊,可能学隐私转换的时候,当然老师也讲过是吧,我们自己可能不去写啊,但是我们得能看懂的,知道别人怎么去用的,那这样的话我们明白之后好去什么使用它对不对啊,我自己写不出来,别人写的我也看不懂,那你这就麻烦了啊,所以同学们千万注意啊,就是我自己写不出来,但我要能看得懂,知道怎么回事啊,这里面会有隐私转换功能,嗯,好,然后后面呢,会有什么reduce by key呀,什么BY呀,还包括什么我们的这个GGBY之类之类东西啊,那么这里面的group by key和这个reduce by key经常会在一块来问,为什么呢?问他俩为什么一个效率一个效率快,其实啊,它主要涉及到S过程当中写数据的问题,你S的这个,嗯,我们说了,当我们的数据容量是一样的话,如果你。
18:28
的这个数据量在沙发的时候如果能减少的话,那么你写磁盘就变快,你读磁盘也就变快了,你的性能就得到了极大的提高。而我们的group key,它是不能够在我们做沙的时候把数据减少的,做不到,但是咱们的reduce key有一个叫预聚合功能,预聚合功能它可以实现这样的操作,所以这样的话我们的性能就得到了提升,对吗?同学们,所以啊,就是这些东西我们之前都讲过了,可能大家印象不深了,我提一提,大家回去呢再好好看一看啊,咱们前面讲了那么多算子,我这里我说了都没有提,但是并不是说它不重要,只是因为太多了,我们缩起来太太麻烦了,你们下来呢,要每个方法都自己写一写,用一用,不一定在什么需求当中就把这个功能用上了啊。
19:15
好了,咱们接着往下吧,同学们来往下啊,嗯呃,往下呢,这边会有一个咱们的叫做什么呢?来来来往下走,往下走,嗯,有一个诶阿里实操,这个按理实操呢,其实就是我们之前给大家讲的它的一个转换的操作,对吧,咱们去转换,这个咱们也不再细说了,下面呢,有个叫行动算子,咱们前面叫转换算子,转换算子呢,是把一个旧的RDD给它转换成一个新的RDD,我们称之为叫转换,而所谓的行动呢,就是触发我们的作业的执行,那么你触发作业的执行的话,那么我们的作业它有个叫run job对吧,底层代码,那它就会开始运行了,底层会有个叫active job的概念啊好,这个呢我们就说到这,具体呢我们这里就不再说了,嗯,然后呢,这里面有一个叫做什么呢?咱们叫做aggregate,这个稍微的单独的说一说吧,因为这个aggregate啊,在我们之前学过一个叫aggregate by key,那个aggregate by key呢,它是我们的什么呢?就是初始它只参与我们分区内的。
20:15
计算,那么分区间它是不参与的,但是我们这个aggregate它的那个general value初始值,它会在我们分区内和分区间都进行计算,对吧?所以这个呢,我们需要大家注意,别的其实都没什么了,嗯,好,然后接着往下,下面呢有一个叫风,这个我们千万要强调一下,因为我记得我给大家写代码的时候,我是有意识的去规避了这个方法的使用,我为什么要规避这个方法的使用呢?我是希望大家能够明白,那我们分布式计算到底是怎么回事儿啊,就是我就没有给大家去用这个for啊,但是我们讲到这个地方的时候,我们就要给大家讲RDD点,你会发现你打印的数据是乱的,为什么乱呢?是分布,是打印,谁先执行谁后执行是不确定的,对吗?啊,那不确定的情况下,那我们就需要考虑清楚了,对吗?诶就是这样啊好,我们接着往下啊往下下面呢,就涉及到这个序列化的问题了,因为你是分布式嘛,那么你就要从driver当。
21:15
中把数据呢,给它传到excuor来进行操作,那么这个操作过程当中就需要你的数据要能够序列化,能够序列化,那我们怎么知道你能不能序列化呢?所以它有一个B包检测功能,因为我们要想序列化的话,你肯定是从driver传给ecuor,那么我们一般情况下是有B包的,有B包的话,我在检测过程当中就可以判断你到底能不能序列化,所以啊,这是我们的一个序列化的操作啊,有个B包检测,嗯,然后后面呢,我们给大家在讲解过程当中啊,我们这里还涉及到一个叫K啊yo的序列化框架,这个框架对于我们来讲应该其实啊是怎么说呢,比较麻烦,麻烦在于啊,它会涉及到很多类的去写,为什么呢?因为它不可能说让我们的框架直接使用这个这个KR,那这样的话,我们的这个所有的类都使用的话,感觉上倒挺好,对不对,还是会有问题啊,有问题为什么呢?它的那个数据到底怎么转换不是很方便。
22:15
所以呢,这个其实在底层当中啊,它只有一部分的数据使用了kr yo,绝大部分自定义的数据是没有办法用kr yo的,你要想用可不可以,可以需要额外的这些代码,操作就有点麻烦了啊,所以k yo呢,其实它的性能还是各方面不错的,但是不好就不好带,不能对任意的类进行序列化,对吧?就这个要求啊,好,接着往下,下面呢,是我们的依赖关系啊,这个依赖关系啊,其实就是我们的A和B他们的关系,我A用到了B依赖于B,对不对啊,就这个意思啊,这就叫依赖关系,但这里面还有个叫血缘关系,所谓的血缘关系呢,其实就是多个依赖所形成的一个关系啊,对吧,我们A依赖于BB,依赖于CC,依赖于D,那这样的话就形成了一个血缘关系。
23:00
啊,好吧,同学们就是把这个依赖和选呢给它区分开就可以了啊,那为什么要有这个关系呢?就是因为我们在分布式计算当中很容易出现错误,那么一旦出现错误的话,那我们到底从哪里开始从头执行呢?我得找到它的最开始的位置,就是你的血缘,根据你的血缘找到你最开始的位置来得到数据的一个什么,我们的处理的一个源头,然后呢,按部就班的一步一步得到我现在的结果,所以啊,它其实就是为了什么?诶,重新计算用的好,接着往下啊,下面下面叫依赖,还有这个叫宽依赖和窄依赖,那么宽依赖和窄依赖呢,其实主要指的是分区数据之间的关系,我们的上游啊,大家看一下啊,咱们的上游,上游的一个分区的数据被下游的什么多个我们的分区所共享的,那如果上游的一个R下的R。
24:01
数据所独享的话,那么其实就是一对一的关系,我们就称之为叫窄依赖啊,一对多咱们叫宽,一对一就叫窄依赖了啊,所以这边就有个叫one to one dependency是吧?那么下面呢,有一个叫shuffle dependency,这叫宽依赖,那么这个宽依赖为什么叫shuffle呢?是一般我们有shuffle的依赖的话,就存在了杀口操作就会有落盘处理啊,有落盘处理,嗯,好,接着往下,下面就是我们的阶段划分了,咱们刚才说过了,我们再去执行操作的过程当中,我需要知道我们到底有没有小沙uffle,那么如果有沙uffle的话,我们就得把它分成两段啊,前面一段要执行完毕才开,后面一段执行,所以它要分成两段,那么分成两段的情况下,那么就有涉及到一个阶段的划分啊,到底分几个阶段呢?分一个两个三个对不对,还要分几个阶段,我们再给大家讲这个的时候啊,是看了它底层的源码,它的底层源码当中其实是判断了一下我们。
25:01
到底有多少个什么我们的杀Le依赖啊,你的杀Le依赖的个数决定了我们到底有多少个阶段,对吧?我们本身就一个阶段,诶,你增加了一个沙浮依赖就变成两个了,有两个杀依赖就变成三个了,对吧?就这么个意思,嗯,然后接下来呢,还有一个叫任务的划分,那么任务的划分呢,其实对于我们来讲就是我们任务该如何确定,那其实啊,我们看过源码之后,你会发现最后就是一个阶段的最后RD当中的分区数量,其实就是它任务的数量,所以咱们今天就讲过了,你的分区数其实跟你的任务数没有什么太大的区别啊,就是这个意思啊。好了,接着我们往下啊,往下往下来啊,下面呢叫持久化啊,这个持久化呢,我们给大家讲了两个,一个叫一个叫persist,那么他们都是用来将数据持久化的,但是我们的cash呢,默认是保存到内存当中,对吧,但是你要说保存到文件中也可以啊,想保存到文件中也可以,但是这个保存到文件当中啊,它有个问题,当我们。
26:01
的程序计算完毕之后,你的这个保存的文件就会删除,为什么呢?它是以我们的作业为单位的,当你当前的作业执行完毕之后,那么临时保存的数据呢,就全部完成了,给它删掉,可是我以后想用怎么办?哎,这个时候呢,我们就要用另外一种方式,咱们叫检查点,叫checkpoint,它可以将咱们的数据保存到我们的分布式的存储系统当中,哎,是这么回事儿,这样的话呢,我们就可以重复来利用咱们的数据,对不对,哎,就是这样,所以啊,咱们的这个什么持久化呀,包括检查点呢,它首先就有一个功能叫重复使用的问题,还有第二个,第二是什么呢?就是什么当一旦出现了问题的话,我们会从指定的位置来进行数据的读取,这个其实也叫重用,对不对,但这个重用呢,是我出现问题的去重用,而不是正常情况下去重用,这是两回事,对不对?哎,两回事儿啊,那么这两个其实是有区别的,所谓的区别就在于我们的这个。
27:01
这句话的操作是有可能因为一些特殊的情况导致数据丢失的,所以在这种情况下,我们需要从头把数据再读回来,那么它就不能切断血缘关系,而我们的这个持久化呢,它会把数据保存到分布式存储系统当中,数据更加的安全,所以他就不需要再从头去读了,他们只要从检查点去读就行了,所以它是可以切断血缘的啊,这个呢,我们再说一下啊,嗯,好了,接着往下,下面呢是分区器啊,就是自己来定义我们的数据的分区规则啊。好,咱们再往下往下啊来往下呢,就是我们文件的读取和保存了,这里呢,给大家讲了一下什么text这样sequence object这样的一些操作啊,嗯,后面呢是累加器,那么累加器呢,其实就是数值累加嘛,数据累加对不对啊,它是一种特定的数据结构,它的这个含义是什么意思呢?就是说我们的driver。啊,有一个ecuor,咱们的driver和ECU啊,我们的driver把数据传给ecuor,但是默认情况下使B是没有办法把结果返回回来的啊,这个它做不到,那这样的话我就没有办法来聚合咱们的计算结果,所以为了实现这个功能,我们就有个累加器的这种操作,我们可以在我们传过去值之后,由框架由Spark将咱们结果往回返再做合并,注意啊,有这么个操作,这个就可以用累加器实现,所以累加器其实是有合并的概念的啊好,我们接着往下,具体的这个实现过程和步骤呢,我们不再详细的给大家说了,咱们把原理再说一说,其实就够了啊好,接着往下,下面呢有一个叫广播变量,这个广播变量其实是用来共享数据用的,它为什么要共享数据啊,是因为咱们默认情况下,我们的driver啊,他给我们的executor传数据,其实它传输的单位并不是excuor,它是那个task。
28:57
他才那个task,就意味着我们的driver会把数据给task,那一个task传一份,两个task传两份,三个task传三份,那么task越多,你传的越多,可是你传的是相同的数据,那这样的话就会导致我们的内存中有大量的数据冗余,而且你长时间的占用内存,性能就下降的特别厉害,所以啊,我们就希望干嘛呢,把这些共同的数据给它,诶放在我们E的内存当中,你放在的内存当中,哎,共享给他们的task,这样的话数据只存一份不就够了吗?这样的话节省了内存空间,就可以提升咱们的效率,所以啊,广播变量其实是用来提升效率的啊,它可以节省内存空间,就这么个意思,嗯。
29:45
然后它的用法也非常简单啊,这边有个叫broadcast,给它封装好,封装好以后在里面用一用就可以了,嗯,好了,后面呢是案例实操,这个咱们就不再说了,所以呢,简单的通过咱们的课件,把咱们之前讲过的内容梳理一下,也算做一个总结吧,好不好,同学们,行了,18课咱们就讲到这里了啊,同学们,我们后面会讲新的模块。
我来说两句