百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

HDFS元数据管理机制(hadoop元数据管理)

wxin55 2024-11-11 14:40 8 浏览 0 评论

1. 元数据管理概述

HDFS元数据,按类型分,主要包括以下几个部分:

(1) 文件、目录自身的属性信息,例如文件名、目录名、修改信息等。

(2) 文件记录的信息的存储相关的信息,例如存储块信息,分块情况,副本个数等。

(3) 记录 HDFS 的 DataNode 的信息,用于DataNode 的管理。

按形式分为内存元数据和元数据文件两种,分别存在内存和磁盘上。

HDFS 磁盘上元数据文件分为两种,用于持久化存储:

fsimage 镜像文件:

是元数据的一个持久化的检查点,包含 Hadoop 文件系统中的所有目录和文件元数据信息,但不包含文件块的位置信息。文件块位置信息

只存储在内存中,是在 DataNode 加入集群的时候,NameNode 询问 DataNode 得到的,并且间断的更新。

Edits 编辑日志:

存放的是 Hadoop 文件系统的所有更改操作(文件创建,删除或修改)的日志,文件系统客户端执行的更改操作首先会被记录到 Edits 文件中。

Fsimage 和 Edits 文件都是经过序列化的,在 NameNode 启动的时候,它会将 Fsimage 文件中的内容加载到内存中,之后再执行 Edits 文件中的各项操作使得内存中的元数据和实际的数据数据同步,存在内存中的元数据支持客户端的读操作,也是最完整的元数据。当客户端对 HDFS 中的文件进行新增或者修改操作操作,操作记录首先被记录到 Edits日志文件中,当客户端操作成功后,相应的元数据会更新到内存元数据中。因为 Fsimage 文件一般都很大(GB级别的很常见),如果所有的更新操作都往 Fsimage 文件中添加,这样会导致系统运行的十分缓慢。

HDFS 这种设计实现着手于:

一是内存中数据更新、查询快,极大缩短了操作响应时间;

二是内存中元数据丢失风险颇高(断电等),因此辅佐元数据镜像文件(fsimage)+ 编辑日志文件(edits)的备份机制进行确保元数据的安全。

NameNode 维护整个文件系统元数据。因此,元数据的准确管理,影响着HDFS提供文件存储 服务的能力。

2. 元数据目录相关文件

在Hadoop的HDFS首次部署好配置文件之后,并不能马上启动使用,而是先要对文件系统进行格式化。需要在NameNode(NN)节点上进行如下的操作:

$HADOOP_HOME/bin/hdfs namenode –format

在这里要注意两个概念

一个是文件系统,此时的文件系统在物理上还不存在;

二就是此处的格式化并不是指传统意义上的本地磁盘格式化,而是一些清除与准备工作。

格式化完成之后,将会在$dfs.namenode.name.dir/current目录下创建如下的文件结构,这个目录也正是namenode元数据相关的文件目录:

current/
|-- VERSION
|-- edits_*
|-- fsimage_0000000000008547077
|-- fsimage_0000000000008547077.md5
|-- seen_txid

其中的dfs.namenode.name.dir是在hdfs-site.xml文件中配置的,默认值如下:

<property>
     <name>dfs.namenode.name.dir</name>
     <value>file://${hadoop.tmp.dir}/dfs/name</value>
</property>

hadoop.tmp.dir 是在 core-site.xml中配置的,默认如下
<property>
     <name>dfs.tmp.dir</name>
     <value>/tmp/hadoop-${user.name}</value>
     <descriptition>A base for other temporary dirctories.</descriptition>
</property>

dfs.namenode.name.dir属性可以配置多个目录,各个目录存储的文件结构和内容都完全一样,相当于备份,这样做的好处是当其中一个目录损坏了, 也不会影响到Hadoop的元数据,特别是当其中一个目录是NFS(网络文件系统Network File System,NFS)之上,即使你这台机器损坏了, 元数据也得到保存。

下面对$dfs.namenode.name.dir/current/目录下的文件进行解释。

[hadoop@hadoop001 current]$ cat VERSION 
#Sat Mar 30 10:40:17 CST 2019
namespaceID=2096127794
clusterID=CID-15815684-06ec-43e7-a400-7fbbde19adce
cTime=0
storageType=NAME_NODE
blockpoolID=BP-1332988158-192.168.100.111-1553639671281
layoutVersion=-60
  • namespaceID/clusterID/blockpoolID 这些都是HDFS集群的唯一标识符。标识符被用来防止DataNodes意外注册到另一个集群中的namenode上。这些标识在联邦(federation)部署中特别重要。联邦模式下,会有多个NameNode独立工作。每个的NameNode提供唯一的命名空间(namespaceID),并管理一组唯一的文件块池(blockpoolID)。clusterID将整个集群结合在一起作为单个逻辑单元,在集群中的所有节点上都是一样的。
  • storageType说明这个文件存储的是什么进程的数据结构信息(如果是DataNode,storageType=DATA_NODE);
  • cTime NameNode存储系统创建时间,首次格式化文件系统这个属性是0,当文件系统升级之后,该值会更新到升级之后的时间戳;
  • layoutVersion表示HDFS永久性数据结构的版本信息,是一个负整数。

补充说明:

cluster_id

格式化集群的时候,可以指定集群的cluster_id,但是不能与环境中其他集群有冲突。如果没有提供cluster_id,则会自动生成一个唯一的ClusterID。

$HADOOP_HOME/bin/hdfs namenode -format -clusterId <cluster_id>

seen_txid

$dfs.namenode.name.dir/current/seen_txid非常重要,是存放transactionId的文件,format之后是0,它代表的是namenode里面的edits*文件 的尾数,namenode重启的时候,会按照seen_txid的数字,循序从头跑edits_0000001~到seen_txid的数字。所以当你的hdfs发生异常重启的时候, 一定要比对seen_txid内的数字是不是你edits最后的尾数。

 [hadoop@hadoop001 current]$ pwd
/home/hadoop/app/hadoop-2.6.0-cdh5.7.0/data/dfs/name/current
[hadoop@hadoop001 current]$ ll
 .
 .
 .
-rw-rw-r--. 1 hadoop hadoop 1048576 Apr  7 06:00 edits_0000000000000007338-0000000000000007338
-rw-rw-r--. 1 hadoop hadoop      42 Apr 11 11:25 edits_0000000000000007339-0000000000000007340
-rw-rw-r--. 1 hadoop hadoop 1048576 Apr 11 11:25 edits_inprogress_0000000000000007341
-rw-rw-r--. 1 hadoop hadoop   37129 Apr 11 11:24 fsimage_0000000000000007338
-rw-rw-r--. 1 hadoop hadoop      62 Apr 11 11:24 fsimage_0000000000000007338.md5
-rw-rw-r--. 1 hadoop hadoop   37129 Apr 11 11:25 fsimage_0000000000000007340
-rw-rw-r--. 1 hadoop hadoop      62 Apr 11 11:25 fsimage_0000000000000007340.md5
-rw-rw-r--. 1 hadoop hadoop       5 Apr 11 11:25 seen_txid
-rw-rw-r--. 1 hadoop hadoop     208 Apr 11 11:24 VERSION

[hadoop@hadoop001 current]$ pwd
/home/hadoop/app/hadoop-2.6.0-cdh5.7.0/data/dfs/name/current
[hadoop@hadoop001 current]$ cat seen_txid
7341

Fsimage & edits $dfs.namenode.name.dir/current目录下在format的同时也会生成fsimage和edits文件,及其对应的md5校验文件。

3. secondary namenode

NameNode职责是管理元数据信息,DataNode的职责是负责数据具体存储,那么SecondaryNameNode的作用是什么?对很多初学者来说是非常迷惑的。它为什么会出现在HDFS中。从它的名字上看,它给人的感觉就像是NameNode的备份。但它实际上却不是。大家猜想一下,当HDFS集群运行一段事件后,就会出现下面一些问题:

edit logs文件会变的很大,怎么去管理这个文件是一个挑战。

NameNode重启会花费很长时间,因为有很多改动要合并到fsimage文件上。

如果NameNode挂掉了,那就丢失了一些改动。因为此时的fsimage文件非常旧。

因此为了克服这个问题,我们需要一个易于管理的机制来帮助我们减小edit logs文件的大小和得到一个最新的fsimage文件,这样也会减小在 NameNode上的压力。这跟Windows的恢复点是非常像的,Windows的恢复点机制允许我们对OS进行快照,这样当系统发生问题时, 我们能够回滚到最新的一次恢复点上。SecondaryNameNode就是来帮助解决上述问题的,它的职责是合并NameNode的edit logs到fsimage文件中。

4. Checkpoint

每达到触发条件,会由secondary namenode将namenode上积累的所有edits和一个最新的fsimage下载到本地,并加载到内存进行merge (这个过程称为checkpoint),如下图所示:

4.1 Checkpoint详细步骤

  • NameNode管理着元数据信息,其中有两类持久化元数据文件:edits操作日志文件和fsimage元数据镜像文件。新的操作日志不会立即与fsimage 进行合并,也不会刷到NameNode的内存中,而是会先写到edits中(因为合并需要消耗大量的资源),操作成功之后更新至内存。
  • 有dfs.namenode.checkpoint.period和dfs.namenode.checkpoint.txns 两个配置,只要达到这两个条件任何一个,secondarynamenode就会 执行checkpoint的操作。
  • 当触发checkpoint操作时,NameNode会生成一个新的edits即上图中的edits.new文件,同时SecondaryNameNode会将edits文件和fsimage 复制到本地(HTTP GET方式)。
  • secondarynamenode将下载下来的fsimage载入到内存,然后一条一条地执行edits文件中的各项更新操作,使得内存中的fsimage保存最新, 这个过程就是edits和fsimage文件合并,生成一个新的fsimage文件即上图中的Fsimage.ckpt文件。
  • secondarynamenode将新生成的Fsimage.ckpt文件复制到NameNode节点。
  • 在NameNode节点的edits.new文件和Fsimage.ckpt文件会替换掉原来的edits文件和fsimage文件,至此刚好是一个轮回,即在NameNode中又是 edits和fsimage文件。
  • 等待下一次checkpoint触发SecondaryNameNode进行工作,一直这样循环操作。

4.2 Checkpoint触发条件

Checkpoint操作受两个参数控制,可以通过hdfs-site.xml进行配置:

<property>
<name> dfs.namenode.checkpoint.period</name>
<value>3600</value>
<description>两次连续的checkpoint之间的时间间隔。默认1小时</description>  
</property>

<property>
<name>dfs.namenode.checkpoint.txns</name>
<value>1000000</value>
<description>最大的没有执行checkpoint事务的数量,满足将强制执行紧急checkpoint,即使尚未达到检查点周期。默认设置为100万。</description> 
</property>

从上面的描述我们可以看出,SecondaryNamenode根本就不是Namenode的一个热备,其只是将fsimage和edits合并。其拥有的fsimage不是最新的, 因为在他从NameNode下载fsimage和edits文件时候,新的更新操作已经写到edit.new文件中去了。而这些更新在SecondaryNamenode是没有同步到的!当 然,如果NameNode中的fsimage真的出问题了,还是可以用SecondaryNamenode中的fsimage替换一下NameNode上的fsimage, 虽然已经不是最新的fsimage,但是我们可以将损失减小到最少!

如果大佬们感觉此文对您有帮助,欢迎关注我的个人微信公众号(Java大数据架构师成长之路),感谢。

相关推荐

ES6中 Promise的使用场景?(es6promise用法例子)

一、介绍Promise,译为承诺,是异步编程的一种解决方案,比传统的解决方案(回调函数)更加合理和更加强大在以往我们如果处理多层异步操作,我们往往会像下面那样编写我们的代码doSomething(f...

JavaScript 对 Promise 并发的处理方法

Promise对象代表一个未来的值,它有三种状态:pending待定,这是Promise的初始状态,它可能成功,也可能失败,前途未卜fulfilled已完成,这是一种成功的状态,此时可以获取...

Promise的九大方法(promise的实例方法)

1、promise.resolv静态方法Promise.resolve(value)可以认为是newPromise方法的语法糖,比如Promise.resolve(42)可以认为是以下代码的语...

360前端一面~面试题解析(360前端开发面试题)

1.组件库按需加载怎么做的,具体打包配了什么-按需加载实现:借助打包工具(如Webpack的require.context或ES模块动态导入),在使用组件时才引入对应的代码。例如在V...

前端面试-Promise 的 finally 怎么实现的?如何在工作中使用?

Promise的finally方法是一个非常有用的工具,它无论Promise是成功(fulfilled)还是失败(rejected)都会执行,且不改变Promise的最终结果。它的实现原...

最简单手写Promise,30行代码理解Promise核心原理和发布订阅模式

看了全网手写Promise的,大部分对于新手还是比较难理解的,其中几个比较难的点:状态还未改变时通过发布订阅模式去收集事件实例化的时候通过调用构造函数里传出来的方法去修改类里面的状态,这个叫Re...

前端分享-Promise可以中途取消啦(promise可以取消吗)

传统Promise就像一台需要手动组装的设备,每次使用都要重新接线。而Promise.withResolvers的出现,相当于给开发者发了一个智能遥控器,可以随时随地控制异步操作。它解决了三大...

手写 Promise(手写输入法 中文)

前言都2020年了,Promise大家肯定都在用了,但是估计很多人对其原理还是一知半解,今天就让我们一起实现一个符合PromiseA+规范的Promise。附PromiseA+规范地址...

什么是 Promise.allSettled()!新手老手都要会?

Promise.allSettled()方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的pr...

前端面试-关于Promise解析与高频面试题示范

Promise是啥,直接上图:Promise就是处理异步函数的API,它可以包裹一个异步函数,在异步函数完成时抛出完成状态,让代码结束远古时无限回掉的窘境。配合async/await语法糖,可...

宇宙厂:为什么前端离不开 Promise.withResolvers() ?

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发。1.为什么需要Promise.with...

Promise 新增了一个超实用的 API!

在JavaScript的世界里,Promise一直是处理异步操作的神器。而现在,随着ES2025的发布,Promise又迎来了一个超实用的新成员——Promise.try()!这个新方法简...

一次搞懂 Promise 异步处理(promise 异步顺序执行)

PromisePromise就像这个词的表面意识一样,表示一种承诺、许诺,会在后面给出一个结果,成功或者失败。现在已经成为了主流的异步编程的操作方式,写进了标准里面。状态Promise有且仅有...

Promise 核心机制详解(promise机制的实现原理)

一、Promise的核心状态机Promise本质上是一个状态机,其行为由内部状态严格管控。每个Promise实例在创建时处于Pending(等待)状态,此时异步操作尚未完成。当异步操作成功...

javascript——Promise(js实现promise)

1.PromiseES6开始支持,Promise对象用于一个异步操作的最终完成(包括成功和失败)及结果值的表示。简单说就是处理异步请求的。之所以叫Promise,就是我承诺,如果成功则怎么处理,失败怎...

取消回复欢迎 发表评论: