spark|Spark - 说说存储的那些事

前面已经差不多把执行的流程都讲完了,这篇讲讲每个Task执行的结果是如何存储和读取的。
BlockManager BlockManager是SparkEnv中的组件之一,存储体系的所有组件和功能都是依赖着BlockManager,包括之前提到的ShuffleManager、DiskBlockManager、MapOutputTracker等,这篇会的流程也会再讲解一次。
BlockManagerMaster BlockManager是SparkEnv的一部分,那Driver和Executor启动的时候,都会对BlockManager进行实例化。而Driver和Executor之间的BlockManager通信,包括注册BlockManager、更新Block信息、获取Block的位置(即Block所在的BlockManager)、删除Executor等,都是通过BlockManagerMaster。
Driver启动的时候,BlockManagerMaster会创建BlockManagerMasterEndpoint并注册到Driver的RpcEnv中,而Executor启动的时候,会创建BlockManagerMasterEndpointRef,指向Driver的BlockManagerMasterEndpoint。
spark|Spark - 说说存储的那些事
文章图片

BlockManagerMasterEndpoint中维护着一个HashMap,key为BlockManagerId,value为BlockManagerInfo。BlockManagerId是唯一的,就是通过BlockManagerMasterEndpoint来管理的。
当Driver和Executor初始化BlockManager的时候,都会向BlockManagerMasterEndpoint发起RegisterBlockManager请求。Driver是发送给自己的,Executor通过BlockManagerMasterEndpointRef发送给BlockManagerMasterEndpoint。
spark|Spark - 说说存储的那些事
文章图片

BlockManagerMasterEndpoint收到请求后,就会更新map里的值,所以BlockManagerMasterEndpoint管理着所有的BlockManagerId。并且把BlockManagerId返回给请求方。那BlockManagerId是什么?
spark|Spark - 说说存储的那些事
文章图片

BlockManagerId 不同节点和实例上的BlockManager进行相互通信的时候,就需要有一个唯一的身份标识-BlockManagerId。
BlockManagerId包括host、port、executorId等信息。如果实例是Driver,那么executorId为driver,否则由Master负责给各个Executor分配,ID格式为app-日期格式字符串-数字。
上图中,第一个是的Driver的BlockManager,她的executorId为driver。第二个是Executor的BlockManager,她的executorId略过日期格式,简写为app-0。第三个Executor的BlockManager,她的executorId略过日期格式,简写为app-1。
DiskBlockManager BlockManager中有一个用来对磁盘上的文件及目录的读写操作进行管理,叫做磁盘块管理器DiskBlockManager。
当要写入磁盘的时候(这里可以看之前Task的执行过程),DiskBlockManager就会创建唯一的BlockId和文件,用来存储Shuffle中间结果。
spark|Spark - 说说存储的那些事
文章图片

DiskBlockManager维护着本地目录的数组localDirs以及本地子目录的二维数组subDirs。localDirs为blockmgr-为前缀,后面加UUID。subDirs记录本地子目录的数量,默认是64,所以创建文件的时候,就会根据判断二级目录是否存在,如果不存在则创建二级目录。
整个树形结构如下:
spark|Spark - 说说存储的那些事
文章图片

比如创建TempShuffleBlock,文件路径如下:
spark|Spark - 说说存储的那些事
文章图片

DiskBlockObjectWriter DiskBlockManager创建文件后,对文件的写入操作是由DiskBlockObjectWriter来完成的(这里可以看之前Task的执行过程),最后合并后,就有了data数据文件和index索引文件。然后告知Driver文件的信息,此步骤具体见Task执行结果的处理。
spark|Spark - 说说存储的那些事
文章图片

BlockTransferService 【spark|Spark - 说说存储的那些事】Executor执行的过程中,会创建很多个块,块的传输都是通过块传输服务BlockTransferService,主要用于不同阶段的任务之间的Block数据的传输与读写。默认为NettyBlockTransferService,每个BlockTransferService都有netty对应的server用于提供服务和clientFactory用于创建client。
假设Executor1执行的时候,通过trackerEndpoint向Driver的MapOutputTrackerMasterEndpoint获取到了她需要的block信息(此步骤具体见Task执行结果的处理)在Executor0,与是通过NettyBlockTransferService向Executor0获取block信息。
spark|Spark - 说说存储的那些事
文章图片

Executor0接收到信息后,就会通过DiskBlockManager把data文件和index文件取出来,根据起始偏移量返回数据给Executor1。
spark|Spark - 说说存储的那些事
文章图片

    推荐阅读