前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一行Spark代码的诞生记(深度剖析Spark架构)

一行Spark代码的诞生记(深度剖析Spark架构)

作者头像
大蕉
发布2018-02-05 18:02:34
6680
发布2018-02-05 18:02:34
举报

大家好,我是一行Spark代码,我叫小小小蕉,不知道为毛,我爸爸大蕉和我妈妈大大蕉把我生的又瘦又长。长这样。

代码语言:js
复制
val sssjiao = new SparkContext(new SparkConf().setAppName("sssjiao").setMaster("yarn-cluster")).parallelize(Array(""));

我真的,不知道怎么说,好长好长啊。。总有小伙伴对着我说:

问君何不乘风起 扶摇直上九万里。

说出来不怕吓着你,其实我一个字都看不懂。

作为一行普通的代码,我也开始思考码生的三大问题,我是谁,我从哪里来,要到哪里去。

我从我从哪里来,开始讲我的故事吧。

我从哪里来?

这有什么好说的,出自我爸爸大大蕉之手,就酱。

本文终。

当当当,你以为就这样结束了吗?不可能的。我长得这么细这么长,其实我是由三个部分组成的。分别是SparkConf,SparkContext,RDD[String],从代码层面来说,就是定义了一个SparkConf的配置,来生成一个SparkContext上下文,然后用这个SparkContext来对数组进行序列化,我就被产生出来啦。

但是我今天不仅仅是想介绍这么浅层的来源,毕竟爸比妈咪生得我那么辛苦是吧?

(要开始Spark on yarn的深度剖析了)

大大蕉:yarn兄,我要生一个儿子,oh不我要产生一个Spark任务了,能帮忙拨 点行政资源不?

yarn :啥玩意,你想干啥?要尊贵的cluster模式还是平民的client模式?

大大蕉:这两个有啥差别?我头胎。

yarn :client就你用你自己粗糙的Driver,cluster模式就我给你分配一个高配置又漂亮的Driver。

大大蕉:那行,给我来个尊贵的cluster吧。

yarn :等着。

yarn :歪,ResourceManager吗(管资源的,下面简称RM)?你那边不是在管资源吗?咱这有货吗?赶紧给我空运一个高配的机器,嗯对,用来跑Driver和ApplicationMaster的,嗯对对对,我们这边有人快生了。对,急急急,这辈子就这要一次最急。

RM :知道了(一脸嫌弃懒洋洋)。

过了0.00001ms,对于CPU来说过了好久了

RM :NodeManage(每台机器的管家,下面简称NM),歪,根据记录你那里的配置恰好够用,你那里的Container1容器我征用了,就这样。

NM :我R。。。

RM :yarn老哥,给你那个名字为container-1的容器吧,他的地址和配置信息(CPU,内存)在这,你收好了。

yarn的最小分配单位为Container

yarn :好的,非常感谢,后面有事情还麻烦你。

yarn :大大蕉吗?Container拿到了,就是Container1,自己去看看怎么生吧。

大大蕉:好的。掰。

大大蕉:(自言自语)根据说明书,先启动一个ApplicationMaster,名字叫做sssjiao,用来管理这个Job和Container。再先启动一个Driver,来管理DAGScheduler(有向无环图管理)和TaskScheduler(任务调度管理),BlockManagerMaster(数据块管理的Master)。咦,那我去哪跑任务呢?还差一些Worker工作站啊。

Spark将一个大的任务拆成一个有向无环图,来表示依赖关系。

大大蕉:歪。yarn吗?嗯是我。我这好像还差点东西啊。。我还需要一些Container来做我的Worker啊,不然我儿子生完往哪放啊?

yarn :知道了知道了,不会一次说完吗?真讨厌。

大大蕉:我。。。我™也不知道需要这个啊。

yarn :歪。RM吗?嗯又是我。我需要一批Container。嗯对高配那种。对,急急急,这辈子就这一次最急。

RM :知道了。(不耐烦)

RM :NM-A,NM-B,NM-C,NM-D,你们几个的资源我都征用了。

NM界一脸懵逼,都感觉自己被抢劫了。。

RM :歪,yarn老哥吗?资源都ok了。ContainerA,ContainerB,ContainerC,ContainerD。

yarn :好嘞。

yarn :大大蕉。资源拿到了,信息我装在信封里了,你拿好吧。

大大蕉:嗯,我还想问一下,后面的(电话那头传来嘟嘟嘟挂断的声音)。步、骤、要、怎、么、走。算了还是自己看说明书吧。

首先在Container里面启动一个或者多个Executor,然后启动一些jvm和BlockManager。好了现在Driver、Master和Worker都有了,完事具备,只欠东西南北风了。

到这里,SparkContext算是初始化完了。

大大蕉抓着头发,一脸茫然地看着面前这堆玩意,要怎么玩。。。

诶,再看看说明书吧,看看有没有说怎么玩。(大蕉自言自语道)

突然空气中响起了旁白:切分、分配、切分、分配。

对!这个job可以先用DAGScheduler进行stage切分。

切分完然后用TaskScheduler进行任务调度分配。所以一个Job就被切分成很多个stage,封装成很多个TaskSet,然后每次Executor来请求任务的时候,就给他们分配一个,所有的Executor执行完成后又向TaskScheduler报告进度。

Task失败了?报告TaskScheduler。从头开始重新跑。

Task太慢了?TaskSchduler找多一个Executor并行跑,谁先跑完就用谁(好残忍)

Stage挂了?TaskScheduler报告DAGScheduler重新进行Stage拆分,看看是从当前开始重跑还是要用从父stage重跑。

好了到现在,小小小蕉我,还没有被产生出来。。

然后SparkContext就我的前辈Array("")进行序列化,然后根据key,也就是每个字符串进行分区,分区完之后把分区信息和对应的Executor保存起来。然后呢根据分区信息把数据发送到Executor那边去。所以我的本体RDD是在Driver的,但是我被分成很多份很小份很小份放在Exector里面的。

我是谁?

我是一个RDD。全名 RDD(Reilient Distributed DataSets)弹性分布式数据集。

我要到哪里去?

我后面的任务就是进行具体程序的执行,一个job一个job,一个stage一个stage。

这里再深入,就是从编译完的.class文件,用JVM的ClassLoader类加载器,加载完变成一个真正的类,然后再又JVM编译成机器码,在堆里开辟一点内存初始化一个String对象,在栈里开辟一点内存初始化一个指针。

然而跑完之后呢,我又将何去何从呢?

然后10M以下的就直接放在结果返回给TaskScheduler啦。

如果在10M以上的,就放到某个BlockManage,只返回BlockId了。

通知TaskScheduler说跑完啦。

然后TaskScheduler就通知DAGScheduler说跑完啦。

然后DAGScheduler就通知SparkContext说跑完啦。

然后SparkContext就通知Driver跑完啦。

然后SparkContext就准备要stop了。

大大蕉 :歪,yarn吗?我儿子生完了,资源都还给你把。

yarn :好。

yarn :歪。RM吗?刚刚申请的资源用完了,你把它们标记为可用把。

虚拟机 :这行又瘦又长的叫sssjiao的代码是谁啊。。好像被人丢在这了,诶当垃圾回收了吧,然后就给小小小蕉脸上盖上了一个待回收的印子♻️。

过了不久,小小小蕉就被GC(Garbage Collection)回收了,但是它脸上洋溢着笑容,它,是快乐的。

这就是小小小蕉快快乐乐的一生。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-08-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 一名叫大蕉的程序员 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
大数据
全栈大数据产品,面向海量数据场景,帮助您 “智理无数,心中有数”!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档