SecondaryNamenode工作机制
前提知识点
HDFS中,有NameNode和DataNode两种节点。
DataNode是真正存数据的地方。NameNode存的是一种叫元数据的东西。而元数据可以理解为文件在磁盘中的目录(这个文件被分成几块、每块都在哪些机器上)。客户端请求查询数据的时候,通过NameNode查询到的元数据就能方便的在集群上不同的机器上找到需要的数据。
元数据这个东西,为了更快的反馈给客户端,存储位置选择的肯定是高速的内存,而不是磁盘。
小知识点:
- 一个元数据占150K
fsImage的由来
但是内存中的数据是易丢失的,所以如果突然NameNode挂掉了。我们将失去所有的元数据(目录),而元数据一旦丢失,就再也找不到我们存储的数据了。这肯定是不能接受的。于是,我们就需要定期的给元数据备份。于是有了fsimage(元数据的镜像文件,磁盘中)。有了fsimage,就算NameNode挂了,下次启动的时候就能根据这个fsimage来恢复元数据。
怎么方便理解?
我们可以把元数据看成一个个对象(就java那种对象),而备份fsimage就是将这个对象序列化到磁盘上。后面备份元数据这个过程都会称为序列化。
fsimage存在的问题
-
元数据大,数据序列化慢的问题
我们一条元数据150K,序列化成fsimage问题不大。但是如果我们是大数据,如果元数据上亿条了呢(15G左右),十亿条呢?如果我们要序列化这个fsimage,就很慢了。因为我们的Namenode是不知道我的哪些元数据是序列化了的,哪些是没有序列化的。每次的序列化都将可能是一次艰巨的任务。
-
可能存在的数据丢失问题
我们知道,fsimage是Namenode的镜像文件,为了维护元数据的数据一致性,我们就要定期去维护这个fsimage。那么我们就要选择一个时间去更新这个fsimage,而这个时间是多少呢?我们假设是30分钟序列化一次。那么我们如果第29分钟的时候Namenode突然挂了,这29分钟新增的元数据就没了,无论多少数据都没了。这是我们承受不起的。
SecondaryNamenode的由来(简称SN)
为了解决上面提到的两个问题。
提出了SecondaryNamenode这个概念。
问题的解决思路:edits的由来
为了解决元数据大,定期一次的序列化慢,消耗大这个问题。HDFS新增了edits(操作记录日志,磁盘里)这样一个东西。
edit 里面只存元数据操作的记录,比如什么时候创建了什么目录、什么时候新增了什么文件、什么时候删除了什么文件。从而我们可以根据这个记录,结合定义好的算法,恢复出元数据来。而一直记录操作记录是件很快且方便的事。
edits结合fsimage的工作方式
有了一直维护的edits就注定我们的数据不会丢失。就算Namenode突然挂了,我们操作记录已经存了,再开启的时候再把操作记录还原成元数据就行了。第二个问题解决了。
而定期将我们的edits还原成元数据,并追加到已有的fsimage中。将一次完成得巨量的序列化工作,换成一步步慢慢维护的fsimage,每次将edits转换成元数据追加到fsimage中后将旧的edits删除,新来的元数据变化就是新的edits,记录了元数据的状态。good~ edits的工作将第一个问题也解决了。
但是紧接着来了第三个问题。
我们的操作日志不可能只有新增的信息,大量删除的信息显然也是存在的,新增的信息好说,我们直接转成对应的元数据追加到fsimage中就好。那删除的呢?我们只能去已有的fsimage中找到对应的元数据然后删了。显然磁盘不能做这些事,我们只能用我们的内存来干活了。那么要多少内存了?一半甚至以上。因为我们要保证我们已有的元数据都能读到内存里,加上NameNode上面本来就有,各占半壁江山?显然这资源利用率是非常低的,我们要长期空很多内存来防备我们的备份能成功完成。
为了解决上面这个问题,我们将edits还原成元数据并和已有的fsimage合并的过程放在了另外一台机器上进行。这就是SecondaryNamenode的由来。
竟然是两台机器了,肯定要有分工的。那么他们两个是怎么工作的呢?
SecondaryNamenode的工作机制
现在我们看看我们有什么,一台NameNode,一台SecondaryNamenode。
NameNode | SecondaryNamenode |
---|---|
元数据 | edits(NameNode上来的) |
edits | fsimage(自己存的,内存中) |
fsimage |
拉取edits的过程 (checkpoint)
NameNode还是一直维护这自己的edits(每个edit有固定的大小,达到一定大小后如果还没有被处理,就会单独拎出来保存在文件中,而当前正在维护的edit有个特殊的编号edits.inprogress)。定期SN会发出信号,询问NameNode我能不能干活了(拉取NameNode的edits)?如果获得可拉取的信号,就强制滚动一下当前的edits.inprogress(滚动差不多就算强制把现在正维护的单拎出来弄成一个单独的文件存储不管你有多少,看来SN还是很尽责的就想着多干点活),然后将此时所以的非inprogress的edits全部拉到自己的内存中。这个过程叫checkpoint。
除了定期询问,edits达到一定数量了,也会触发checkpoint。
合并和备份
SN拉取来新的edits后,就掏出自己内存中的fsimage开始计算合并了。获得了新的fsimage然后将它**发给NameNode,**然后存着这个fsimage(还是存内存里)以便下次合并用。
图解工作机制
图片看不清就放大点,不能惯着你们。