简介:
有这样一个问题,因为客户端要访问 HDFS 必须得经过的 Namenode(以下称为 NN),因为 NN一直在记录(管理)元数据。(元数据可以理解为日志信息)
假如 NN 元数据满了,或者断电了那岂不是数据会丢失了,也就意味着存在Datanode 的数据都报销了。
如果你是一个设计者,会考虑到这种问题,应该这么解决呢?带着这个思考来文中寻找答案吧。
01-NN 的工作机制
首先为了承受大量的请求,尤其是查询,NN 必须运行在内存中,保证响应速度。
NN 记录着元数据,也就是保存着 HDFS 的名字空间。如果客户端要增/删/改文件系统,NN 都会使用一种称为 EditLog 的事务日志记录下来。
EditLog 只提供追加元数据,不会修改元数据。
PS:就好比酒店柜台要登记每天入住或退房的客人,方便以后查水表。
另外 EditLog 的另一个黄金搭档是 FsImage ,存储整个文件系统的名字空间,包括数据块到文件的映射、文件的属性等。
Editlog:记录着最新的操作日志;
FsImage:保存着一段时间的元数据镜像文件;
因为 Editlog 和 FsImage 是 NN 的核心,一旦出了问题直接 GG ,所以 NN 可以配置成支持维护多个FsImage 和 Editlog 的副本,保证可靠性。
PS: 分散风险一直是个重要的课题。
NN 的工作机制如图所示:
- 客户端上传文件时,NN 首先往 Editlog 文件(大小 64 MB)中记录元数据操作日志。
- 客户端开始上传文件,完成后返回成功信息给 NN,NN 就在内存中写入这次上传操作的新产生的元数据信息。
- 每当 Editlog 文件写满时,需要将这一段时间的新的元数据刷到 FsImage 文件中去。
问题:
内存记录什么时候才需要同步到磁盘文件中?用什么形式?
答:在 Editlog 文件满之前或者满的时候,需要将这一段时间的新的元数据刷到 FsImage 文件中去。
但是 Editlog 与 FsImage 合并的时候,格式不同需要进行转换,若在 NN 进行转化,需要占用一定的空间以及 CPU,这样会降低响应的速度。
所以这个时候需要引入 Secondary NameNode 。
02-Secondary NameNode
从字面上看,很容易被人误以为是 NN 的备胎,其实它的职责是合并 NN 的 Editlog 到 FsImage 文件中。
具体操作:
- NN 的结构大概分为 内存(meta.data)、fsimage、edits
- 当 NN 的 edits 快满了,于是通知 SN 进行 Chekpoint(合并) 操作,这时 SN 要通知 NN 马上对 edits 文件停止写入数据,因为如果 NN 还在持续写入数据,会导致数据不一致,但客户端的上传文件又不可能停止。
- 于是呢,NN 这边又新建了一个 edits.new 新文件。
- SN 把 NN 中的 fsimage 和 edits 用 HTTP 的方式下载到 SN 中,进行合并,生成 新的 fsimage.chekpoint
- SN 把新的 fsimage.chekpoint 上传给 NN ,并且通知 NN 删除原来的 fsimage,把 fsimage.chekpoint 重命名回 fsimage;同时也让 NN 删除原来的 edits 把 edits.new 重命名回去。
NN 后记
NN 是整个文件系统的管理节点。维护着整个文件系统的文件目录树,文件/目录的元信息和每个文件对应的数据块列表。接收用户的操作请求。
(均保存在 Linux 文件系统中)文件包括:
fsimage :元数据镜像文件。存储着某一时间段 NameNode 内存元数据信息。
edits :操作日志文件。
fstime: 保存最近一次 chekpoint 的时间。
什么时候 chekpoint ?
fs.chekpoint.period 指定两次 chekpoint 的最大时间间隔,默认 3600 s
fs.chekpoint.size 规定 edits 文件的最大值,一旦超过这个值则强制 chekpoint,不管是否到达最大时间间隔,默认大小 64 M。