思考:
NameNode
中的元数据是存储在哪里的?
首先,我们做个假设,如果存储在
NameNode
节点的磁盘中,因为经常需要进行随机访
问,还有响应客户请求,必然是效率过低。因此,元数据需要存放在内存中。但如果只存在
内存中,一旦断电,元数据丢失,整个集群就无法工作了。
因此产生在磁盘中备份元数据的
FsImage
。
这样又会带来新的问题,当在内存中的元数据更新时,如果同时更新
FsImage
,就会导
致效率过低,但如果不更新,就会发生一致性问题,一旦
NameNode
节点断电,就会产生数
据丢失。
因此,引入
Edits
文件(只进行追加操作,效率很高)。每当元数据有更新或者添
加元数据时,修改内存中的元数据并追加到
Edits
中。
这样,一旦
NameNode
节点断电,可
以通过
FsImage
和
Edits
的合并,合成元数据。
但是,如果长时间添加数据到
Edits
中,会导致该文件数据过大,效率降低,而且一旦
断电,恢复元数据需要的时间过长。因此,需要定期进行
FsImage
和
Edits
的合并,如果这
个操作由
NameNode
节点完成,又会效率过低。
因此,引入一个新的节点
SecondaryNamenode
,
专门用于
FsImage
和 Edits 的合并。
1
)第一阶段:
NameNode
启动
(
1
)第一次启动
NameNode
格式化后,创建
Fsimage
和
Edits 文件。如果不是第一次启动,直接加载编辑日志和镜像文件到内存。
(2)客户端对元数据进行增删改的请求。
(3)
NameNode
记录操作日志,更新滚动日志。
(4)
NameNode
在内存中对元数据进行增删改。
2
)第二阶段:
Secondary NameNode
工作
(
1
)
Secondary NameNode
询问
NameNode
是否需要
CheckPoint
。直接带回
NameNode
是否检查结果。
(2)
Secondary NameNode
请求执行
CheckPoint
。
(3)
NameNode
滚动正在写的
Edits
日志。
(4)将滚动前的编辑日志和镜像文件拷贝到 Secondary NameNode。
(5)
Secondary NameNode
加载编辑日志和镜像文件到内存,并合并。
(6)生成新的镜像文件
fsimage.chkpoint
。
(7)拷贝
fsimage.chkpoint
到
NameNode
。
(8)
NameNode
将
fsimage.chkpoint
重新命名成
fsimage
。
参考:尚硅谷