大数据必只理论知识(一)

hdfs的写流程:
1、客户端向namenode发送数据上传的请求
2、namenode进行相关的检查工作:文件是否存在、父目录是否存在、权限检查
3、检查完毕,namenode向客户端返回存储的相应的节点信息(就近原则)
4、客户端准备上传文件,先将文件进行逻辑切块,根据返回的节点id构建数据块上传通道
5、开始进行真正的上传文件,一边上传一边进行物理切块
6、在节点上传先存储在内存中,以package为单位,每当有一个package上传成功,一边写入磁盘,一边向另一个节点进行
传输
7、当一个数据块上传成功,然后进行下一个数据块的上传,当有一个节点的数据块上传成功,就认为这个数据块上传成功
8、然后重复上面的操作,构建通道,上传操作
9、当所有数据块都上传成功,会向客户端返回响应
10、客户端向namenode发送消息,文件上传成功,namenode开始更新元数据

hdfs的读流程:
1、客户端向namenode发送数据下载的请求
2、namenode进行相关的检查工作:文件是否存在,如果不存在会报错
3、namenode会向客户端返回数据块对应的节点信息及副本节点信息
4、客户端根据就近原则到对应的节点上下载数据
5、下载的数据会生成一个crc文件与文件上传时的meta文件进行校验,校验的是起始偏移量与末尾偏移量之间的内容
6、然后重复下载后面的数据块
7、当所有的数据块下载完成,客户端会向namenode报告,下载成功

shuffle过程:
1、文件在map端进行一个切分,切分后的数据块就是一个切片,每一个切片对应一个maptask
2、maptask的数据会被收集到一个收集器中
3、收集器会将数据写入到一个环形缓冲区中,默认大小是100M,中间有个赤道,一边是元数据,一边是原始数据,当数
据达到一个阈值时(80%),就会把数据溢写到磁盘中,剩下的20%继续接收数据,如果20%也满了,80%的数据区域
内数据还没有全部溢写完成,这时候处于阻塞状态,等到全部溢写完成才能开始接收数据
4、在溢写入磁盘之前会进行二次排序,先按照分区排序,然后在分区内部按照key进行排序
5、溢写到磁盘可能会有大量的溢写文件,对这些溢写文件进行归并排序,合并成一个溢写文件
6、当有一个maptask任务完成,MRAppMaster会通知reduce
7、reduce会开启5个线程池,去每个分区拉取数据,对拉取来的数据按照分区进行归并排序,保证分区和key值是有序的
8、然后reduce按照自定义分组或者默认分组
9、有几个分区就会产生几个reducetask,然后将数据输出到hdfs上或者其他路径上

MR
1、自定义类
<1>实现接口Writable
<2>重写write(序列化)和readField(反序列化)

2、自定义排序
<1>实现接口WritableComparable
<2>重写write、readField、compareTo

3、自定义分组:默认情况下分组和排序的规则一样,都是调用的compareTo()方法
<1>继承WritableComparator类
<2>重写compare方法
<3>指定分组类

4、自定义分区
<1>继承Partitoner
<2>重写getPartition方法
<3>在job中指定分区类
<4>指定reducetask的个数

yarn资源的调度过程:
1、客户端向rm发送提交job的请求
2、rm向客户端返回相应的资源节点
3、客户端到对应的资源节点上启动MRAppMaster
4、在节点山先启动container,然后在container中启动MRAppMaster
5、MRAppMaster向rm申请相应的资源启动maptask和reducetask
6、rm返回相应的资源,优先返回maptask的资源
7、MRAppMaster到相应的节点上启动对应的maptask
8、当有一个maptask完成就会启动reducetask
9、当maptask或者reducetask完成就会向MRAppMaster汇报,MRAppMaster就会销毁对应的资源
10、当任务都完成,MRAppMaster就会向rm汇报,销毁资源

job的提交过程:
1、客户端向rm申请提交job的请求
2、rm向客户端返回一个application的id和共享资源路径:包括jar包、切片信息、配置信息
3、客户端将共享资源放在共享资源路径下
4、客户端向rm报告,资源放置完成,开始真正的提交job
5、rm向客户端返回对应的资源节点
6、客户端到对应的资源节点启动MRAppMaster
7、也是现在节点上启动container,然后在container中启动MRAppMaster
8、MRAppMaster会先初始化job的工作簿(主要是记录maptask和reducetask的进度和状态)
9、MRAppMaster到共享资源路径下拉取相应的信息(maptask和reducetask的数量)
10、MRAppMaster向rm申请资源运行maptask和reducetask
11、rm返回相应的资源,优先返回maptask的资源
12、MRAppMaster到对应节点上线启动container,然后启动maptask
13、maptask到共享资源路径下拉取相应的资源
14、maptask开始运行
15、maptask在运行过程中想MRAppMaster汇报当前的进度和状态
16、当有一个maptask任务完成,MRAppMaster会启动reducetask任务
17、reducetask任务运行过程中也要向MRAppMaster汇报当前的进度和状态
18、当有maptask或者reducetask任务完成,MRAppMaster会销毁对应的资源
19、当任务都完成,MRAppMaster会向rm汇报,任务完成,然后销毁对应的资源

非全新集群zk的选举依据:
逻辑时钟(投票次数)、数据版本(zxid)、serverid
过程:
当逻辑时钟不统一时,先统一逻辑时钟
在逻辑时钟统一后,比较数据版本,zxid越大,代表数据版本越新,zxid最大的当选leader,
当zxid一样时,根据serverid的大小,serverid大的,当选leader

选举leader后怎么保证follower和observer的数据统一?
follower向leader发送自己最新的数据版本信息
leader将发送过来的数据版本与自己的版本进行比较,确定同步点
follower开始进行数据版本的更新,在更新过程中,无法向外界提供相应的服务
当follower完成数据版本更新,leader就会将其状态切换为updated,这时候就可以对外提供服务了

spark的运行原理:
1、启动spark集群,使用spark脚本命令启动,启动对应的master和worker进程
2、worker进程向master进行注册
3、worker注册成功之后,worker不断向master发送心跳包,监听master节点是否存活
4、Driver向master提交任务,申请资源
5、master接收到相关申请后,向worker节点指派相应的任务,让其启动对应的executor进程
6、worker接收到master发来的任务,启动executor,向master报告,启动成功,可以接收任务
7、executor启动成功后,向Driver进行反向注册,告诉Driver,谁可以接收任务,执行任务
8、Driver接收到反向注册信息
9、DAGScheduler对任务按照stage进行划分,并将划分后的stage的task任务封装在taskset中,交给taskScheduler,由taskScheduler交给executor
10、executor接收到Driver发送过来的taskset后,对其进行反序列化,将这些task封装在taskRunner线程中,放在本地线程池中,等待调用执行

sparkContext的构建过程:
1、通过sparkContext的方法createTaskScheduler()创建SchedulerBackend和TaskScheduler
2、调用Scheduler的initialize方法进行初始化
3、在调用Scheduler的start方法,通过Driver向Master发送注册消息
4、在SchedulerBackend中通过withRegistor()和tryRegistor()方法向master发送注册请求
5、Master中的recevie方法收到Driver发送过来的请求,然后到worker上启动相应的executor
6、worker通过相关的API启动相应的executor
7、启动起来之后向SchedulerBackend进行反向注册

spark-on-yarn模式:
spark-cluster:
1、先向yarn集群的提供资源申请
2、rm接收到请求后,在集群中选择一个nm,为这个程序分配一个container,在container中启动applicationMaster,这个applicationMaster对SparkContext进行初始化
3、applicationMaster向rm注册申请资源
4、当applicationMaster申请到资源后(也就是container),然后向nm进行反向注册,在container中启动相关的程序
5、应用程序运行完成后,applicationMaster向rm申请注销并关闭自己

spark-client:
1、先向rm申请资源
2、rm收到请求后,在集群中选择一个nm,为该程序分配第一个container,并在这个coontainer中启动applicationMaster
3、client中的SparkContext初始化完毕后,与applicationMaster建立通信,applicationMaster向rm注册,申请资源
4、一旦applicationMaster申请到资源后(container),向client中SparkContext进行反向注册
5、SparkContext分配任务给container执行
6、程序运行结束以后,client的SparkContext向rm申请注销并关闭自己

spark-cluster和client的区别:
cluster模式的Driver是运行在集群中的container中的ApplicationMaster
client模式的Driver是本地创建的

worker节点的内部原理
1、Master向worker发送一个launchDriver的请求,worker接收到请求后会创建一个DriverRunner对象
2、然后DriverRunner对象调用其start()方法,启动一个线程
3、在这个线程内部,首先创建一个本地目录,然后拷贝要运行的jar文件到本地,接着创建出来一个ProcessBuilder对象
4、利用这个ProcessBuilder对象启动Driver进程
5、当Driver进程启动那个完成之后,向启动DriverRunner线程的worker节点发送一个Driver启动的状态
6、当前worker向Master发送Driver启动的情况,这时候Driver启动就完成了
7、然后就是Application的启动过程和Driver的启动基本一致,只是在worker节点上启动的是ExecutorRunner线程
8、在最后Executor启动完成之后,要想Driver进行注册

Spark Master的HA机制
说白了就是元数据的切换
1、当active master挂掉以后,通知standby master启动,并使用持久化引擎对持久化数据进行读取
2、持久化引擎将不为空的数据全部注册带master的内存缓存中
3、master向所有的application、worker、Driver发送自己的地址信息
4、application、Worker、Driver收到消息后返回一个消息给master
5、master接收到各自application、worker、Driver的消息后,开始过滤掉没有响应的节点信息
然后调用Scheduler()方法,开始为相关进程分配资源

spark的准备切换提供了两种模式:
一种是基于文件系统的:需要手动切换到standby master节点
另一种是基于zookeeper的:可以自动切换到Master
在进行master切换的过程中,已经在运行的程序会正常运行,影响的就是新的job不能提交给集群

Spark的Driver的HA?
<1>设置checkpoint,保证Driver挂掉之后能够进行数据恢复
<2>设置Driver挂掉之后能够进行自动重启,在脚本命令中加入–supervise关键字

Spark任务的详细执行流程
(1)、将我们编写的程序打成 jar 包
(2)、调用 spark-submit 脚本提交任务到集群上运行
(3)、运行 sparkSubmit 的 main 方法,在这个方法中通过反射的方式创建我们编写的主类的
实例对象,然后调用 main 方法,开始执行我们的代码(注意,我们的 spark 程序中的 driver
就运行在 sparkSubmit 进程中)
(4)、当代码运行到创建 SparkContext 对象时,那就开始初始化 SparkContext 对象了
(5)、在初始化 SparkContext 对象的时候,会创建两个特别重要的对象,分别是:DAGScheduler
和 TaskScheduler
【DAGScheduler 的作用】将 RDD 的依赖切分成一个一个的 stage,然后将 stage 作为 taskSet
提交给 DriverActor
(6)、在构建 TaskScheduler 的同时,会创建两个非常重要的对象,分别是 DriverActor 和
ClientActor
【clientActor 的作用】向 master 注册用户提交的任务
【DriverActor 的作用】接受 executor 的反向注册,将任务提交给 executor
(7)、当 ClientActor 启动后,会将用户提交的任务和相关的参数封装到 ApplicationDescription
对象中,然后提交给 master 进行任务的注册
(8)、当 master 接受到 clientActor 提交的任务请求时,会将请求参数进行解析,并封装成
Application,然后将其持久化,然后将其加入到任务队列 waitingApps 中
(9)、当轮到我们提交的任务运行时,就开始调用 schedule(),进行任务资源的调度
(10)、master 将调度好的资源封装到 launchExecutor 中发送给指定的 worker
(11)、worker 接受到 Master 发送来的 launchExecutor 时,会将其解压并封装到 ExecutorRunner
中,然后调用这个对象的 start(), 启动 Executor
(12)、Executor 启动后会向 DriverActor 进行反向注册
(13)、driverActor 会发送注册成功的消息给 Executor
(14)、Executor 接受到 DriverActor 注册成功的消息后会创建一个线程池,用于执行 DriverActor
发送过来的 task 任务
(15)、当属于这个任务的所有的 Executor 启动并反向注册成功后,就意味着运行这个任务的
环境已经准备好了,driver 会结束 SparkContext 对象的初始化,也就意味着 new SparkContext
这句代码运行完成
(16)、当初始化 sc 成功后,driver 端就会继续运行我们编写的代码,然后开始创建初始的 RDD,
然后进行一系列转换操作,当遇到一个 action 算子时,也就意味着触发了一个 job
(17)、driver 会将这个 job 提交给 DAGScheduler
(18)、DAGScheduler 将接受到的 job,从最后一个算子向前推导,将 DAG 依据宽依赖划分成
一个一个的 stage,然后将 stage 封装成 taskSet,并将 taskSet 中的 task 提交给 DriverActor
(19)、DriverActor 接受到 DAGScheduler 发送过来的 task,会拿到一个序列化器,对 task 进行
序列化,然后将序列化好的 task 封装到 launchTask 中,然后将 launchTask 发送给指定的
Executor
(20)、Executor 接受到了 DriverActor 发送过来的 launchTask 时,会拿到一个反序列化器,对
launchTask 进行反序列化,封装到 TaskRunner 中,然后从 Executor 这个线程池中获取一个线
程,将反序列化好的任务中的算子作用在 RDD 对应的分区上

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值