BlockManager

BlockManager的作用

Spark作为分布式的处理引擎,其数据也是分布式存储。在这种情况下,分布在不同节点的数据如何管理、如何知道数据的总体分布情况、如何进行数据操作等,这都就需要一个统一抽象来管理及完成这些工作。BlockManager顾名思义,用于块管理,分布式数据均已block为单位,BlockManager直接管控着这些块的信息获取、读、写等操作。

BlockManagerMaster

BlockManager离不开BlockManagerMaster,BlockManagerMaster就像是一个中央情报局,手握全局资料,拥有各种指挥权。各地的BlockManager都要向BlockManagerMaster上报自身的块信息,并接收和执行来自BlockManagerMaster的命令。

BlockManager和BlockManagerMaster的创建

均在SparkEnv创建的时候,源码对应于SparkEnv.scala的create代码

val blockManagerMaster = new BlockManagerMaster(registerOrLookupEndpoint(
  BlockManagerMaster.DRIVER_ENDPOINT_NAME,
  new BlockManagerMasterEndpoint(rpcEnv, isLocal, conf, listenerBus)),
  conf, isDriver)

// 只有BlockManager的initialize方法调用之后BlockManager才可用,也就是说用之前必须初始化
// 因为初始化传入的应用ID,在BlockManager实例化的时候还不可知
val blockManager = new BlockManager(executorId, rpcEnv, blockManagerMaster,
  serializerManager, conf, memoryManager, mapOutputTracker, shuffleManager,
  blockTransferService, securityManager, numUsableCores)

具体driver端SparkEnv的创建,对应于SparkContext构建时的如下初始化代码

_env = createSparkEnv(_conf, isLocal, listenerBus)

具体executor端SparkEnv的创建,对应于CoarseGrainedExecutorBackend进程启动后的如下代码

val env = SparkEnv.createExecutorEnv(
  driverConf, executorId, hostname, cores, cfg.ioEncryptionKey, isLocal = false)

从create可以看到,不管是在driver端还是executor端,BlockManagerMaster和BlockManager都会先后执行new BlockManagerMaster和new BlockManager代码,很明显BlockManager在driver和executor的创建方式没有明显不同。这里边的区别在于,在executor端执行new BlockManagerMaster实例化后其对应拿到的是driver端的BlockManagerMasterEndpoint。

BlockManager的初始化

BlockManager存在于driver端和executor端,初始化BlockManager的地方有两个,如下

  • 在SparkContext初始化过程中,创建好Spark执行环境SparkEnv以后在该执行环境中初始化BlockManager
_env.blockManager.initialize(_applicationId)
  • 另一个是在Executor实例的创建中初始化
if (!isLocal) {
  env.blockManager.initialize(conf.getAppId)
  ...
}

CoarseGrainedExecutorBackend进程启动后会对应创建Executor。

交互

Executor上的BlockManager要和BlockManagerMaster通信,上报块状态信息。具体实现方式是通过Rpc来进行通信。

BlockManagerMasterEndpoint

在创建BlockManagerMaster的时候,同时实例化Driver端的BlockManagerMasterEndpoint,并注册到RpcEnv,用于Driver和Executor的BlockManager进行通信。

BlockManagerSlaveEndpoint

在BlockManager创建的时候,BlockManagerSlaveEndpoint也一起创建,BlockManagerSlaveEndpoint注册到RpcEnv。

关联:

在调用BlockManager的initialize的方法中,会将该BlockManager注册给BlockManagerMaster。

val id =
  BlockManagerId(executorId, blockTransferService.hostName, blockTransferService.port, None)

val idFromMaster = master.registerBlockManager(
  id,
  maxOnHeapMemory,
  maxOffHeapMemory,
  slaveEndpoint)

那Executor上的BlockManager是怎么把自己注册给Master的?

RpcEndpointRef

即BlockManagerMasterEndpoint的引用,可以知道这一过程是通过Rpc操作来完成的。

def registerBlockManager(
    blockManagerId: BlockManagerId,
    maxOnHeapMemSize: Long,
    maxOffHeapMemSize: Long,
    slaveEndpoint: RpcEndpointRef): BlockManagerId = {
  logInfo(s"Registering BlockManager $blockManagerId")
  // BlockManager通过driverEndpoint即BlockManagerMasterEndpoint将自己注册给BlockManagerMaster
  val updatedId = driverEndpoint.askSync[BlockManagerId](
    RegisterBlockManager(blockManagerId, maxOnHeapMemSize, maxOffHeapMemSize, slaveEndpoint))
  logInfo(s"Registered BlockManager $updatedId")
  updatedId
}

BlockManager注册内容

每个Executor中的BlockManager向BlockManagerMaster注册成为ID及BlockManagerInfo的一种键值对形式的组合关系。

// BlockManagerId到BlockManagerInfo的映射.
private val blockManagerInfo = new mutable.HashMap[BlockManagerId, BlockManagerInfo]

BlockManager与BlockManagerMaster实际交互

通过以下方法的实现来完成

def receiveAndReply(context: RpcCallContext): PartialFunction[Any, Unit] = {
  case _ => context.sendFailure(new SparkException(self + " won't reply anything"))
}

BlockManager与BlockManagerMaster发送对应的message到前边注册到RpcEnv的RpcEndpoint接口实现,master与slave中各自的receiveAndReply负责处理具体的命令和请求。包括更新块信息、删除RDD等。在Rpc的实现中可以看到,消息被发往一个中转站,然后逐一匹配处理。

Block存储

实际的块存储相关由以下两个实例来完成。分别对应着块在内存的存储和块在磁盘的存储。

MemoryStore:内存存储
DiskStore:磁盘存储

他们随着BlockManager的创建一起创建

private[spark] val memoryStore =
  new MemoryStore(conf, blockInfoManager, serializerManager, memoryManager, this)
private[spark] val diskStore = new DiskStore(conf, diskBlockManager, securityManager)
memoryManager.setMemoryStore(memoryStore)

对应完成内存、磁盘数据的存、取等动作。

发布了95 篇原创文章 · 获赞 5 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43878293/article/details/103610676