说明
DataNode文件系统相关的行为体现在管理与操作数据块
- 数据块创建
- 维护数据块与校验文件对应关系
组织结构
- DataNode指定了多个异构的目录
FsVolumeList:保存所有的FsVolumeImpl对象 - DataNode每个目录包含多个数据块
FsVolumeImpl:包含多个BlockPoolSlice对象 - DataNode每个目录包含多个块池,每个块池包含多个块
BlockPoolSlice:管理一个池块在一个目录下的所有数据块 - 每个数据块包含副本
ReplicaMap: 维护DataNode上所有块的副本状态。块有5种状态。不同状态持久化到不同的磁盘上。
rbw目录,rbw,rbr.
tmp目录,在副本均衡等
finalized目录,完成
rbw目录上应该是客户端已经有一个副本了的块,所以重启时可以进入rbr等待恢复。
tmp目录,应该是没有一个副本。所以直接删了就好
finalized目录,完成的目录。包含数据块和校验文件
BlockPoolSlice实现
BlockPoolSlice字段
- bpid
blockpool的id - current/finalized/rbw/tmp引用
blockpoolslice需要有整个目录的所有文件引用 - dfsUsage
当前块目录的磁盘使用情况
BlockPoolSlice方法
- 构造函数
创建目录,并将目录的引用到指定字段上。进程结束时,钩子保存du信息。 - 磁盘空间方法
- dfsUsage
- 块池目录子文件方法
getDirectory/getRbwDir等 - 数据块副本操作方法
池块创建数据块副本
tmp状态的副本
rbw状态的副本均可以直接在目录下创建,createTmpFile()
finalized状态的副本需要使用addBlock方法获取目录,创建block和metafile。
finalized状态的副本应该只能创建目录,然后从之前的位置move过来吧。
获取池块目录存储副本状态
BlockPoolSlice.getVolumeMap,启动时调用
通过目录加载块状态到volumeMap中
恢复临时文件
临时文件是为了保存previous和current目录下的变动的数据块
FsVolumeImpl实现
FsVolumeImpl对应的是dn配置的一个存储目录
FsVolumeImpl方法
定义了如下方法:
- getBlockPoolList
- getAvailable
- getBasePath
- getPath
- getFinalizedDir
- getStorageType
- reserveSpaceForRbw
- isTransientStorage
FsVolumeImpl的字段方法
- dataset 用来加锁
- storageId
- currentDir
- usage
- reserved
- bpSlics: 当前FSVolumeImpl下的所有BlockPoolSlice引用
- cacheExecutor 线程池
- reservedForRbw 预留的磁盘
FsVolumeImpl获取的磁盘,子目录,数据块操作都是通过BlockpoolSplit进行的,累加合并。
FsVolumeList实现
FsVolumeList字段
使用线性表管理所有的FsVolumeList管理所有的FsVolumeImpl对象。一个DN可以配置多个目录。
- List<FsVolumeImpl> volumes
- VolumeChoosingPolicy<FsVolumeImpl>blockChooser 磁盘存储副本策略 空闲或者轮询(选择哪一个目录)
FsVolumeList操作
- 容量相关
- 数据块相关
getVolumeMap - BlockPool方法
所有的块池增加或者删除块池存储目录,每一个FsVolumeImpl启用一个独立的线程创建 - 获取存储副本的目录
最终调用的是FsVolumeImpl上通过调用BlockPoolSlice实现创建目录。
FsDataSetImpl
- 通过持有FsVolumeList的对象来对DataNode上定义的数据块进行管理和操作。
- 持有DataStorage对象来进行Datanode存储空间的操作。
可以操作存储和文件目录,FsDataSetImpl完全掌握了DN的数据