欢迎光临散文网 会员登陆 & 注册

大数据离线阶段-03

2023-08-14 10:07 作者:程序员四次元ポケット  | 我要投稿

HDFS入门

HDFS基本概念

HDFS介绍

HDFS是Hadoop Distribute File System 的简称,意为:Hadoop分布式文件系统。是Hadoop核心组件之一,作为最底层的分布式存储服务而存在。

分布式文件系统解决的问题就是大数据存储。它们是横跨在多台计算机上的存储系统。分布式文件系统在大数据时代有着广泛的应用前景,它们为存储和处理超大规模数据提供所需的扩展能力。


HDFS设计目标

  1. 硬件故障是常态, HDFS将有成百上千的服务器组成,每一个组成部分都有可能出现故障。因此故障的检测和自动快速恢复是HDFS的核心架构目标。

  2. HDFS上的应用与一般的应用不同,它们主要是以流式读取数据。HDFS被设计成适合批量处理,而不是用户交互式的。相较于数据访问的反应时间,更注重数据访问的高吞吐量。

  3. 典型的HDFS文件大小是GB到TB的级别。所以,HDFS被调整成支持大文件。它应该提供很高的聚合数据带宽,一个集群中支持数百个节点,一个集群中还应该支持千万级别的文件。

  4. 大部分HDFS应用对文件要求的是write-one-read-many访问模型。一个文件一旦创建、写入、关闭之后就不需要修改了。这一假设简化了数据一致性问题,使高吞吐量的数据访问成为可能。

  5. 移动计算的代价比之移动数据的代价低。一个应用请求的计算,离它操作的数据越近就越高效,这在数据达到海量级别的时候更是如此。将计算移动到数据附近,比之将数据移动到应用所在显然更好。

  6. 在异构的硬件和软件平台上的可移植性。这将推动需要大数据集的应用更广泛地采用HDFS作为平台。

HDFS重要特性

首先,它是一个文件系统,用于存储文件,通过统一的命名空间目录树来定位文件;

其次,它是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色。


master/slave架构

HDFS采用master/slave架构。一般一个HDFS集群是有一个Namenode和一定数目的Datanode组成。

Namenode是HDFS集群主节点,Datanode是HDFS集群从节点,两种角色各司其职,共同协调完成分布式的文件存储服务。

分块存储

HDFS中的文件在物理上是分块存储(block)的,块的大小可以通过配置参数来规定,默认大小在hadoop2.x版本中是128M。

名字空间(NameSpace)

HDFS支持传统的层次型文件组织结构。用户或者应用程序可以创建目录,然后将文件保存在这些目录里。文件系统名字空间的层次结构和大多数现有的文件系统类似:用户可以创建、删除、移动或重命名文件。

Namenode负责维护文件系统的名字空间,任何对文件系统名字空间或属性的修改都将被Namenode记录下来。

HDFS会给客户端提供一个统一的抽象目录树,客户端通过路径来访问文件,形如:hdfs://namenode:port/dir-a/dir-b/dir-c/file.data。

Namenode元数据管理

我们把目录结构及文件分块位置信息叫做元数据。Namenode负责维护整个hdfs文件系统的目录树结构,以及每一个文件所对应的block块信息(block的id,及所在的datanode服务器)。

Datanode数据存储

文件的各个block的具体存储管理由datanode节点承担。每一个block都可以在多个datanode上。Datanode需要定时向Namenode汇报自己持有的block信息。

副本机制

为了容错,文件的所有block都会有副本。每个文件的block大小和副本系数都是可配置的。应用程序可以指定某个文件的副本数目。副本系数可以在文件创建的时候指定,也可以在之后改变。

副本数量也可以通过参数设置dfs.replication,默认是3。

一次写入,多次读出

HDFS是设计成适应一次写入,多次读出的场景,且不支持文件的修改。

正因为如此,HDFS适合用来做大数据分析的底层存储服务,并不适合用来做.网盘等应用,因为,修改不方便,延迟大,网络开销大,成本太高。

HDFS基本操作

Shell 命令行客户端

Hadoop提供了文件系统的shell命令行客户端,使用方法如下:


hadoop  fs <args>


文件系统shell包括与Hadoop分布式文件系统(HDFS)以及Hadoop支持的其他文件系统(如本地FS,HFTP FS,S3 FS等)直接交互的各种类似shell的命令。所有FS shell命令都将路径URI作为参数。

URI格式为scheme://authority/path。对于HDFS,该scheme是hdfs,对于本地FS,该scheme是file。scheme和authority是可选的。如果未指定,则使用配置中指定的默认方案。

对于HDFS,命令示例如下:

hadoop fs -ls  hdfs://namenode:host/parent/child

hadoop fs -ls  /parent/child    fs.defaultFS中有配置

对于本地文件系统,命令示例如下:

hadoop fs -ls file:///root/

如果使用的文件系统是HDFS,则使用hdfs dfs也是可以的,此时


hadoop fs <args> = hdfs dfs <args>


Shell常用命令介绍

-ls

使用方法:hadoop fs -ls [-h] [-R] <args>

功能:显示文件、目录信息。

示例:hadoop fs -ls /user/hadoop/file1

-mkdir

使用方法:hadoop fs -mkdir [-p] <paths>

功能:在hdfs上创建目录,-p表示会创建路径中的各级父目录。

示例:hadoop fs -mkdir –p /user/hadoop/dir1

-put使用方法:hadoop fs -put [-f] [-p] [ -|<localsrc1> .. ]. <dst>

功能:将单个src或多个srcs从本地文件系统复制到目标文件系统。

-p:保留访问和修改时间,所有权和权限。

-f:覆盖目的地(如果已经存在)

示例:hadoop fs -put -f localfile1 localfile2 /user/hadoop/hadoopdir

-get

使用方法:hadoop fs -get [-ignorecrc] [-crc] [-p] [-f] <src> <localdst>

-ignorecrc:跳过对下载文件的CRC检查。

-crc:为下载的文件写CRC校验和。

功能:将文件复制到本地文件系统。

示例:hadoop fs -get hdfs://host:port/user/hadoop/file localfile

-appendToFile

使用方法:hadoop fs -appendToFile <localsrc> ... <dst>

功能:追加一个文件到已经存在的文件末尾

示例:hadoop fs -appendToFile localfile  /hadoop/hadoopfile

-cat

使用方法:hadoop fs -cat [-ignoreCrc] URI [URI ...]

功能:显示文件内容到stdout

示例:hadoop fs -cat  /hadoop/hadoopfile

-tail

使用方法:hadoop fs -tail [-f] URI

功能:将文件的最后一千字节内容显示到stdout。

-f选项将在文件增长时输出附加数据。

示例:hadoop  fs  -tail  /hadoop/hadoopfile

-chgrp

使用方法:hadoop fs -chgrp [-R] GROUP URI [URI ...]

功能:更改文件组的关联。用户必须是文件的所有者,否则是超级用户。

-R将使改变在目录结构下递归进行。

示例:hadoop fs -chgrp othergroup /hadoop/hadoopfile

-chmod

功能:改变文件的权限。使用-R将使改变在目录结构下递归进行。

示例:hadoop  fs  -chmod  666  /hadoop/hadoopfile

-chown

功能:改变文件的拥有者。使用-R将使改变在目录结构下递归进行。

示例:hadoop  fs  -chown  someuser:somegrp   /hadoop/hadoopfile

-cp

功能:从hdfs的一个路径拷贝hdfs的另一个路径

示例: hadoop  fs  -cp  /aaa/jdk.tar.gz  /bbb/jdk.tar.gz.2

-mv  

功能:在hdfs目录中移动文件

示例: hadoop  fs  -mv  /aaa/jdk.tar.gz  /

-getmerge

功能:合并下载多个文件

示例:比如hdfs的目录 /aaa/下有多个文件:log.1, log.2,log.3,...

hadoop fs -getmerge /aaa/log.*  ./log.sum

-rm

功能:删除指定的文件。只删除非空目录和文件。-r 递归删除。

示例:hadoop fs -rm -r /aaa/bbb/

-df

功能:统计文件系统的可用空间信息

示例:hadoop  fs  -df  -h  /

-du

功能:显示目录中所有文件大小,当只指定一个文件时,显示此文件的大小。

示例:hadoop fs -du /user/hadoop/dir1

-setrep

功能:改变一个文件的副本系数。-R选项用于递归改变目录下所有文件的副本系数。

示例:hadoop fs -setrep -w 3 -R /user/hadoop/dir1

HDFS基本原理

NameNode概述

  1. NameNode是HDFS的核心。

  2. NameNode也称为Master。

  3. NameNode仅存储HDFS的元数据:文件系统中所有文件的目录树,并跟踪整个集群中的文件。

  4. NameNode不存储实际数据或数据集。数据本身实际存储在DataNodes中。

  5. NameNode知道HDFS中任何给定文件的块列表及其位置。使用此信息NameNode知道如何从块中构建文件。

  6. NameNode并不持久化存储每个文件中各个块所在的DataNode的位置信息,这些信息会在系统启动时从数据节点重建。

  7. NameNode对于HDFS至关重要,当NameNode关闭时,HDFS / Hadoop集群无法访问。

  8. NameNode是Hadoop集群中的单点故障。

  9. NameNode所在机器通常会配置有大量内存(RAM)。


DataNode概述

  1. DataNode负责将实际数据存储在HDFS中。

  2. DataNode也称为Slave。

  3. NameNode和DataNode会保持不断通信。

  4. DataNode启动时,它将自己发布到NameNode并汇报自己负责持有的块列表。

  5. 当某个DataNode关闭时,它不会影响数据或群集的可用性。NameNode将安排由其他DataNode管理的块进行副本复制。

  6. DataNode所在机器通常配置有大量的硬盘空间。因为实际数据存储在DataNode中。

  7. DataNode会定期(dfs.heartbeat.interval配置项配置,默认是3秒)向NameNode发送心跳,如果NameNode长时间没有接受到DataNode发送的心跳, NameNode就会认为该DataNode失效。

  8. block汇报时间间隔取参数dfs.blockreport.intervalMsec,参数未配置的话默认为6小时.


HDFS的工作机制

NameNode负责管理整个文件系统元数据;DataNode负责管理具体文件数据块存储;Secondary NameNode协助NameNode进行元数据的备份。

HDFS的内部工作机制对客户端保持透明,客户端请求访问HDFS都是通过向NameNode申请来进行。


HDFS写数据流程


详细步骤解析:

1.client发起文件上传请求,通过RPC与NameNode建立通讯,NameNode检查目标文件是否已存在,父目录是否存在,返回是否可以上传;

2.client请求第一个 block该传输到哪些DataNode服务器上;

3.NameNode根据配置文件中指定的备份数量及副本放置策略进行文件分配,返回可用的DataNode的地址,如:A,B,C;注:默认存储策略由BlockPlacementPolicyDefault类支持。也就是日常生活中提到最经典的3副本策略。1st replica 如果写请求方所在机器是其中一个datanode,则直接存放在本地,否则随机在集群中选择一个datanode.2nd replica 第二个副本存放于不同第一个副本的所在的机架.3rd replica 第三个副本存放于第二个副本所在的机架,但是属于不同的节点

4.client请求3台DataNode中的一台A上传数据(本质上是一个RPC调用,建立pipeline),A收到请求会继续调用B,然后B调用C,将整个pipeline建立完成,后逐级返回client;

5.client开始往A上传第一个block(先从磁盘读取数据放到一个本地内存缓存),以packet为单位(默认64K),A收到一个packet就会传给B,B传给C;A每传一个packet会放入一个应答队列等待应答。

6.数据被分割成一个个packet数据包在pipeline上依次传输,在pipeline反方向上,逐个发送ack(命令正确应答),最终由pipeline中第一个DataNode节点A将pipeline ack发送给client;

7.当一个block传输完成之后,client再次请求NameNode上传第二个block到服务器。

HDFS读数据流程

详细步骤解析:

  1. Client向NameNode发起RPC请求,来确定请求文件block所在的位置;

  2. NameNode会视情况返回文件的部分或者全部block列表,对于每个block,NameNode都会返回含有该block副本的DataNode地址;

  3. 这些返回的DN地址,会按照集群拓扑结构得出DataNode与客户端的距离,然后进行排序,排序两个规则:网络拓扑结构中距离Client近的排靠前;心跳机制中超时汇报的DN状态为STALE,这样的排靠后;

  4. Client选取排序靠前的DataNode来读取block,如果客户端本身就是DataNode,那么将从本地直接获取数据;

  5. 底层上本质是建立FSDataInputStream,重复的调用父类DataInputStream的read方法,直到这个块上的数据读取完毕;一旦到达块的末尾,DFSInputStream 关闭连接并继续定位下一个块的下一个 DataNode;

  6. 当读完列表的block后,若文件读取还没有结束,客户端会继续向NameNode获取下一批的block列表;一旦客户端完成读取,它就会调用 close() 方法。

  7. 读取完一个block都会进行checksum验证,如果读取DataNode时出现错误,客户端会通知NameNode,然后再从下一个拥有该block副本的DataNode继续读。

  8. NameNode只是返回Client请求包含块的DataNode地址,并不是返回请求块的数据;

  9. 最终读取来所有的block会合并成一个完整的最终文件。

HDFS其他功能

不同集群之间的数据复制

在我们实际工作当中,极有可能会遇到将测试集群的数据拷贝到生产环境集群,或者将生产环境集群的数据拷贝到测试集群,那么就需要我们在多个集群之间进行数据的远程拷贝,hadoop自带也有命令可以帮我们实现这个功能。

集群内部文件拷贝scp

cd /export/softwares/

scp -r jdk-8u141-linux-x64.tar.gz root@node2:/export/

跨集群之间的数据拷贝distcp

bin/hadoop distcp hdfs://node1:8020/jdk-8u141-linux-x64.tar.gz  hdfs://cluster2:9000/

Archive档案的使用

HDFS并不擅长存储小文件,因为每个文件最少一个block,每个block的元数据都会在NameNode占用内存,如果存在大量的小文件,它们会吃掉NameNode节点的大量内存。

Hadoop Archives可以有效的处理以上问题,它可以把多个文件归档成为一个文件,归档成一个文件后还可以透明的访问每一个文件。

如何创建Archive

Usage: hadoop archive -archiveName name -p <parent> <src>* <dest>

其中-archiveName是指要创建的存档的名称。比如test.har,archive的名字的扩展名应该是*.har。 -p参数指定文件存档文件(src)的相对路径。

举个例子:-p /foo/bar a/b/c e/f/g

这里的/foo/bar是a/b/c与e/f/g的父路径,

所以完整路径为/foo/bar/a/b/c与/foo/bar/e/f/g

例如:如果你只想存档一个目录/input下的所有文件:

hadoop archive -archiveName test.har -p /input  /outputdir

这样就会在/outputdir目录下创建一个名为test.har的存档文件。


如何查看Archive

首先我们来看下创建好的har文件。使用如下的命令:

hadoop fs -ls /outputdir/test.har

这里可以看到har文件包括:两个索引文件,多个part文件(本例只有一个)以及一个标识成功与否的文件。part文件是多个原文件的集合,根据index文件去找到原文件。

例如上述的三个小文件1.txt 2.txt 3.txt内容分别为1,2,3。进行archive操作之后,三个小文件就归档到test.har里的part-0一个文件里。

archive作为文件系统层暴露给外界。所以所有的fs shell命令都能在archive上运行,但是要使用不同的URI。Hadoop Archives的URI是:


har://scheme-hostname:port/archivepath/fileinarchive  


scheme-hostname格式为hdfs-域名:端口,如果没有提供scheme-hostname,它会使用默认的文件系统。这种情况下URI是这种形式:


har:///archivepath/fileinarchive  


如果用har uri去访问的话,索引、标识等文件就会隐藏起来,只显示创建档案之前的原文件:


如何解压Archive

按顺序解压存档(串行):

Hadoop fs -cp har:///user/zoo/foo.har/dir1  hdfs:/user/zoo/newdir

要并行解压存档,请使用DistCp:

hadoop distcp har:///user/zoo/foo.har/dir1  hdfs:/user/zoo/newdir

Archive注意事项

  1. Hadoop archives是特殊的档案格式。一个Hadoop archive对应一个文件系统目录。Hadoop archive的扩展名是*.har;

  2. 创建archives本质是运行一个Map/Reduce任务,所以应该在Hadoop集群上运行创建档案的命令;

  3. 创建archive文件要消耗和原文件一样多的硬盘空间;

  4. archive文件不支持压缩,尽管archive文件看起来像已经被压缩过;

  5. archive文件一旦创建就无法改变,要修改的话,需要创建新的archive文件。事实上,一般不会再对存档后的文件进行修改,因为它们是定期存档的,比如每周或每日;

  6. 当创建archive时,源文件不会被更改或删除;

HDFS元数据管理机制

元数据管理概述

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提供文件存储服务的能力。

元数据目录相关文件

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


在这里要注意两个概念,一个是文件系统,此时的文件系统在物理上还不存在;二就是此处的格式化并不是指传统意义上的本地磁盘格式化,而是一些清除与准备工作。


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

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

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

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

VERSION

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,则会自动生成一个唯一的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最后的尾数。

Fsimage & edits

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

Fsimage、Edits

概述

fsimage文件其实是Hadoop文件系统元数据的一个永久性的检查点,其中包含Hadoop文件系统中的所有目录和文件idnode的序列化信息;

fsimage包含Hadoop文件系统中的所有目录和文件idnode的序列化信息;对于文件来说,包含的信息有修改时间、访问时间、块大小和组成一个文件块信息等;而对于目录来说,包含的信息主要有修改时间、访问控制权限等信息。

edits文件存放的是Hadoop文件系统的所有更新操作的路径,文件系统客户端执行的所以写操作首先会被记录到edits文件中。

NameNode起来之后,HDFS中的更新操作会重新写到edits文件中,因为fsimage文件一般都很大(GB级别的很常见),如果所有的更新操作都往fsimage文件中添加,这样会导致系统运行的十分缓慢,但是如果往edits文件里面写就不会这样,每次执行写操作之后,且在向客户端发送成功代码之前,edits文件都需要同步更新。如果一个文件比较大,使得写操作需要向多台机器进行操作,只有当所有的写操作都执行完成之后,写操作才会返回成功,这样的好处是任何的操作都不会因为机器的故障而导致元数据的不同步。

内容查看

fsimage、edits两个文件中的内容使用普通文本编辑器是无法直接查看的,幸运的是hadoop为此准备了专门的工具用于查看文件的内容,这些工具分别为oev和oiv,可以使用hdfs调用执行。

oev是offline edits viewer(离线edits查看器)的缩写,该工具只操作文件因而并不需要hadoop集群处于运行状态。

-i,--inputFile <arg>  

-o,--outputFile <arg>  Name of output file.

在输出文件中,每个RECORD记录了一次操作,示例如下:

oiv是offline image viewer的缩写,用于将fsimage文件的内容转储到指定文件中以便于阅读,该工具还提供了只读的WebHDFS API以允许离线分析和检查hadoop集群的命名空间。oiv在处理非常大的fsimage文件时是相当快的,如果该工具不能够处理fsimage,它会直接退出。该工具不具备向后兼容性,比如使用hadoop-2.4版本的oiv不能处理hadoop-2.3版本的fsimage,只能使用hadoop-2.3版本的oiv。同oev一样,就像它的名称所提示的(offline),oiv也不需要hadoop集群处于运行状态。

-i,--inputFile <arg>  

-o,--outputFile <arg>  Name of output file.

在输出文件中,每个RECORD记录了一次操作,示例如下:


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文件中。


Checkpoint

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


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进行工作,一直这样循环操作。

Checkpoint触发条件

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




两次连续的checkpoint之间的时间间隔。默认1小时


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


HDFS安全模式

安全模式概述

安全模式是HDFS所处的一种特殊状态,在这种状态下,文件系统只接受读数据请求,而不接受删除、修改等变更请求,是一种保护机制,用于保证集群中的数据块的安全性。

在NameNode主节点启动时,HDFS首先进入安全模式,集群会开始检查数据块的完整性。DataNode在启动的时候会向namenode汇报可用的block信息,当整个系统达到安全标准时,HDFS自动离开安全模式。

假设我们设置的副本数(即参数dfs.replication)是5,那么在Datanode上就应该有5个副本存在,假设只存在3个副本,那么比例就是3/5=0.6。在配置文件hdfs-default.xml中定义了一个最小的副本的副本率(即参数dfs.namenode.safemode.threshold-pct)0.999。

我们的副本率0.6明显小于0.99,因此系统会自动的复制副本到其他的DataNode,使得副本率不小于0.999.如果系统中有8个副本,超过我们设定的5个副本,那么系统也会删除多余的3个副本。

如果HDFS处于安全模式下,不允许HDFS客户端进行任何修改文件的操作,包括上传文件,删除文件,重命名,创建文件夹,修改副本数等操作。

安全模式配置

与安全模式相关主要配置在hdfs-site.xml文件中,主要有下面几个属性:

dfs.namenode.replication.min: 每个数据块最小副本数量,默认为1. 在上传文件时,达到最小副本数,就认为上传是成功的。

dfs.namenode.safemode.threshold-pct: 达到最小副本数的数据块的百分比。默认为0.999f。当小于这个比例,那就将系统切换成安全模式,对数据块进行复制;当大于该比例时,就离开安全模式,说明系统有足够的数据块副本数,可以对外提供服务。小于等于0意味不进入安全模式,大于1意味一直处于安全模式。

dfs.namenode.safemode.min.datanodes: 离开安全模式的最小可用datanode数量要求,默认为0.也就是即使所有datanode都不可用,仍然可以离开安全模式。

dfs.namenode.safemode.extension: 当集群可用block比例,可用datanode都达到要求之后,如果在extension配置的时间段之后依然能满足要求,此时集群才离开安全模式。单位为毫秒,默认为30000.也就是当满足条件并且能够维持30秒之后,离开安全模式。 这个配置主要是对集群稳定程度做进一步的确认。避免达到要求后马上又不符合安全标准。

总结一下,要离开安全模式,需要满足以下条件:

1)达到副本数量要求的block比例满足要求;

2)可用的datanode节点数满足配置的数量要求;

3) 1、2 两个条件满足后维持的时间达到配置的要求

安全模式命令

手动进入安全模式

手动进入安全模式对于集群维护或者升级的时候非常有用,因为这时候HDFS上的数据是只读的。手动退出安全模式可以用下面命令:

如果你想获取到集群是否处于安全模式,可以用下面的命令获取:


大数据离线阶段-03的评论 (共 条)

分享到微博请遵守国家法律