HDFS:Edits和Fsimage详解与合并流程_为什么要将edit logs和fsimage定期合并。-程序员宅基地

技术标签: 大数据开发  hadoop  大数据  

HDFS:Edits和Fsimage详解与合并流程

NameNode如何管理和存储元数据

计算机中存储数据有两种:内存或磁盘
元数据存储磁盘: 存储磁盘无法面对客户端对元数据信息的任意的快速低延迟的响应,但是安全性高
元数据存储内存:元数据存放内存,可以高效的查询以及快速响应客户端的查询请求,数据保存在内存,如果断电,内存中的数据全部丢失

因此,考虑上述两种存储方式的优缺点,HDFS采用了内存+磁盘的形式来管理元数据。即: NameNode(内存)+FsImage文件. 其中,NameNode文件维护了文件与数据块的映射表以及数据块与数据节点的映射表,比如,一个文件它被切分成了几个数据块,这些数据块分别存储在哪些datanode节点上。而Fsimage保存在磁盘上,为某一时刻下内存中元数据在本地磁盘的映射。就是在该时刻下,内存中元数据记录的所有文件块和目录,分别的状态,位于哪些datanode,各自的权限,各自的副本个数等 (可以通过查看Fsimage保存的内容可以看到上述信息)。因此,利用内存+磁盘的方式,内存中的元数据可以快速响应客户端的用户请求,而映射到磁盘中的元数据Fsimage可以实现安全性,防止数据的丢失。

而接下来的一个新问题是:磁盘和内存中的元数据如何进行划分。
即两个数据一摸一样,还是两个数据合并到一起才是一份完整的数据呢?

  • 一模一样:client如果对元数据进行增删改操作,需要保证两个数据的一致。FsImage文件操作起来效率也不高,因为FsImage存储在磁盘中,对磁盘中的内容进行写入势必会增加很多的IO操作,也要占用CPU。此时,相当于每一次增删改操作,都需要对两个文件同时进行修改。
  • 两个合并=完整数据:由于如果要将操作写入磁盘会降低运行效率。所以想法就是对于增删改操作,只有内存中的元数据进行响应,而不直接进行磁盘IO读写。此时,为了保证两个数据的一致性,NameNode就引入了以一个edits文件,该日志文件只能进行追加写入,以此来记录client的每次增删改操作。虽然此时仍然有IO流的操作,但是相比于每次将元数据内容写入Fsimage,edits日志文件的写入内容更少,效率更高。

至此我们知道了HDFS元数据管理机制采用了内存+磁盘的形式,内存中的NameNode来快速响应客户端的查询请求,磁盘中的元数据作为备份,防止数据的丢失。同时,为了保证内存和磁盘中元数据的一致,hdfs采用了呀一个edits的日志文件,该文件记录了客户端对元数据的操作。利用edits+Fsimage的形式,就完成了对元数据的管理和存储。下面就来对这两个部分进行深入介绍,即它们是如何合作来实现管理和存储的。

FsImage

  • FsImage: 是namenode中关于元数据的镜像,一般称为检查点(checkpoing),这里包含了HDFS文件系统所有目录以及文件相关信息(Block数量,副本数量,权限等信息)

在机器学习或这深度学习模型训练的过程中,为了防止异常中断,所以都会设定在某一具体时刻或者效果达到最好结果时,将模型参数都保存下来。这样,后续就可以在异常中断后利用来文件直接对模型的参数进行初始化赋值,而不用再重新进行训练。在模型训练中保存的文件也叫作checkpoint。因此这里HDFS的检查点checkpoint也可以同样来理解。即FsImage保存了某一时刻下元数据内的所有信息,这样,当HDFS异常中断或者程序启动时,就可以利用该检查点文件,来对元数据进行初始化,以此还原到异常中断或程序停止前的最新状态。

Edits文件

  • 存储了客户端对HDFS文件系统所有的更新操作记录,Client对HDFS文件系统所有的更新操作都会被记录到Edits文件中(不包括查询操作)

最开始提到,Client对HDFS的更新操作会更新内存中的元数据信息,而不会直接写入到FsImage文件中。那么为了保证内存和磁盘中元数据信息的一致性,就利用了edits文件来记录下所有的更新操作。edits文件记录的就是当原FsImage被载入内存后,Client又对元数据进行了哪些操作。 这样,只要在原FsImage中执行这些操作,对保存的元数据信息进行更新,就可以使得内存和磁盘汇总的元数据信息一致。通过此方法,即解决了为了保证一致性,要对FsImage直接进行写入的过程。这也是引入edits文件的关键原因。

Fsimage与Edits的合并

介绍完FsImage和Edits文件的概念和各自的作用之后,就方便后续对两者进行合并过程的理解。
因为edits文件是一个只能追加写入的文件,在程序运行过程中会不断的记录客户端的更新操作。同时,根据上面对Edits中的介绍可知,引入载入的FsImage的元数据内容不是最新状态,所以只有在FsImage的内容上,执行edits文件中的更新操作,才能将FsImage的元数据更新为最新状态。此时,假设edits不断的进行追加写,当某一时刻需要NameNode重启时,此时NameNode会先将FsImage里面的内容映射到内存中,即相当于对元数据进行初始化,同时为了恢复到最新的状态,还需要在一条一条的执行edits中的记录。当edits文件非常大时,会导致NameNode启动过程非常慢,而在这段时间HDFS系统会处于安全模式,即保证了要将元数据恢复到最新后才能接收客户端请求。这显然是不符合用户要求的。因此,就需要设计能不能在NameNode运行的时候使得edits文件小一些,这样就能使启动过程加快。所以就要引入FsImage和Edits的合并过程。

首先给出合并过程的执行流程图。接下来对每个流程部分进行详细介绍。

Namenode & SecondaryNamenode & Checkpoint 工作机制

首先可以看出,除了NameNode节点外,为了进行合并,还引入了另一个SecondaryNameNode节点。SecondaryNanoe是HDFS架构中的一个组成部分,它是用来保存namenode中对HDFS metadata的信息的备份而设定的。一般都是将SecondaryNamenode单独运行在一台机器上。

详细流程介绍如下:
首先黑色字体代表的流程表示NameNode自身启动和运行时的流程,下面每个序号对应图中流程。
1)程序启动时,需要对元数据进行恢复。根据上述对FsImage和edits文件的已经知道,HDFS首先将Fsimage读入内存对元数据进行恢复,然后再读edits文件中的更新操作在恢复后的元数据上进行执行,使得此时的NameNode中保存的是停止前的最新状态。
2、3)当有客户端执行增删改查操作时,HDFS会记录其中的增删改操作到edits文件中,这样就避免了直接对Fsimage文件的IO操作。
4) 内存中保存的元数据执行客户端的增删改查操作。(FsImage在此阶段是不改变的)

粉色字体代表的流程表示SecondaryNameNode对文件的合并流程,下面每个序号对应图中流程。
1)SecondaryNameNode向NameNode发送请求,询问是否需要进行合并。在Hadoop中通过两个维度来控制是否需要Checkpoint,如图中所示:1) 到定时时间 2) Edits文件是否满或超过了设定的大小范围。
2)如果满足上面的触发条件,则开始下述执行合并流程。
3、4)由于NameNode需要将此时的edits文件和FsImage文件发送到SecondaryNamenode,所以在NameNode节点上需要停止使用该edits文件,暂时将新的写操作写到一个新的文件比如edits_inprogress_002中,而将原先的edits_inprogress_001重命名为esits_001进行发送。这样,有inprogress标识的edits表示最新正在写入更新操作的文件,而没有该标识,且后面数字最大的edits文件,即表示最后一个已经合并的文件。比如在实际的文件夹下会生成以下文件:
在这里插入图片描述

各文件名的含义即如上所述。

5)SecondaryNamenode通过HTTP GET方式从NameNode上获取到fsimage和edits文件,并下载到本地的相应目录下。然后,SecondaryNamenode将下载下来的fsimage载入内存,然后一条一条地执行edits文件中的各项更新操作,使得内存中的fsimage保存最新;这个过程就是edits和fsimage文件的合并。(是不是跟我们上面说的在NameNode启动时的载入过程很像。HDFS就是利用了另一台机器的资源来对FsImage进行更新,这样NameNode所在节点的资源就只专注响应对客户端的操作)。

6)经过合并阶段之后,FsImage的内容即进行了更新,此时并不与NameNode中的元数据内容一致,相差的仍然是edits_inprogress_002中写入的更新操作。

7、8)SecondaryNameNode会通过post方式将新的FsImage文件发送到NameNode节点上。NameNode将接收到的新的fsimage替换旧的fsimage文件,同时将edit_inprogress_002文件来记录合并后续的更新操作。通过这个过程,edits就变小了。

总结

通过上面的描述可以总结几点。

  1. 为了解决元数据备份的问题,HDFS采用了edits+FsImage的策略,edits文件保存了客户端的更新操作,Fsimage保存了元数据的具体内容。HDFS在运行时将客户端的操作响应在内容中的元数据上,同时将所有的更新操作写入edits文件,避免了直接对FsImage进行操作造成效率降低
  2. HDFS为了解决edits不断追加写入过大的问题,采用了edits与FsImage合并的策略。即edits文件不是一直在原文件中进行写入的,而是在一定时间或者条件后,就把该时间段内客户端的更新操作同步到FsImage文件中,来更新FsImage文件的内容。这样,新的edits文件就可以只记录合并之后的更新操作,从而减小了edits文件的大小。
  3. HDFS通过引入SecondaryNameNode来实现上述过程,利用了一台独立的机器资源来处理合并流程。所谓edits与FsImage的合并,其实就是在SecondaryNamenode内存中,将edits中记录一条一条的在fsiamge中执行,来更新Fsiamge的内容。同时,可以知道,SecondaryNameNode获取到的FsImage不是最新的,因为在它从NameNode下载edits和FsImage文件的时候,新的更新操作已经写到新的edits文件里去了(比如这里的edits_inprogress_002)。而这些更新在SecondaryNamenode是没有同步到的。
  4. edits和FsImage利用了文件命名格式来标识各自的最新文件。如fsiamge和edits文件图中所示,edits文件以edits_开头,后面跟一个txid范围端,并且多个edit log之间首尾相连,正在使用的edits文件名字为edits_inprogress_txid。该路径下还会保存两个FsImage文件(dfs.namenode.num.checkpoints.retained在namenode上保存的fsimage个数的默认配置,超过的被删除,默认保存两个)。文件格式为fsimage_txid,txid与edits中的txid对应,表示该fsimage加载的是哪一个edits。比如从图中可以看出,此时的fsimage已经加载到尾数为1545的edits文件内容

其它补充

实际查看FsImage文件的内容时,可以发现Fsimage中是没有记录块所对应DataNode的。比如下图所示:
在这里插入图片描述
在内存元数据中是有记录块所对应的datanode信息,但是fsimage中就剔除了这个信息;HDFS集群在启动的时候会加载image以及edits文件,block对应的dn信息都没有记录,集群启动时会有一个安全模式(safemode),安全模式就是为了让datanode汇报自己当前所持有的block信息给nn来补全元数据。后续每隔一段时间datanode都要汇报自己持有的block信息。因为即使fsimage中记录了datanode信息,但是在恢复元数据的过程中,可能某些datanode节点出现了问题。所以,其实无论FsImage中是否对block的dn信息进行了记录,恢复的时候都是需要dn来汇报自己持有的block信息,这样才是最真实和安全的。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Urbanears/article/details/115031274

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签