fsimage 和 edits

转载地址:https://www.aboutyun.com/blog-40148-2944.html

怎么理解这两个文件?

这两个文件本质上是一样,都是备份。

先从盘古开天地讲起,(给你设计你会怎么设计)
一开始,光有namenode进程,还并没有这两个文件的概念,当外部客户端有操作了,namenode进程把客户端的操作生成元数据,在进程中记录下来,也就是可能在内存维护一个列表数据结构之类的什么吧。

就这样吧,能用了

问题是这样直接记录在内存中,一掉电这些信息就丢了(服务器不重启就还能好好的运行工作下去),重启,进程起来,进程内部数据结构中没有任何元数据记录,进程可能会认为hdfs是空的,

你想到了用一个文件记录下来。。。可行,先姑且命名为edits,每次操作,进程还是老样子,生成元数据信息放在进程的数据结构中,也就是内存,同时在edits文件中记录下每一步操作的步骤,为什么不直接把元数据顺便保存到edits里面呢?也许是因为记录步骤成本更低,可能记录元数据还比较复杂,总之把步骤记录下来可能比较划算,就在文件中记录步骤,至少现在的机制看来是这样的。

重启,进程中的数据结构刚开始是空的是肯定的,再把之前记录到edits中的步骤,重演一遍,相当于客户端重新操作一遍,把每一步生成的元数据再次存到自己的数据结构中,也就恢复了HDFS集群的datanode分布信息。继续处理客户端的操作,没问题。

客户端新来的操作,操作步骤往这个edits里追加。
每来一个操作,namenode进程一边把操作转换生成元数据保存在自己的内存数据结构中,一遍把步骤写到edits,备份操作步骤,还是前面的以为,为什么不把元数据直接写到edits?

重启的时候,namenode进程先要做的,就是读取edits文件中的所有步骤,重新操作这些步骤,在内存中重现hdfs集群的datanode分布信息,内存的数据结构就又有元数据信息了,这样周而复始。

这样周而复始下去,操作越多edits中的步骤越多。每次进程重启,记录下来的操作步骤都重做一遍的,累死。。。

上面的机制,按理说别操作太多,可以交差了,

幻想客户端应该不会操作太多吧。。。屁,还叫大数据干嘛

稍微。。。改改

这样改,hdfs创建之初就自带生成两个文件放那,hdfs格式化肯定都是空的,我们改进的理念还是保证edits记录功能,稍微有点进化。
两个文件一个叫fsimage,一个叫做eidts
fsimage里面保存生成好元数据的可能是某种神奇的镜像文件,具体是什么我也不清楚,反正就是进程读取的时候速度非常快,结束了进程一个步骤一个步骤的去重现演算所有步骤的体力活。取而代之的是一次性加载fsimage进内存,快速恢复所有元数据。
看过程推演:
安装hdfs,格式化,这时啥也没有,两个文件都是空的,客户端进行操作,namenode进程把每一步操作转的元数据,存到进程的数据结构中,把所有步骤记录到edits。运行下去。。。内存里记录了很多元数据,edits里也记录了这些元数据对应的所有步骤。
duang,重启,内存的数据都空了,进程一起来第一件事就是重演edits里的步骤,相当于客户端重新操作一遍(那这样的话,重演一遍的话,我们知道hdfs不是一次存储多次读取吗?不让第二次写的吗?【hdfs 是块存储,也就是每次读取一个块,存储也是一样的,所以你可以理解为可以随机读写文件块,但是对文件不支持随机读写,因为一个文件块中有很多文件】哦。。。这时正对namenode来说的,也就是客户端写的东西,namenode里有了,namenode拒绝,现在namenode重启啥数据也米有,相当于hdfs服务器是空的,这样就没问题),进程重启之初,namenode进程会把edits中记录的步骤还原到fsimage里,然后把这个文件瞬间加载到进程内存中,这样进程内存中就有了元数据了,这段时间,相当于把edits和fsimage合并,合并到fsimage。
这第一步结束之后,namenode进程的内存状态恢复到重启前的状态了,可以继续接待客户端新的操作了,继续做着把操作步骤记录到eidts,把步骤的元数据转换到自己的进程内存中的工作。
duang,重启,内存又空了,进程一起来,第一件事就是合并这两个文件,重演edits里的步骤,得到元数据追加到fsimage,加载合并后的fsimage到内存,恢复到重启前的内存状态。继续做着接待客户端的工作,把操作步骤记录到eidts,把步骤的元数据转换到自己的进程内存中的工作。周而复始。

等到重启,加载旧的前面n..n次前的元数据信息,也就只需要加载一次fsimage,估计这个镜像文件加载速度不慢,重演的步骤也就最近一次重启前的步骤,相对之前要重现从安装hdfs系统以来所有的操作步骤现在已经少了不少,因为以前的步骤都在之前就合并成fsimage合并掉了。

这样,这个机制也能凑活运行下去,

再稍微优化一下,

再加一个进程,叫secondary namenode,开辟另外的一台服务器,上面运行一个secondaryNamenode进程,相当于一个助手的角色,
定期的从namenode这台服务器复制fsimage和edits文件(这里有个细节就是,deits复制走),然后做掉namenode重启的的时候该做的事情,具体这位助手做了哪些事情:
就是加载fsimage到进程内存,然后重演edits记录的步骤,产生元数据,这个过程就是namenode服务进程重启后要做的第一件事。这个助手之后再把所有元数据导出来,生成相同格式的fsimage文件,重命名为fsimage.chpt,再悄悄放回到主人服务器上并把名字改成fsimage,
主人掉电重启的时候就会直接加载这个文件,快速读进内存,不用重演好多步骤。
助手把edits文件取走了之后,不就没这个文件了吗,这时主人要记录新的操作步骤,要往哪记呢?当然,助手会创建一个新的edits,主人根本不知道edits被替换过,自己写入的是个新的edits。就像你在饭店吃饭,服务员定期给你换了骨盘一样的感觉。
这样,极限的理想情况会变成什么样?就是助手不停的合并主人的edits到fsimage,以至于主人的edits里面的步骤是空的,下次主人重启,根本不要重演步骤,速度是不是就爽了。

fsimage是被复制走的应该,等secondary返回新的fsimage在把旧的覆盖,因为如果是移走,那这时候重启就没fsimage加载了
edits说的移走的,创建一个新的edits给primaryNamenode使用,但如果这时候重启,前面操作的步骤不也丢了?

posted @ 2020-07-03 11:32  Loading~  阅读(438)  评论(0编辑  收藏  举报