Spark源码解析之Storage模块


Storage模块整体架构

Storage模块主要分为两层:

  1. 通信层:storage模块采用的是master-slave结构来实现通信层,master(Driver)和slave(Executor)之间传输控制信息、状态信息,这些都是通过通信层来实现的。
  2. 存储层:storage模块需要把数据存储到disk或是memory上面,有可能还需replicate到远端,这都是由存储层来实现和提供相应接口。

而其他模块若要和storage模块进行交互,storage模块提供了统一的操作类BlockManager,外部类与storage模块打交道都需要通过调用BlockManager相应接口来实现。



理论不多说 ,贴代码以作备忘:

SparkContext类中的 _env对象在初始化:
  1. private[spark] def createSparkEnv(
  2.       conf: SparkConf,
  3.       isLocal: Boolean,
  4.       listenerBus: LiveListenerBus): SparkEnv = {
  5.     SparkEnv.createDriverEnv(conf, isLocal, listenerBus) //创建一个SparkEnv 包含一个BlockManagerMaster对象(启动BlockManagerMasterEndPoint并获取Ref)
  6.   }

BlockManagerMaster有个Actor消息传递模型BlockManagerMasterEndpoint,该对象用来跟踪所有块管理器的信息,它有比较重要的三个变量:

1.blockManagerInfo:HashMap容器,key值为BlockManagerID对象,value值为Bolck信息(即BlockManagerInfo对象),Block信息包括BlockManagerID,最大内存,以及从节点上的actor模型;

2.blockManagerIdByExecutor:HashMap容器,key值存放ExecutorID,value值为对应的BlockManagerID对象;

3.blockLocations:JHashMap容器,key值存放相应的块(BlockId对象),可能有多个块管理器拥有该块,所以value值就为管理该块的所有的块管理器所构成一个HashSet


Executor中会起一个BlockManagerSlaveEndpoint来和BlockManagerMasterEndpoint通讯,负责删除块等操作

看一下Executor:   

  1. if (!isLocal) {
  2.     env.metricsSystem.registerSource(executorSource)
  3.     env.blockManager.initialize(conf.getAppId)
  4.   }
blockManager中会向主节点注册:
  1. def initialize(appId: String): Unit = {
  2.     blockTransferService.init(this)
  3.     shuffleClient.init(appId)

  4.     blockManagerId = BlockManagerId(
  5.       executorId, blockTransferService.hostName, blockTransferService.port)

  6.     shuffleServerId = if (externalShuffleServiceEnabled) {
  7.       logInfo(s"external shuffle service port = $externalShuffleServicePort")
  8.       BlockManagerId(executorId, blockTransferService.hostName, externalShuffleServicePort)
  9.     } else {
  10.       blockManagerId
  11.     }

  12.     master.registerBlockManager(blockManagerId, maxMemory, slaveEndpoint)     //向主节点注册BlockManager

  13.     // Register Executors' configuration with the local shuffle service, if one should exist.
  14.     if (externalShuffleServiceEnabled && !blockManagerId.isDriver) {
  15.       registerWithExternalShuffleServer()
  16.     }
  17.   }

看一下BlockManagerMasterEndpoint:
  1. override def receiveAndReply(context: RpcCallContext): PartialFunction[Any, Unit] = {
  2.     case RegisterBlockManager(blockManagerId, maxMemSize, slaveEndpoint) =>
  3.       register(blockManagerId, maxMemSize, slaveEndpoint)
  4.       context.reply(true)
  5.      .....

  1. private def register(id: BlockManagerId, maxMemSize: Long, slaveEndpoint: RpcEndpointRef) {
  2.     val time = System.currentTimeMillis()
  3.     if (!blockManagerInfo.contains(id)) {
  4.       blockManagerIdByExecutor.get(id.executorId) match {
  5.         case Some(oldId) =>
  6.           // A block manager of the same executor already exists, so remove it (assumed dead)
  7.           logError("Got two different block manager registrations on same executor - "
  8.               + s" will replace old one $oldId with new one $id")
  9.           removeExecutor(id.executorId)
  10.         case None =>
  11.       }
  12.       logInfo("Registering block manager %s with %s RAM, %s".format(
  13.         id.hostPort, Utils.bytesToString(maxMemSize), id))

  14.       blockManagerIdByExecutor(id.executorId) = id

  15.       blockManagerInfo(id) = new BlockManagerInfo(                          //添加到blockManagerInfo
  16.         id, System.currentTimeMillis(), maxMemSize, slaveEndpoint)
  17.     }
  18.     listenerBus.post(SparkListenerBlockManagerAdded(time, id, maxMemSize))
  19.   }

Executor中的run方法中调用Task的run方法。Task的run方法调用实现类的runTask方法,runTask方法中调用Rdd的iterator迭代方法。
runTask方法返回 MapStatus对象。该对象包含了该文件存储的BlockManagerId和不同ReduceId要读取的数据大小。Executor中会将
数据序列化并根据大小决定是直接返回还是存入BlockManager。


未完待续....



参考:http://jerryshao.me/architecture/2013/10/08/spark-storage-module-analysis/


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29754888/viewspace-1839920/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/29754888/viewspace-1839920/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值