首先我们知道NameNode保存着数据的元数据信息,真正的数据存在于各个DataNode,那NameNode的元数据保存在哪里呢?
这么重要的数据肯定不可能存在于内存,内存容易丢失,那肯定是磁盘了。
那问题来了,当客户发送请求时(比如读取数据),这个请求发送到NameNode,NameNode再从磁盘寻找所需要的目标文件元数据信息,然后再发送给客户端,每次都要经过磁盘的读写,这样的效率是极其低的。
而NameNode和SecondaryNameNode本身的工作机制就很好的解决了上面的问题
- Fsimage : 镜像文件,HDFS文件系统元数据的一个永久检查点
- Edits: 编辑日志,存放HDFS文件系统所有更新 *** 作的 *** 作路径
- Seen_txid:保存着edits最新末尾数字
- 如果第一次NameNode,会创建Fsimage和Edits文件,如果不是第一次则会加载Fsimage和未合并的Edits文件到内存中(我们集群启动完成后打开NameNode页面发现他并没有很快的变成active状态,就是因为要加载文件和接受DataNode的心跳)。
- 当准备就绪后,客户端就可以发送请求给NameNode,NameNode将会把客户端所请求的增删改 *** 作(查询并不会记录,因为查询对元数据并没有更改),记录到Edits文件中
- 当Edits文件中的 *** 作记录次数达到100万次时(默认dfs.namenode.checkpoint.txns 参数),将会触发Fsimage和Edits文件的合并(将Fsimage和Edits文件加载进内存,通过Edits文件对Fsimage一步步执行,形成新的Fsimage),而这个检查 *** 作次数(SecondaryNameNode每分钟会对NameNode进行检查–dfs.namenode.checkpoint.check.period默认参数)和去合并都是由SecondaryNameNode进行完成
- 另外SecondaryNameNode会每隔一小时(默认dfs.namenode.checkpoint.period 参数)去对NameNode的Fsimage和Edits文件进行一次合并,或者达到"第三条"的 *** 作次数达到100次
- 而在SecondaryNameNode要执行合并时,首先会让NameNode的Edits文件滚动成一个空的Edits.inprogress文件,之后所有的客户端 *** 作将会写入这个新的Edits.inprogress文件中,而未合并的Edits将会拷贝到SecondaryNameNode本地,然后加载到内存进行合并,合并完成后生成Fsimage.chkpoint文件,然后Fsimage.chkpoint文件拷贝到NameNode,重命名后替换原来的Fsimage,完成了整个元数据的更新存储
好像是还不如直接存储到磁盘,读磁盘来的爽快。但是仔细发现,这种工作机制,既能让元数据信息能够安全的保存,也让NameNode的工作效率没有降低。
NameNode在元数据存储这块真正的只需要接受客户端请求和记录客户端的 *** 作,他不用管数据的安全问题,具体存储问题,如何存储问题,他依然是最直接的从内存中寻找到元数据信息返回给客户端,而其他复杂的都交给了秘书SecondaryNameNode。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)