背景
在Spark的网络环境中,Netty是进行RPC通讯的底层通讯模块,在Netty之上,Spark构建起了一整套的通信发送与接收处理机制,这个机制涉及到了Spark 的Dispatcher ,MessageLoop ,Endpoint ,Inbox 等一系列的概念和关系,理解诸如这些概念和关系是很多Spark初学者的挡路石,为了能让初学者以及一直使用Spark的同学深入了解这些概念和内容,我准备写一个专题,叫做《大画Spark》,通过一系列相视的生活中的例子,大家都能听懂的常识,以及生动的插画(这块以后准备和插画师姐姐一起合作)来讲清楚Spark的逻辑。
在这个过程中,无论是技术同学还是非技术同学,你们会发现,所有的复杂架构模型最终都是上升到一套管理哲学体系,而不是简单的代码的堆砌,所以,程序员→Leader→架构师→技术总监→CTO的成长之路其实也就是一个对这个世界不断认知、自我抽象了解、理解、举一反三,从而最终自我消化并创新的过程。
问题
你在阅读源代码,或者理解一个架构体系的时候一般怎么做?
搜索概念看网上大牛怎么说
这个是一般人的做法,初级程序员,打开百度,中高级程序员打开google。问题是,这些回答是正确的么?
看官方文档
进阶一点的同学会选择看官方文档,那里有真实详实的介绍,原汁原味,不会有错。问题是,很多原理可能讲的不够细致
参加培训机构
更进阶的同学,为了自己更好更快的了解技术,重金参课,这个方法会有个讨论的圈子,也会有个答疑的渠道,地区会很快的了解很多技术细节。问题是,你消化了么?
看源代码
这是一条无法回头的路,也是一条荆棘密布的路,然而,却是一条最有效的路。走这条路其实建议的是在上面三种选择都走过,或者走过前两种之后,再来走这条路。因为惟有这条路才可以让你真正理解并掌握这门技术
好处
- 可以了解技术本质,可以更好的在使用的过程中排查问题,降本增效
- 而在我看来,随着阅历的增长,你会发现,所有好的架构体系下的源代码都是一门非常生动的管理哲学体系,这套体系不仅是你以后去构建技术平台的标准与参考,更是如何去管理企业的黄金标准,而且,并不难,不信?咱们可以看看
困难
在理解一门技术和源代码的时候,都会经历非常折磨且焦虑的过程,一整套架构动辄几十万上百万的代码体系,如何去看?如何去理解?对很多人来说都是一个不可能完成的任务,对我来讲,刚毕业的时候让我去想想写出几十万行代码来完成一个小的系统那简直就是天方夜谭,那个时候的我对于技术其实是有抵触情绪的,但随着工作年限的增加,对于技术的理解和兴趣却在与日俱增,原因就是,这些技术中的原理都是在讲述一个个生动鲜活的故事,而你的不理解仅仅是没有去get到其中的精髓而已,我们可以一起往下看
读不懂
作为不说英文的人群,我们对源代码的理解是一大困难。很多初级程序员的代码中最大一个特带你就是会充斥着汉语拼音,其实,这是我们所有人的诉求,我们渴望从代码中快速理解每一个变量每一个方法每一个类的含义,面向对象OOP所有人都知道,而真正理解的又有几成呢?对象是什么呢?这些对象映射到现实世界又是什么呢?为什么要有面向对象呢?好处在哪里?
举个例子,我们实际工作当中,如果是后端开发的同学,很多都是在Controller 和Service 中写面向过程的批处理,过程无外乎CRUD+缓存,测试的时候解决变量传错的各种低级bug,日复一日年复一年,如果持续做这个过程,为什么不去做嵌入式开发呢?直接把c代码烧到硬件中,效率高提升快,数据结构的理解还会更加深刻
一些基础的英文需要理解到它的本质含义,如Master,Manager,Worker,Executor,Client,Server等等等等,这些基础到不能再基础的词汇恰恰很清晰描述出了层次关系职级体系
跳出定式思维
所以,先要跳出一个老的框架性的思维方式,试着先去理解OOP,理解抽象的概念。
《未来简史》这本书非常推荐,你会发现,我们习以为常的很多东西其实都是想像出来的,国家,社会,公司,期指等等,这些想像出来的东西在我们社会中却又好像是完全存在的。比如一个公司,你就会觉得你每天的办公室,你每天的写字楼就是你的公司,然而,这个写字楼中每个房间只是一个物理客观存在的屋子,挂上了公司的logo就是公司?有个前台就是公司?大家聚集到一起为一个同样的目标每天工作就是一个公司么?你有想过这些事情本质到底是什么么?当有一天公司倒闭了,牌子撤下了,家产变卖了,公司就不复存在了,这个时候在你看来这个公司好像就没有出现过一样,而公司存在的时候为什么又是存在呢?
答案很简单,客观存在的物理现象和事物之上,人类其实抽象和想像出了很多的概念和虚拟的实体,这些实体按照一系列的规则在人类社会中组织着我们的生活,让人们“认为”它们就是客观存在的实体,其实,按照尤瓦尔·赫拉利的说法,那都是人类的想象,其实也是一种抽象。
联想一下
上面跳出定式思维的例子,我们可以做一个联想。
你所在公司的大厦,物理存在。我们把它想做一个巨大的内存。
你的公司,按照我说的观点,是一个想像出来的抽象概念,我们可以定义为一个Java中的Class,叫做ExcitedCorporation.java,当公司建立的时候,我们即new出了一个ExcitedCorporation.class,即在大楼中租用了一层楼,你是公司的CTO,那么ExcitedCorporation中可以有一个叫做CTO的变量,而你的办公室不能被随意闯入,所以应该定义为private,那公司内部可能还有CEO,PMO,各种developer等等等等,把这些内容组合在一起,成为了一个ExcitedCorporation。这些部门的相互关系、协调、组织,形成了他们的各种调用和处理过程。
而当你的ExcitedCorporation运行不好,关门打烊的时候,大厦把你们清退,变卖财产,下一个企业检修入住,NextGenerationCorporation.class在你原来的公司位置重新挂牌经营。而你的ExcitedCorporation就消失在了历史长河中,好像从没有出现过一样。
这个小小的抽象能力,相信很多做过开发的同学都看过,也都理解这样的例子,而这个过程就是你如何去理解每一个技术架构,理解每一套技术标准的最好的发散性思维准则,带着这种感觉,跟上我的想象力,让我们来进入今天的主题,听我给你讲述一个集团一个企业的故事,让你理解,哦?原来这就是源代码,这就是spark。
雅恩集团(背景)
雅恩集团是一家大型的民营食品服装轻工业原材料提炼加工集团,成立于2006年。集团在全国各地有自己的加工工厂也有OEM工厂,加工的范围从成品食品到服装鞋帽,遍及社会民生的各个方面,在多年的运营管理中积累了一整套现代化企业管理的规范,加工流程的规范,并借助先进的软硬件设备成为了国内领先的上市企业,股票代码是: YARN 。
雅恩集团并不是生产各种成品,而是对基础原材料做二次加工提纯等高科技的加工操作,并把高纯度的加工材料进行存储的企业,从某种程度来说,雅恩集团是一家科技型的化工企业。
关于雅恩集团的管理理念,我们可以在以后慢慢聊,这次我们先聊一聊雅恩集团内部斯帕克公司的生产调度部门之间的高效的沟通交流机制。
雅恩集团虽然是民营企业,但是CEO早年留洋,对于所有企业内的人员的Title都喜欢给一个英文名称,包括公司名称等等,这在很多当下的企业中司空见惯,有些企业甚至用动漫的任务形象来命名,并且,公司也会承接海外的项目,所以集团内的下属企业也都有自己的英文名称,后文细细道来。
管理组织架构
雅恩集团总部在北京,总部是职能部门,核心董事会主席的英文名字叫做ResourceManager 主管公司的企业战略规划,组织架构调整,ResourceManager 有其自己的董事局成员一起主持公司大事。ResourceManager 按公司长成,配合董事局成员,进行在全国各大区以及区域的旗下企业的管理与协调,对子企业的管理采用资源统一调配,而企业内的工作与协作采用协作调度式的放权策略,子企业需要与集团进行业绩汇报,集团对企业的工作情况进行监管,并对效能提供不断的改进和调整策略。最近,雅恩集团刚开了战略部署会议,准备在天津成立雅恩集团第二总部,应对业务量不断扩张带来的管理压力,以及对北京总部一些任务的分担,比如在一些政策影响的情况下也可以把天津作为集团总部,北京作为其他职能的堆外窗口,两个集团行政管理中心可以各司其职,也在做一系列的战略调整。
技术解读
YARN 中,ResourceManager 的角色跃然纸上。而如果担心一个节点有安全隐患,还有StandBy的天津分ResourceManager 。当然,实际的管理当中,不会有企业设立两家top权限职能的中心,这里只是做个比喻而已。本章重点不是YARN ,而是Spark 中的消息处理机制,即Dispatcher 的过程,这里YARN 一带而过,作为基础背景。
雅恩集团的8个大区(8是一个举例的随机数)
雅恩集团现在在全国划分了总部,东北大区,华北大区,华中大区,华南大区,西北大区,西南大区,华东大区,8大区。对于一家大型生产加工企业来讲,对整体资源和行政区域的划分是非常重要的,对于每一个大区都会独立的管理起来,这个管理者叫做大区总监,集团给他们的title叫做NodeManager ,代表对每一个大区行使管理权的大区总监,这些大区总监会与总部的董事会主席(ResourceManager )进行沟通与汇报,时刻让集团核心了解到每一个大区的运营情况,方便做出战略调整与判断。比如有新的加工和生产的任务,首先需要董事局了解到各个大区的生产与负荷情况,是否可以快速保质保量的交付生产结果,选择最优的区域和资源进行生产工作。
之所以这样去划分大区其实也有战略意义,不同的大区有着不同的特点,可以生产加工不同的原材料,并且,总部以及下属企业公司也可以根据实际大群内的物料仓储情况来进行科学调度策略。
区域架构图
组织架构图
技术解读
YARN 中,有ResourceManager 进行资源统筹管理,那么也会有NodeManager对每一个节点的资源进行单独管理,ResourceManager 与NodeManager 通过RPC不断的通信沟通,NodeManager 不断汇报资源使用情况,ResourceManager 总揽全局进行不断的协调与调整,并把新的任务不断分派。每一个大区(NodeManager ),就是我们的一台资源物理机,而ResourceManager 也是物理机。
雅恩集团的2大龙头生产企业
雅恩集团下属2家最大的龙头生产企业,分管两种不同加工与研发模式
-
订单式批量成品加工——由斯帕克有限责任公司负责(公司英文名称Spark) 公司特点是按照订单进行批次加工,每次加工都采用项目制的方式,有不同的行政角色、管理角色、技术工种等多种角色共同参与进行,加工完成后一般会从项目上解散掉团队。资源回归到公司内部,等待后续新的开发加工工作再重新组建整个生产团队。 -
原材料的挖掘提炼研发——由茯苓克有限责任公司负责(公司英文名称Flink) 这是集团的核心技术部门,旨在不间断的进行原材料工艺的精进工作。众所周知,加工生产企业对于原材料技术的掌握是非常重要的,大家可以去搜索一下鸿海集团对于原材料工艺技术不断研发的例子。所以,对于这块工艺的加工探索与开采则是一个不停息的过程,即每天都会实时的去科研,实验,交付验证,与斯帕克的项目制加工生产有些实效上的差异。
雅恩集团的物流仓储企业
除了生产加工,雅恩集团还有自己的仓储企业,海肚铺物流仓储有限责任公司(公司英文名称Hadoop)。仓储是生产企业的核心能力,也是加工的基础,这个企业的能力与运作模式有空可以大画一下。
斯帕克有限责任公司(背景)
公司简介
斯帕克有限责任公司初建于2009年,在建立初期,公司一直在不断摸索新的管理与生产模式,旨在自动化串联生产步骤,提升原材料的科学化仓储运输与调拨,通过一系列的改进最终达到降本增效的目的。在2013年公司发布了自己的行业标准,并在实际生产中不断提升与演进,其模式已经遍布全球很多大型企业当中。现在是雅恩集团内的最大生产加工企业之一。
核心竞争力
这里略略有些科幻色彩,不过便于理解,我们需要一定的想象力。By dclar
斯帕克这家公司虽然是一家生产加工企业,但是它有一个最大的特点——移动式加工模式。
我们都知道,物流存储是重型的产业,加工的物料在某个地区和仓库存储的时候,一定要借助物流运输运送到加工企业,而运输的成本,途中的不确定性都是风险,比如运送危险液体,运送的保质条件苛刻的物品,路况拥堵造成的影响会对最终的加工产生非常大的时效影响。
传统模式下,加工厂房与仓储厂房分离,需要从仓储货运到加工厂房,费时费力,路途遥远。斯帕克公司采用直接在仓储中心旁建立基础厂房,把货运路程缩短为0,并通过总部直飞运送工人与基础设施的方式来进行物料加工,杜绝了运输的成本,使得加工变成移动化操作。
并且,在整个加工过程当中,可能是多大区多仓库的协同工作,在这个过程中也会引入一个管理协调部门参与到其中,统括所有的生产过程。
图解
-
过去的模式 -
现在的模式
技术解读
经典的大数据中的理论,移动计算,而不是移动数据,找到相应的数据节点进行直接计算,比在网络间传送数据效率要高很多。Spark也是如此。
斯帕克生产加工任务的沟通协调过程(Spark中的Dispatcher)
斯帕克公司在处理这样的物料加工任务的时候早已总结出一套自己的工作模式
- 尽量不移动物料,移动的是轻便的加工能力(这里指图纸,员工等一系列资源)
- 一套行之有效的管理和调度策略,帮助整个生产过程的有序进行
管理模型
前文说到,斯帕克公司善于采用调用人员和轻便加工设备的方式来进行开发,而尽可能的减少物料的移动。而其管理方式亦是如此。
- 总部接收到订单后,会根据不同大区的资源情况首先委派一名本次订单的生产管理总监,这个总监具体在哪个大区指导工作由董事局主席
ResourceManager 说了算,所有大区总监只有上报汇报的权限,可见,这样的生产模式避免了裙带关系 - 图中赵帅帅到达华中大区后,立刻向董事局主席
ResourceManager 汇报情况,申请生产加工资源,根据总部的协调,最终确定在华南大区和西北大区两个大区开展生产工作 - 后续赵帅帅会根据一系列公司长成与授权在两个大区启动其生产基地(
Container ),并在生产基地中规划生产部门(Executor ) - 当一切就绪后赵帅帅会远程控制这两个生产部门进行生产,根据反馈情况不断的进行协调工作
- 当加工工作结束后,整个团队后进行收尾并进行项目解散
生产调度委员会(Driver)
在赵帅帅的直接领导下,对于整个生产过程会启动一个生产调度委员会的组织,这个组织非常庞大,里面包括很多子部门,部门内还会有办公室和其管理职能部门等等,本次我们主要介绍信息的一个过程,我只举几个简单的例子,图中的红色区域
下属部门
来看一下生产部管理总监直属的生产调度委员会中的结构
- 生产总署(SparkContext),是斯帕克公司进行一次生产过程中管理所有部门的总的行政结构,内部或包括很多子部门,比如斯帕克项目工作办公室(
SparkEnv ) - 斯帕克项目工作办公室(SparkEnv),这是斯帕克公司做每次生产研发过程中去组织所有管理部门的一个职能组织,其内部会有诸如途中的物料课经理处(
BlockManager ),对外联络信息办公室(NettyRpcEnv ) - 物料科经理处(
BlockManager ),这里主要负责所有原材料在加工过程中的存储情况的管理,会与各生产基地的生产部门对加工过程中产生的途中物料等产品进行协调管理,具体物料的管理细节后续还可以细聊 - 对外联络信息办公室(
NettyRpcEnv ),这个部门主要是去联系其余的生产基地的一个通信办公室,即如果生产调度委员会(Driver )如果需要与生产基地的生产部门(Executor )进行信息沟通的时候,都会通过这个对外联络信息办公室进行统一的通信,并由这个办公室把信息传送到不同的科室、经理处。一句话,类似于我们耳熟能详的***传达室*** - 其他,本次暂不介绍,后续会慢慢讲
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m3MCt6xp-1630154367640)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/de87990e-8fc8-44e4-8619-e6abf873f2f4/Untitled.png)]
生产调度委员会(Driver)与基地生产部(Executor)的通信机制
二者通信采用Netty 公司的RPC 协议的专用光纤来进行通讯,本次我们只讨论生产调度委员会(Driver )收到基地生产部(Executor )汇报的消息是如何处理的过程
生产调度委员会(Driver)中如何传递信息
整个信息的流转过程其实很简单
- 外部信息首先会统一到达对外联络信息办公室(
NettyRpcEnv ),它有一个专门的部门叫做信息部(NettyRpcHandler ),这个部门有一个专有的服务,叫做信息内转服务(receive ),通过这个子部门的服务可以把消息专递给调度室(Dispatcher ) - 调度室(
Dispatcher )收到消息后会进行分捡,其分捡的部门叫做专有信息投递服务(postMessage ) - 通过这个专有信息投递服务,相应的信息其实已经翻到了接收部门的邮箱中,下图中就是放入了物料科的联络办公室的邮箱中,但是只是放入,并没有通知人家,对方如果好久没有拆信,岂不是会造成信息延误
- 为了解决这个问题,斯帕克公司在调度室中又建立了一个小团队,这个团队叫做公共信息传递巡查办公室(
MessageLoop ),这个组织就是随时查看送来的邮件信息,一旦有消息,则会直接通知到相应的科室,让对方不会错过任何一通消息,从而提高实效性
联络办公室的概念(Endpoint)
上面将的流程中,应该能大概看出联络办公室的作用,就是某一个经理处或者科室专门来接收外部信息的办公室,在这里可以处理信息,并根据消息的类型可进行回复。上图中的物料科联络办公室就是这个作用。
联络办公室(Endpoint)与调度室(Dispatcher)之间的注册制关系
在调度室(Dispatcher )中有一张存放联络办公室名录的表,所有的联络办公室都要通过注册机制,注册到调度室的这张名录上,这样有消息调度室就知道转发给谁了
联络办公室的注册机制
- 注册到名录表
endpoints 上,这个注册机制是在整个工程开始之处进行的,通过一个叫做联络办公室登记处(RegisterRpcEndpoint )的地方进行 - 可以看到,在注册每一个联络办公室的时候,都会为这个办公室建立一个私有独立的邮箱(
Inbox ),这个邮箱未来可以存放给这个联络办公室的信息,方便工作人员查询
注册后
处理邮件信息的整个流程
- 信息会带着物料科联络办公室(
BlockManagerMaster )名称,传入到对外信息联络办公室(NettyRpcEnv ),这个物料科联络办公室的名称也是分发信息的唯一标识 - 消息会发送给调度室的专有信息投递服务(
Dispatcher.postMessage )
- 找到消息是给哪一个联络办公室的,根据联络处名称在联络办公室联络表中筛选
- 当选择到相应的办公室(
BlockManagerMasterEndpoint ),则把邮件发如到它的专有邮箱(Inbox ) - 因为仅仅放入对方未必看得到,所以还会给公共信息传递巡检办公室传递一张叫做
EndpointData 的工单,写清具体联络办公室,名称,邮箱等 - 邮件放入Inbox邮箱
- 工单传入公共信息传递巡检办公室的巡检信件寄存架(
receivers )。这里有一个724365不停歇的协调员时刻监控工单 - 当他发现有工单,会进行处理
- 处理的过程是,直接通知邮箱中的信息协调员(
Inbox.process ),这个信息协调员一旦被通知,则会不断去取出邮箱中的邮件 - 协调员属于物料科的联络办公室,所以其直接通知通知物料科联络办公室(
BlockManagerMasterEndpoint )来处理这封邮件
技术解读
在整个的过程当中,我并没有把源代码贴一行上来,只是从一家公司的体制上来讲解了一下spark在运行过程中如何通过Dispatcher来接收外部消息的过程,仅仅是Spark大生态中的一个小小的浪花而已。
-
YARN 这个就是雅恩公司。其调度的功能和策略,我把它抽象成为了一家集团,控制者整个集团的资源,并且按照中国的版图进行了大区的划分,每一个大区可以理解成为一个物理机节点,每一个物理机节点也是一个NodeManager -
Driver Driver的概念在很多地方就是一个协调者,更多的是从作为一个CoarseGrainedSchedulerBackend 的实体来存在,其本身内部的DriverEndpoint 作为一个联络外界的联络办公室,具体Driver和Executor的细节还想细写一下。需要注意的是Driver只是一个线程而已 -
Executor Executor 是存在于CoarseGrainedExecutorBackend 进程中的一个对象,在它内部也会创建SparkEnv 等一系列的复杂内容,从而和Driver 进行通信 -
SparkEnv 很多地方对SparkEnv的解释就是一个运行环境。这个解释实在是太抽象,太难懂了。但是,也没有什么更好的解释方法,直白来说,想在Driver或者Executor中运行Spark的环境,需要一个大统领,这个大统领就是SparkEnv,它可以初始化所有需要的基础设施,所以我把它比做了项目工作办公室 -
Endpoint 这个概念在我之前的文章中有过涉及,很多地方直接英文翻译成为了端点,但是作为端点如何理解呢?之前曾经考虑过,其实这个Endpoint 就好似在SpringMVC 当中的一个被@RequestMapping 声明的Controller 类,其中的每一个方法即Endpoint中的case class的模式匹配,这么理解貌似会简单很多。但是,很多做大数据开发同学并不懂SpringMVC,所以这么比喻还是有局限性。最终,我考虑用一个联络办公室的方式来做比喻 -
ApplicationMaster 作为ResourceManager 发送到NodeManager 上运行的进程,它是整个任务的起源,把它必做生产管理总监不为过。值得注意的是,当ApplicationMaster 在NodeManager 中启动后,其可以直接与ResourceManager 进行通信,并注册自己
总结
通过一个小故事,解读了Spark 的Dispatcher 在转发消息过程中的路径以及操作逻辑。如果我们直接阅读抽象代码不去和生活中的场景契合,一定会角色晦涩难懂
另外,当你遇到英文的名词和类名、方法名的时候,试着把它直接变成一个你能记得住的中文名字。因为很多人都不是在英美的外企工作,中文中连续夹在着英文会对一句话理解产生巨大的障碍,不信你试试:
- 当信息部接收到数据,后马上通过内转服务转到收发室,收发室启动专有信息投递服务,根据之前登记过的联络办的名字,找到应该把来信投递到哪里,做成工单后发送给调度室的巡检办公室,那里有专人进行分捡并通知相应联络办公室的专员收信,他们会通知办公室的同事进行信件处理
- 当
NettyRpcEnv 的NettyRpcHandler 进行receive 操作后,会调用Dispatcher 的postMessage 方法,经过EndpointData 的筛选后,推送到receivers中,MessageLoop 会循环检验内部的数据,并调用推送过来的Inbox 中的data 的process 方法,进行message 的处理
当然,对于我本身来说,看到英文的可能会更有画面感,因为源代码就在脑海中,但对于初学者,对于我们刚刚理解这个技术而言,最好是自己给自己讲一个简单的故事,抽象出一个具体的场景,那么你会发现,源代码很简单,逻辑很清晰,故事很赞。
|