上一节我们分析了DiskManagerManager,它负责Block逻辑块的目录管理,本节将介绍DiskStore,它是真正负责磁盘存储的组件,用来保存block数据到磁盘中,负责数据写入,读取,删除操作,使用NIO ByteBuffer,MappedByteBuffer,FileChannel等黑科技加速文件写入读取,读取到的数据使用抽象的BlockData来表达,然后供使用方使用。
BlockData
BlockData是一个松散的Scala特征,是DiskStore读取磁盘文件的数据组织形式,其源码如下:
private[spark] trait BlockData {
def toInputStream(): InputStream
def toNetty(): Object
def toChunkedByteBuffer(allocator: Int => ByteBuffer): ChunkedByteBuffer
def toByteBuffer(): ByteBuffer
def size: Long
def dispose(): Unit
}
可以看出来,BlockData定义了一些虚函数:
- toInputStream():将块数据转化为java.io.InputStream
- toNetty():将块数据转化为适合Netty上传输的对象格式
- toChunkedByteBuffer():将块数据转化为ChunkedByteBuffer。ChunkedByteBuffer,是对多个java.nio.ByteBuffer的封装,表示多个不连续的内存缓冲区中的数据。虽然Chunk这个词在中文中一般也翻译作“块”,但它与上面的Block相比,更是一个逻辑概念而非物理概念
- toByteBuffer():将块数据转化为单个java.nio.ByteBuffer
- size():返回这个BlockData的长度。
- dispose():销毁BlockData。
所以,BlockData只是定义了数据转化的规范,并没有涉及具体的存储格式和读写流程,是个松散的特征。BlockData目前有3个实现类:基于内存和ChunkedByteBuffer的ByteBufferBlockData、基于磁盘和File的DiskBlockData,以及加密的EncryptedBlockData。都比较简单就不一一说了。
DiskStore
DiskStore负责磁盘存储的组件,用来保存block数据到磁盘中,负责数据写入,读取,删除操作,我们来看下它的属性:
private[spark] class DiskStore(
conf: SparkConf,
diskManager: DiskBlockManager,
securityManager: SecurityManager) extends Logging {
// SecurityManager用于提供对数据加密的支持
// 读取磁盘中的Block时,是直接读取还是使用FileChannel的内存镜像映射方法读取的阈值。由spark.storage.memoryMapThreshold配置,默认为2M
private val minMemoryMapBytes = conf.get