本文為 Spark 2.0 源碼分析筆記,某些實現可能與其他版本有所出入
再次重申標題中的 Master 是指 Spark Storage 模塊的 Master,是運行在 driver 上的 BlockManager 及其包含的 BlockManagerMaster、RpcEnv 及 RpcEndpoint 等;而 Slave 則是指 Spark Storage 模塊的 Slave,是運行在 executor 上的 BlockManager 及其包含的 BlockManagerMaster、RpcEnv 及 RpcEndpoint 等。下文也將沿用 Master 和 Slave 簡稱。
Master 與 Slaves 之間是通過消息進行通信的,本文將分析 Master 與 Slaves 之間重要的消息以及這些消息是在什么時機被觸發發送的。
Master -> Slave
先來看看 Master 都會發哪些消息給 Slave
case class RemoveBlock(blockId: BlockId)
用于移除 slave 上的 block。在以下兩個時機會觸發:
- task 結束時
- Spark Streaming 中,清理過期的 batch 對應的 blocks
case class RemoveRdd(rddId: Int)
用于移除歸屬于某個 RDD 的所有 blocks,觸發時機:
- 釋放緩存的 RDD
case class RemoveShuffle(shuffleId: Int)
用于移除歸屬于某次 shuffle 所有的 blocks,觸發時機:
- 做 shuffle 清理的時候
case class RemoveBroadcast(broadcastId: Long, removeFromDriver: Boolean = true)
用于移除歸屬于特定 Broadcast 的所有 blocks。觸發時機:
- 調用
Broadcast#destroy
銷毀廣播變量 - 調用
Broadcast#unpersist
刪除 executors 上的廣播變量拷貝
接下來看看 Slaves 發送給 Master 的消息
Slave -> Master
case class RegisterBlockManager(blockManagerId: BlockManagerId ...)
用于 Slave(executor 端 BlockManager) 向 Master(driver 端 BlockManager) 注冊,觸發時機:
- executor 端 BlockManager 在初始化時
case class UpdateBlockInfo(var blockManagerId: BlockManagerId, var blockId: BlockId ...)
用于向 Master 匯報指定 block 的信息,包括:storageLevel、存儲在內存中的 size、存儲在磁盤上的 size、是否 cached 等。觸發時機:
- BlockManager 注冊時
- block 被移除時
- 原本存儲在內存中的 block 因內存不足而轉移到磁盤上時
- 生成新的 block 時
case class GetLocations(blockId: BlockId)
用于獲取指定 blockId 的 block 所在的 BlockManagerId 列表,觸發時機:
- 檢查是否包含某個 block
- 以序列化形式讀取本地或遠程 BlockManagers 上的數據時
- 讀取以 blocks 形式存儲的 task result 時
- 讀取 Broadcast blocks 數據時
- 獲取指定 block id 對應的 block 數據(比如獲取 RDD partition 對應的 block)
case class RemoveExecutor(execId: String)
用于移除已 lost 的 executor 上的 BlockManager(只在 driver 端進行操作),觸發時機:
- executor lost(一般由于 task 連續失敗導致)
case object StopBlockManagerMaster
用于停止 driver 或 executor 端的 BlockManager,觸發時機:
- SparkContext#stop 被調用時,也即 driver 停止時
case object GetMemoryStatus
用于獲取各個 BlockManager 的內存使用情況,包括最大可用內存以及當前可用內存(當前可用內存=最大可用內存-已用內存)
case object GetStorageStatus
用于獲取各個 BlockManager 的存儲狀態,包括每個 BlockManager 中都存儲了哪些 RDD 的哪些 block(對應 partition)以及各個 block 的信息
case class BlockManagerHeartbeat(blockManagerId: BlockManagerId)
用于 Slave 向 Master 發心跳信息,以通知 Master 其上的某個 BlockManager 還存活著
case class HasCachedBlocks(executorId: String)
用于檢查 executor 是否有緩存 blocks(廣播變量的 blocks 不作考慮,因為廣播變量的 block 不會匯報給 Master),觸發時機:
- 檢驗某個 executor 是否閑置了一段時間,即一段時間內沒有運行任何 tasks(這樣的 executor 會慢慢被移除)
歡迎關注我的微信公眾號:FunnyBigData