文章目录
简介
Spark中的RDD-Cache、Shuffle-output以及broadcast的存储实现都是基于BlockManager的,BlockManager提供了数据存储(内存/文件存储)接口。BlockManager是主从结构,在driver和所有executor节点上都会有BlockManager,每个节点上存储的block信息都会汇报给driver端的blockManagerMaster作统一管理。BlockManager主要提供了读取和写数据的接口,可以从本地或者远程读取和写数据,读写数据可以基于内存、磁盘或者是堆外空间 (off-Heap)。
-
如果我们对一个rdd进行了cache,cacheManager也是把数据放在了blockmanager中,后续task运行的时候可以直接从cacheManager中获取到cacherdd,不用再从头计算。
-
shuffle的过程利用blockmanager作为数据的中转站。
-
broadcast调度task到多个executor的时候,broadcast底层使用的数据存储层。
-
Spark Streaming中一个ReceiverInputDStream接受到的数据也是先放在BlockManager中,然后封装为一个BlockRdd进行下一步运算的。
/** * 在每个节点(driver和executors)上运行的管理器, * 它提供将块放入和检索到本地和远程存储(memory、disk和off-heap)的接口。 * * 请注意,必须先调用[[initialize()]],然后才能使用BlockManager。 */ private[spark] class BlockManager( executorId: String, rpcEnv: RpcEnv, val master: BlockManagerMaster, val serializerManager: SerializerManager, val conf: SparkConf, memoryManager: MemoryManager, mapOutputTracker: MapOutputTracker, shuffleManager: ShuffleManager, val blockTransferService: BlockTransferService, securityManager: SecurityManager, numUsableCores: Int) extends BlockDataManager with BlockEvictionHandler with Logging {...}
这里的Block和HDFS中谈到的Block块是有本质区别:HDFS中是对大文件进行分Block进行存储,Block大小固定,如为512M等;而Spark中的Block是用户的操作单位,一个Block对应一块有组织的内存,一个完整的文件或文件的区间端。
在RDD层面上我们了解到RDD是由不同的partition组成的,我们所进行的transformation和action是在partition上面进行的;而在storage模块内部,RDD又被视为由不同的block组成,对于RDD的存取是以block为单位进行的,本质上partition和block是等价的,只是看待的角度不同。
BlockManager的创建
BlockManagerMaster和BlockManager都是在构造SparkEnv的时候创建的,Driver端是创建SparkContext的时候创建SparkEnv,Executor端的S