Spark原始碼解析之Storage模組
Storage模組整體架構
Storage模組主要分為兩層:
- 通訊層:storage模組採用的是master-slave結構來實現通訊層,master(Driver)和slave(Executor)之間傳輸控制資訊、狀態資訊,這些都是透過通訊層來實現的。
- 儲存層:storage模組需要把資料儲存到disk或是memory上面,有可能還需replicate到遠端,這都是由儲存層來實現和提供相應介面。
而其他模組若要和storage模組進行互動,storage模組提供了統一的操作類BlockManager,外部類與storage模組打交道都需要透過呼叫BlockManager相應介面來實現。
理論不多說,貼程式碼以作備忘:
SparkContext類中的_env物件在初始化:
-
private[spark] def createSparkEnv(
-
conf: SparkConf,
-
isLocal: Boolean,
-
listenerBus: LiveListenerBus): SparkEnv = {
-
SparkEnv.createDriverEnv(conf, isLocal, listenerBus) //建立一個SparkEnv 包含一個BlockManagerMaster物件(啟動BlockManagerMasterEndPoint並獲取Ref)
- }
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:
-
if (!isLocal) {
-
env.metricsSystem.registerSource(executorSource)
-
env.blockManager.initialize(conf.getAppId)
- }
-
def initialize(appId: String): Unit = {
-
blockTransferService.init(this)
-
shuffleClient.init(appId)
-
-
blockManagerId = BlockManagerId(
-
executorId, blockTransferService.hostName, blockTransferService.port)
-
-
shuffleServerId = if (externalShuffleServiceEnabled) {
-
logInfo(s"external shuffle service port = $externalShuffleServicePort")
-
BlockManagerId(executorId, blockTransferService.hostName, externalShuffleServicePort)
-
} else {
-
blockManagerId
-
}
-
-
master.registerBlockManager(blockManagerId, maxMemory, slaveEndpoint) //向主節點註冊BlockManager
-
-
// Register Executors' configuration with the local shuffle service, if one should exist.
-
if (externalShuffleServiceEnabled && !blockManagerId.isDriver) {
-
registerWithExternalShuffleServer()
-
}
- }
看一下BlockManagerMasterEndpoint:
-
override def receiveAndReply(context: RpcCallContext): PartialFunction[Any, Unit] = {
-
case RegisterBlockManager(blockManagerId, maxMemSize, slaveEndpoint) =>
-
register(blockManagerId, maxMemSize, slaveEndpoint)
- context.reply(true)
- .....
-
private def register(id: BlockManagerId, maxMemSize: Long, slaveEndpoint: RpcEndpointRef) {
-
val time = System.currentTimeMillis()
-
if (!blockManagerInfo.contains(id)) {
-
blockManagerIdByExecutor.get(id.executorId) match {
-
case Some(oldId) =>
-
// A block manager of the same executor already exists, so remove it (assumed dead)
-
logError("Got two different block manager registrations on same executor - "
-
+ s" will replace old one $oldId with new one $id")
-
removeExecutor(id.executorId)
-
case None =>
-
}
-
logInfo("Registering block manager %s with %s RAM, %s".format(
-
id.hostPort, Utils.bytesToString(maxMemSize), id))
-
-
blockManagerIdByExecutor(id.executorId) = id
-
-
blockManagerInfo(id) = new BlockManagerInfo( //新增到blockManagerInfo
-
id, System.currentTimeMillis(), maxMemSize, slaveEndpoint)
-
}
-
listenerBus.post(SparkListenerBlockManagerAdded(time, id, maxMemSize))
- }
Executor中的run方法中呼叫Task的run方法。Task的run方法呼叫實現類的runTask方法,runTask方法中呼叫Rdd的iterator迭代方法。
runTask方法返回MapStatus物件。該物件包含了該檔案儲存的BlockManagerId和不同ReduceId要讀取的資料大小。Executor中會將
資料序列化並根據大小決定是直接返回還是存入BlockManager。
未完待續....
參考:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29754888/viewspace-1839920/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Spark 原始碼解析之SparkContextSpark原始碼Context
- Spark原始碼解析之Shuffle WriterSpark原始碼
- Spark原始碼-SparkContext原始碼解析Spark原始碼Context
- spark reduceByKey原始碼解析Spark原始碼
- Spark 儲存模組原始碼學習Spark原始碼
- Spark 原始碼系列(九)Spark SQL 初體驗之解析過程詳解Spark原始碼SQL
- Spark原始碼分析之MemoryManagerSpark原始碼
- Spark原始碼分析之BlockStoreSpark原始碼BloC
- webpack核心模組tapable原始碼解析Web原始碼
- Spark Shuffle機制詳細原始碼解析Spark原始碼
- Spark原始碼解析-Yarn部署流程(ApplicationMaster)Spark原始碼YarnAPPAST
- Django(49)drf解析模組原始碼分析Django原始碼
- SOFARegistry 原始碼|資料同步模組解析原始碼
- Spark 原始碼系列(六)Shuffle 的過程解析Spark原始碼
- spark核心(下)——job任務提交原始碼解析Spark原始碼
- spark 原始碼分析之十三 -- SerializerManager剖析Spark原始碼
- Spark原始碼分析之DiskBlockMangaer分析Spark原始碼BloC
- Spark原始碼分析之cahce原理分析Spark原始碼
- Spark原始碼分析之Checkpoint機制Spark原始碼
- spark 原始碼分析之十八 -- Spark儲存體系剖析Spark原始碼
- spark 原始碼分析之十五 -- Spark記憶體管理剖析Spark原始碼記憶體
- spark的基本運算元使用和原始碼解析Spark原始碼
- (一) Mybatis原始碼分析-解析器模組MyBatis原始碼
- python2 traceback模組原始碼解析Python原始碼
- 比特幣原始碼分析:VersionBits模組解析比特幣原始碼
- QT Widgets模組原始碼解析與技巧QT原始碼
- Spark SQL原始碼解析(四)Optimization和Physical Planning階段解析SparkSQL原始碼
- spark 原始碼分析之十六 -- Spark記憶體儲存剖析Spark原始碼記憶體
- spark 原始碼分析之十九 -- Stage的提交Spark原始碼
- spark原始碼之任務提交過程Spark原始碼
- 讀Zepto原始碼之Form模組原始碼ORM
- 讀Zepto原始碼之Data模組原始碼
- Zepto原始碼分析之form模組原始碼ORM
- 讀Zepto原始碼之Fx模組原始碼
- 讀Zepto原始碼之Gesture模組原始碼
- 讀Zepto原始碼之Touch模組原始碼
- jQuery原始碼解析之clone()jQuery原始碼
- jQuery原始碼解析之position()jQuery原始碼