NameNode在内存中保存着整个文件系统的名字空间和文件数据块映射(Blockmap)的映像。
如果NameNode宕机,那么整个集群就瘫痪了
因而则出现了元数据的存储问题,接下来请看如下几个问题
如果元数据仅以文件的形式存储在namenode本地硬盘行不行呢?
因为大批量的客户端同时在进行上传、下载等各种操作时,都要对元数据进行读写及修改操作
仅仅以文件的形式来存储元数据显然不行,因为无法做到对各种操作的快速响应
把元数据放在内存中呢,确实能够提高系统响应速度,但是一旦断电就完全丢失了,这肯定也不行
那么如果把内存的数据定期flush到磁盘文件的方法行不行呢?
一旦断电,没来得及的刷到磁盘的内存数据肯定也是要丢失的,显然也不行
那么在实际环境中,hadoop是怎么管理元数据的呢?
首先,磁盘确实有块空间,对元数据进行持久化存储的,名为fsimage
如果直接读取磁盘文件,速度肯定跟不上,内存中也要放一些元数据信息
虽然很容易丢失,但可以提供查询服务,实际上就是读写分离,由读写分离就有了数据一致性的问题
因为写入数据,没有写入内存中,最新的元数据记录在哪呢?
实际上是记录在edits.log中,这个文件不提供修改,只提供追加,以日志的形式记录
比如在上传一个文件时,先对namenode进行询问,往哪里写,namenode一边分配一边记录
将空间分配信息记录edits.log,当完成一个副本的写入工作后,通知namenode,被认为是写入成功
这时,将edits.log的数据更新至内存,此时,内存中的数据是最新的
即使现在断电,最新的元数据在edits.log也有保存。
当客户端执行写操作时,NameNode会先在编辑日志中写下记录,并在内存中保持一个文件系统元数据
元数据会在编辑日志有所改动后进行更新。内存中的元数据用来提供读数据请求服务
过程分析:
1.客户端写入文件时,NameNode首先在edits.log文件中记录元数据操作
2.操作完成后将成功信息发送给NameNode。NameNode在内存中写入这次操作新产生的元数据信息
更新的顺序edits.log-----内存-----fsimage
fsimage合并操作:
为防止影响响应速度,由SecondaryNamenode来合并
当edits*.log写满或时间达到1h时,通知SecondaryNamenode进行checkpoint操作
【checkpoint】操作
1.辅助Namenode请求主Namenode停止使用edits文件,暂时将新的写操作记录到一个新文件中,如edits.new。
2.辅助Namenode节点从主Namenode节点获取fsimage和edits文件(采用HTTP GET)
3.辅助Namenode将fsimage文件载入到内存,逐一执行edits文件中的操作,创建新的fsimage文件
4.辅助Namenode将新的fsimage文件发送回主Namenode(使用HTTP POST)
5.主Namenode节点将从辅助Namenode节点接收的fsimage文件替换旧的fsimage文件
用步骤1产生的edits.new文件替换旧的edits文件(即改名)。同时更新fstime文件来记录检查点执行的时间
校验点的目的:
通过把hdfs文件系统元数据的快照保存到FsImage中从而保持了hdfs文件系统的一致性。
校验点触发方式:
1.根据时间循环(dfs.namenode.checkpoint.period)单位是秒触发
2.根据文件系统的事务增加量(dfs.namenode.checkpoint.txns)触发
如果两个都进行了设置,那么哪个先达到了,就会触发校验点。
【备注】
尽管读取FsImage是有效的,但是在FsImage文件后附加是无效的。
相对于修改FsImage,更建议修改EditLog文件。在执行校验点的过程中就是把EditLog转换到FsImage中的过程。