关于namenode、datanode和secondarynamenode的互动过程

元数据是保存在namenode中的,这些元数据包括文件名、目录名,文件目录从属关系、文件大小,文件与块对应关系,块所对应的节点等;namenode会将这些元数据信息保存在硬盘上,对应的名字是fsimage_txid(即类似这种:fsimage_000000000000003210),以备下次启动时,可以及时获取到整个hdfs文件系统的重要信息;除了这个文件,还有一个文件edits(或者叫editlog,对应的名字格式:edit_0000000000000xxxx-000000000000xxx+1,由于此文件存储hdfs的所有动作,存储数据量较大,因此通常会分成多个文件存储)文件,这个文件记录了namenode(以及客户端)和datanode交互的所有动作,如果说fsimage文件是地理纬度,则edits文件是时间维度,也就是说,fsimage文件+edits文件=hdfs在某一时刻的快照。

当hdfs重新启动时,必须获得hdfs关闭前的状态,而这个状态自然是记录在fsimage和edits文件中的,因此需要将fsimage和edits中保存的信息加载入namenode的内存,其方式是先将fsimage加载,然后逐条执行edits中的指令,这样看好像解决了重启丢失数据的问题,但仍然有其它问题,hdfs集群通常是长期不关机的,这回造成edits文件无限变大,如果经过了很长时间后,需要重启一次,再像之前那样加载fsimage特别是edits文件,会出现启动时间过长的问题.....三五个小时,甚至整天的时间......

解决这个问题的关键在于怎样在不停止hdfs服务的情况下缩小edits文件,且又要保证数据完整性!目前,hadoop是使用secondarynamenode来解决这个问题的,见下图(不好意思,摘自网上,自己画图水平实在太烂....):

关于namenode、datanode和secondarynamenode的互动过程_第1张图片

在上图中,首先,namenode将自己的edits文件重命名为edits-new;然后在满足一些条件的情况下(这些条件包括:时间“默认一个小时,由hdfs-default.xml中的dfs.namenode.checkpoint.preiod参数指定”;次数“默认一百万次,有hdfs-default.xml的dfs.namenode.checkpoint.txns参数指定”)secondarynamenode通过HTTP的GET请求方式去获取namenode上的fsimage和edits文件;第三,在secondarynamenode中将edits和fsimage进行合并(合并过程:snd加载fsimage,执行edits中的操作,然后重新生成一个新的fsimage,并重命名为fsimage_ckpd_txid);第四,通过HTTP的POST方式将合并后的fsimage上传到namenode下,重命名为fsimage_txid,将edits_new文件重命名为edits_txid;最后,namenode加载新的fsimage,在fstime文件中记录下checkpoint发生的时间点。

 

另外,上图中注意红框部分,并不是把edits文件直接更新到fsimage中,而是secondarynamenode先加载下载下来的fsimage,然后逐条执行edits中的记录,最后重新生成一个新的fsimage。

 

你可能感兴趣的:(关于namenode、datanode和secondarynamenode的互动过程)