在NameNode中,命名空间(namespace,指文件系统中的目录树、文件元数据等信息)是被全部缓存在内存中的,一旦NameNode重启或者宕机,内存中的所有数据将全部丢失,所以必须要有一种机制能够将整个命名空间持久化保存,并且能在NameNode重启时重建命名空间。这里就是通过fsimage(FSImage类)和edits(FSEditLog类)共同实现的。
fsimage:命名空间镜像,存储了某一个时刻名字节点内存元数据(即命名空间)的信息,是一个二进制文件。它将文件系统目录树中的每个文件或者目录的信息保存为一条记录,每条记录中包括了该文件(或目录)的名称、大小、用户、用户组、修改时间、创建时间等信息。
edits:编辑日志,存储了当原fsiamge被载入内存后,所有对元数据信息的更新操作记录。
那假设这里只用fsimage,就可以了吗?很明显是不可以的。因为fsimage始终是磁盘上的一个文件,不可能时时刻刻都跟NameNode内存中的数据结构保持同步,并且fsimage文件一般都很大,如果将所有的更新操作都实时地写入fsimage文件,为啥是不行的呢?写入分为追加写入或者更新某个位置的记录,这里更新某个位置记录很明显不现实(更新哪个位置,怎么更新,删除又怎么删除)。而追加写入存在的问题有:写失败了,fsimage格式有问题,则导致fsimage加载失败所有元数据就都有问题;或者就是NameNode重启时需要去加载fsimage文件,然后要一条条执行edits中的记录应用于命名空间,就会导致NameNode启动非常缓慢。所以这里就引入了edits解决这些问题。
fsimage+edits就形成了NameNode的完整命名空间。而为啥要进行fsimage和edits的定期合并呢,其实就是为了解决NameNode重启时,使用fsimage初始化命名空间,然后应用edits里的更新操作到命名空间效率的问题,即解决NameNode命名空间的重建效率。
合并操作是如何进行的呢?
在hadoop1.x中是在Secondary NameNode里实现的。
在hadoop2.x中是在Standby NameNode里实现的(所以不需要Secondary NameNode了)。
具体实现流程图:
1.x
2.x