NameNode之文件系统目录树
NameNode会为维护文件系统的命名空间,命名空间是以/目录为开始的整棵目录树,整棵目录树是通过FSDirectory来管理的。
在HDFS中,无论是目录还是文件都是,在文件系统目录树中都被看做是一个INode节点,如果是目录则对应的类是INodeDirectory,如果是文件,则对应的类是INodeFile. INodeDirectory包含一个children集合,其子目录或者文件会被保存在这个集合中
HDFS会将命名空间保存到NameNode的本地文件系统上一个叫fsimage的文件中。利用这个文件,NameNode每次重启的时候都能将整个HDFS的命名空间重构,fsimage是由FSImage来负责的。另外对HDFS的操作,NameNode都会早操作日志editlog中进行记录,以便于周期性的将该日志与fsImage进行合并生成新的fsimage。该日志文件也在文件系统保存叫做editlog,有FSEditLog类来管理
一 INode分析
INode是HDFS中目录和文件的抽象。主要保存了一些文件和目录的元数据信息,比如当前文件或者目录的父INode的引用,名字, 用户组,访问权限,最后修改时间,完整的路径名等。
INode实现了INodeAttributes接口:
userName:文件/目录所属用户名
groupName:所属用户组
fsPermission:文件或者目录权限
modificationTime:上次修改时间
INode就只有一个字段parent,持有父类INode引用
三 FSEditlog分析
在NameNode中,命名空间(文件系统目录树,文件元数据信息)都是保存在内存中的,一旦NameNode重启或者宕机,内存中的所有数据将会全部丢失,所以必须有一种机制将整个命名空间持久化。
FSEidtLog用于管理editlog文件。和fsimage文件不同,editlog文件会随着NameNode的运行实时更新,所以FSEditLog的实现依赖于底层的输入流和输出流。
3.1 transactionId机制
Editlog可以存放在多种容器中,文件系统或者NFS,Bookkeeper等。
而管理这些不同容器内文件的方法也有很多,目前HDFS采用是基于
transactionId的日志管理方法
transactionId与客户端每次发起的RPC操作相关,当客户端发起一次RPC请求对NameNode的命名空间修改后,NameNode就会在editlog
中发起一个新的transaction用于记录这次操作。每一个transaction会用一个唯一的transactionid标志
edit文件的命名是以edits_开始的事务id-结束的事务id,这个文件保存了开始事务到结束事务之间的事务所有操作都在这个文件。
edits_inprogress_开始的事务id:表示正在处理的editlog
fsimage_结束事务id:fsimage文件是hadoop文件系统元数据的一个永久性的检查点,包含hadoop文件系统中结束事务id前的完整HDFS命名空间元数据镜像,比如fsimage_00000000031就是fsimage_0000
0030与edits_00000000031-00000000031合并后的镜像文件。
Seen_txid:这个文件中保存了上一个checkpoint以及editlog重置时最新的事务id.
3.2 FSEditLog状态
包括5个状态:
UNINITIALIZED:edit初始状态
BETWEEN_LOG_SEGMENTS:editlog的前一个segment已经关闭,新的还没开始
IN_SEGMENT:editlog处于可编辑状态
OPEN_FOR_READING:editlog处于可读状态
CLOSED:editlog处于关闭状态
对于非HA机制的情况,FSEditLog应该开始于UNINITIALIZED或者CLOSED状态
FSEditLog初始化之后进入BETWEEN_LOG_SEGMENTS状态,表示前一个segment已经关闭,新的还没开始,日志已经准备好了。当打开日志服务时,改变FSEditLog状态为IN_SEGMENT状态,表示可以写editlog了。
3.3 EditLogOutputStream
FSEditLog类会调用FSEditLog.editLogStream字段的write方法在editlog文件中记录一个操作,数据会被先写入到editlog文件输出流的缓存中,FSEditLog类会调用editLogStream.flush()将数据同步到磁盘上。
四 FSImage分析
如果NameNode实时的将内存中的元数据实时同步到fsimage文件中,将会非常消耗资源且造成NameNode运行缓慢,所以NameNode会先将命名空间的修改操作保存在editlog文件中,然后定期合并fsimage和editlog文件
FSImage主要功能:
保存命名空间,加载fsimage文件,加载editlog
4.1保存命名空间
privatesynchronized voidsaveFSImageInAllDirs(FSNamesystemsource,NameNodeFile nnf, long txid, Canceler canceler)
throwsIOException {
StartupProgressprog = NameNode.getStartupProgress();
prog.beginPhase(Phase.SAVING_CHECKPOINT);
if (storage.getNumStorageDirs(NameNodeDirType.IMAGE) ==0) {
throw newIOException("No image directories available!");
}
if (canceler ==null) {
canceler = new Canceler();
}
//构造保存命名空间上下文
SaveNamespaceContextctx = newSaveNamespaceContext(
source, txid,canceler);
/*
* NameNode可以定义多个fsimage存储路径,对于每一个存储路径
* saveFSImageInAllDirs方法会启动一个线程负责在这个路径上
*保存fsimage文件;同时为了防止保存过程中出现错误,命名空间
*信息首先会被保存在fsimage.ckpt文件中,当保存操作全部完成
*之后,才会将fsimage.ckpt重命名为fsimage文件
*/
try {
List<Thread> saveThreads =new ArrayList<Thread>();
//在每一个保存路径上启动一个线程,该线程使用FSImageSaver类保存fsimage文件
for (Iterator<StorageDirectory>it
=storage.dirIterator(NameNodeDirType.IMAGE);it.hasNext();) {
StorageDirectorysd = it.next();
FSImageSaversaver = newFSImageSaver(ctx,sd, nnf);
ThreadsaveThread = newThread(saver,saver.toString());
saveThreads.add(saveThread);
saveThread.start();
}
//等待所有线程执行完毕
waitForThreads(saveThreads);
saveThreads.clear();
storage.reportErrorsOnDirectories(ctx.getErrorSDs());
if (storage.getNumStorageDirs(NameNodeDirType.IMAGE) ==0) {
throw newIOException(
"Failed to save in any storagedirectories while saving namespace.");
}
if (canceler.isCancelled()) {
deleteCancelledCheckpoint(txid);
ctx.checkCancelled();// throws
assert false :"shouldhave thrown above!";
}
//将fsimage.ckpt改名为fsimage
renameCheckpoint(txid,NameNodeFile.IMAGE_NEW,nnf, false);
// 因为现在有了新的保存点,那么可以将存储上的一部分editlog和fsimage删除
purgeOldStorage(nnf);
} finally {
// Notify any threads waiting on the checkpoint to becanceled
// that it is complete.
ctx.markComplete();
ctx = null;
}
prog.endPhase(Phase.SAVING_CHECKPOINT);
}
voidsaveFSImage(SaveNamespaceContextcontext, StorageDirectorysd,
NameNodeFiledstType) throws IOException {
//获取一个事务id
long txid =context.getTxId();
//获取fsimage文件
FilenewFile = NNStorage.getStorageFile(sd, NameNodeFile.IMAGE_NEW,txid);
FiledstFile = NNStorage.getStorageFile(sd,dstType, txid);
//保存FSImage
FSImageFormatProtobuf.Saversaver = new FSImageFormatProtobuf.Saver(context);
FSImageCompressioncompression = FSImageCompression.createCompression(conf);
saver.save(newFile,compression);
MD5FileUtils.saveMD5File(dstFile,saver.getSavedDigest());
storage.setMostRecentCheckpointInfo(txid, Time.now());
}
4.2加载fsimage
当NameNode启动的时候,会加载fsimage文件中保存的命名空间到NameNode内存,然后再一条一条的将editLog文件记录的更新加载并合并到命名空间。
接下来NameNode会等待各个DataNode向自己会报数据块信息来组装blockMap
NameNode每次启动的时候都会调用FSImage.loadFSImage方法执行加载fsimage和editlog文件。
五 FSDirecotry分析
NameNode最重要的两个功能之一就是维护整个文件系统的目录树。HDFS的命名空间是通过FSDirectory来管理的,FSNameSystem也提供了目录树的管理功能,但是还是调用的FSDirecotry的方法,FSNameSystem在FSDirecotry的基础上添加了editlog日志记录功能,而FSDirectory的操作则全部是在内存中进行的,并不进行editlog的日志记录。
常见的增删改功能
addChild:向目录树添加子节点
addBlock:添加数据块
setOwner:设置文件所有者
NameNode之文件系统目录树相关推荐
- Hdfs文件系统目录树以及INode类分析
NameNode会维护文件系统的命名空间,hdfs文件系统的命名空间是以"/" 为根目录开始的整棵目录树,整棵目录树是通过FSDirectory类来管理的. 在HDFS中,无论是目 ...
- Nachos文件系统目录树实现
扩展Nachos的文件系统 实验任务 尝试多级目录(目录树)的设计与实现方法. 拓展(选做):目前Nachos文件系统仅仅实现了单级目录结构,只有一个根目录.可以尝试采用目录树对文件进行管理. 设计思 ...
- Linux下文件系统目录结构
Linux 文件系统目录结构简介 对于Linux来讲它的树型结构与Windows不同,Windows可以有多个分区,每个分区都有根,但Linux 只有一个根,其他的所有文件.目录或硬盘分区.软盘.光盘 ...
- linux系统目录树/内核源码目录树
关于系统目录树和源码目录树的结构图如下 内核版本: centos 7.0 升级内核之后 3.10.0-957-5.1.e17
- linux 源码目录结构 文件系统目录结构
学习Linux也有一段时间了,具体来整理一下Linux源码的目录结构和文件系统的目录结构,以便加深记忆. 一.Linux源码的目录结构 首先上一张截图,如下所示: 再看各个文件的介绍,借用一下其他资源 ...
- Linux文件系统目录
在Linux世界里,一切皆文件.Linux根目录下得文件系统目录如下: 目录: /bin:存放常用的指令. /boot:存放系统引导文件. /dev:存放管理设备文件夹.电脑硬件通过文件夹形式展示 / ...
- windows CMD生成文件夹树状图(tree)命令(以图形显示驱动器或路径的文件夹结构)
如: 步骤: 在当前路径运行CMD: 输入tree: 当然也可以用绝对路径, 以tree \起头: 太多了就不贴上来了. 也可以用相对路径: tree .\test_pipreqs 省略.\也可以: ...
- 文件系统(文件系统目录结构、磁盘分区、虚拟文件系统)、linux内核结构框图
什么是文件系统? 常规认知就是根目录下那些文件,但其实并不是那样.文件系统是操作系统用于明确存储设备(常见的是磁盘,也有基于NAND Flash的固态硬盘)或分区上的文件的方法和数据结构:即在存储设备 ...
- linux 往文件写4k大小,[svc]为何linux ext4文件系统目录默认大小是4k?
linux ext4普通盘为什么目录大小是4k? Why does every directory have a size 4096 bytes (4 K)? To understand this, ...
最新文章
- [C#基础]Func和Action学习
- CDays–2 完成核心功能 CMD模块 Python基础教程 cmd cli
- Silverlight中的拖拽实现的图片上传---1
- 【实验】DHCP、NAT配置案例
- DataSet转化为DataTable
- 【Linux系统编程】进程常用调度算法
- c语言版票务管理系统,火车票务管理系统(C语言版)【TXT文件,改后缀即可】
- 适合初学者的安卓开源项目_开源初学者的6个起点
- DensePose开源了,2D变3D人体姿势实时识别 | Facebook@CVPR 2018
- Springsecurity之认证过程简析
- java中使用activiti(工作流)
- Druid连接池原理
- 3、MybatisPlus
- 【算法学习笔记】09.数据结构基础 二叉树初步练习2
- json嵌套字典数据获取
- 系统学习——Bootstrap
- Linux内核:一文搞懂外设I/O内存资源的静态映射方式
- 哈工大2022春CSAPP大作业-程序人生(Hello‘s P2P)
- Havel-Hakimi算法
- element blur事件去触发一个方法
热门文章
- 做系统的U盘如何格式化
- 玻璃质感_央美设计基础 | 造型基本功练习——玻璃质感训练
- php商品低库存报警,Magento中产品库存不报警解决方案
- 同事更新几个表_无法抵挡的帅气!西铁城潮酷光动能表
- html水调歌头实验总结,水调歌头明月几时有反思小结
- 自动化调参NNI学习(三):使用python启动NNI框架调整随机森林(RandomForest)模型
- R语言快速学习第一部分(有其他语言基础)
- docker安装ping命令
- 英文文本分析:与COVID-19有关的论文文本分析
- html保存导入word文档格式,WordPress网站在导入Word文档时如何保持原有格式