Hadoop 入门笔记 十四 : HDFS架构原理
一. HDFS 架构剖析
1. HDFS 整体概述
HDFS是Hadoop Distribute File System 的简称,意为:Hadoop分布式文件系统。是Hadoop核心组件之一,作为大数据生态圈最底层的分布式存储服务而存在。HDFS解决的问题就是大数据如何存储,它是横跨在多台计算机上的文件存储系统并且具有高度的容错能力。
HDFS集群遵循主从架构。每个群集包括一个主节点和多个从节点。在内部,文件分为一个或多个块,每个块根据复制因子存储在不同的从节点计算机上。主节点存储和管理文件系统名称空间,即有关文件块的信息,例如块位置,权限等。从节点存储文件的数据块。主从各司其职,互相配合,共同对外提供分布式文件存储服务。当然内部细节对于用户来说是透明的。
文章图片
2.角色介绍
1. 概述
HDFS遵循主从架构。每个群集包括一个主节点和多个从节点。其中:
NameNode是主节点,负责存储和管理文件系统元数据信息,包括namespace目录结构、文件块位置信息等;DataNode是从节点,负责存储文件具体的数据块。
两种角色各司其职,共同协调完成分布式的文件存储服务。
SecondaryNameNode是主角色的辅助角色,帮助主角色进行元数据的合并。
文章图片
2. Namenode
NameNode是Hadoop分布式文件系统的核心,架构中的主角色。它维护和管理文件系统元数据,包括名称空间目录树结构、文件和块的位置信息、访问权限等信息。基于此,NameNode成为了访问HDFS的唯一入口。
内部通过内存和磁盘两种方式管理元数据。其中磁盘上的元数据文件包括Fsimage内存元数据镜像文件和edits log(Journal)编辑日志。
文章图片
3. Datanode
DataNode是Hadoop HDFS中的从角色,负责具体的数据块存储。DataNode的数量决定了HDFS集群的整体数据存储能力。通过和NameNode配合维护着数据块。
文章图片
4. Secondarynamenode
除了DataNode和NameNode之外,还有另一个守护进程,它称为secondary NameNode。充当NameNode的辅助节点,但不能替代NameNode。
当NameNode启动时,NameNode合并Fsimage和edits log文件以还原当前文件系统名称空间。如果edits log过大不利于加载,SecondaryNameNode就辅助NameNode从NameNode下载Fsimage文件和edits log文件进行合并。
3. HDFS重要特性
1. 主从架构
HDFS采用master/slave架构。一般一个HDFS集群是有一个Namenode和一定数目的Datanode组成。Namenode是HDFS主节点,Datanode是HDFS从节点,两种角色各司其职,共同协调完成分布式的文件存储服务。
2. 分块机制
HDFS中的文件在物理上是分块存储(block)的,块的大小可以通过配置参数来规定,参数位于hdfs-default.xml中:dfs.blocksize。默认大小是128M(134217728)。
3. 副本机制
为了容错,文件的所有block都会有副本。每个文件的block大小(dfs.blocksize)和副本系数(dfs.replication)都是可配置的。应用程序可以指定某个文件的副本数目。副本系数可以在文件创建的时候指定,也可以在之后通过命令改变。
默认dfs.replication的值是3,也就是会额外再复制2份,连同本身总共3份副本。
4. NameSpace
HDFS支持传统的层次型文件组织结构。用户可以创建目录,然后将文件保存在这些目录里。文件系统名字空间的层次结构和大多数现有的文件系统类似:用户可以创建、删除、移动或重命名文件。
Namenode负责维护文件系统的namespace名称空间,任何对文件系统名称空间或属性的修改都将被Namenode记录下来。
HDFS会给客户端提供一个统一的抽象目录树,客户端通过路径来访问文件,形如:hdfs://namenode:port/dir-a/dir-b/dir-c/file.data。
5. 元数据管理
在HDFS中,Namenode管理的元数据具有两种类型:
- 文件自身属性信息
文件名称、权限,修改时间,文件大小,复制因子,数据块大小。 - 文件块位置映射信息
记录文件块和DataNode之间的映射信息,即哪个块位于哪个节点上
文章图片
2. HDFS Web Interfaces 1. Web Interfaces介绍
除了命令行界面之外,Hadoop还为HDFS提供了Web用户界面。用户可以通过Web界面操作文件系统并且获取和HDFS相关的状态属性信息。
HDFS Web地址是http://nn_host:port/,默认端口号9870。
2. 模块功能模块
- Overview
Overview是总揽模块,默认的主页面。展示了HDFS一些最核心的信息。
文章图片
- Summary
文章图片
- NameNode Journal Status
文章图片
- NameNode Storage
文章图片
- DFS Storage Types
文章图片
- Datanodes
Datanodes模块主要记录了HDFS集群中各个DataNode的相关状态信息
文章图片
- Datanode Volume Failures
此模块记录了DataNode卷故障信息。
文章图片
- Snapshot
Snapshot模块记录HDFS文件系统的快照相关信息,包括哪些文件夹创建了快照和总共有哪些快照。
文章图片
- Satartup progress
Startup Progress模块记录了HDFS集群启动的过程信息,执行步骤和每一步所做的事和用时。
文章图片
- Utilities
Utilities模块算是用户使用最多的模块了,里面包括了文件浏览、日志查看、配置信息查看等核心功能。
文章图片
- Browse the file system
文章图片
- Logs、Log Level
文章图片
文章图片
- Configruation
文章图片
1. 写数据流程
文章图片
1. Pipeline管道、ACK应答响应 Pipeline,中文翻译为管道。这是HDFS在上传文件写数据过程中采用的一种数据传输方式。客户端将数据块写入第一个数据节点,第一个数据节点保存数据之后再将块复制到第二个数据节点,后者保存后将其复制到第三个数据节点。通俗描述pipeline的过程就是:Client->A->B->C
为什么datanode之间采用pipeline线性传输,而不是一次给三个datanode拓扑式传输呢?因为数据以管道的方式,顺序的沿着一个方向传输,这样能够充分利用每个机器的带宽,避免网络瓶颈和高延迟时的连接,最小化推送所有数据的延时。在线性推送模式下,每台机器所有的出口宽带都用于以最快的速度传输数据,而不是在多个接受者之间分配宽带。
ACK (Acknowledge character)即是确认字符,在数据通信中,接收方发给发送方的一种传输类控制字符。表示发来的数据已确认接收无误。在pipeline管道传输数据的过程中,传输的反方向会进行ACK校验,确保数据传输安全。
文章图片
2. 具体流程
- HDFS客户端通过对DistributedFileSystem 对象调用create()请求创建文件
2. DistributedFileSystem对namenode进行RPC调用,请求上传文件。namenode执行各种检查判断:目标文件是否存在、父目录是否存在、客户端是否具有创建该文件的权限。检查通过,namenode就会为创建新文件记录一条记录。否则,文件创建失败并向客户端抛出IOException。 - DistributedFileSystem为客户端返回FSDataOutputStream输出流对象。由此客户端可以开始写入数据。FSDataOutputStream是一个包装类,所包装的是DFSOutputStream。
- 在客户端写入数据时,DFSOutputStream将它分成一个个数据包(packet 默认64kb),并写入一个称之为数据队列(data queue)的内部队列。DFSOutputStream有一个内部类做DataStreamer,用于请求NameNode挑选出适合存储数据副本的一组DataNode。这一组DataNode采用pipeline机制做数据的发送。默认是3副本存储。
- pipeline传递数据给DataNode, DataStreamer将数据包流式传输到pipeline的第一个datanode,该DataNode存储数据包并将它发送到pipeline的第二个DataNode。同样,第二个DataNode存储数据包并且发送给第三个(也是最后一个)DataNode。
- DFSOutputStream也维护着一个内部数据包队列来等待DataNode的收到确认回执,称之为确认队列(ack queue),收到pipeline中所有DataNode确认信息后,该数据包才会从确认队列删除。
- 客户端完成数据写入后,将在流上调用close()方法关闭。该操作将剩余的所有数据包写入DataNode pipeline,并在联系到NameNode告知其文件写入完成之前,等待确认。
- 因为namenode已经知道文件由哪些块组成(DataStream请求分配数据块),因此它仅需等待最小复制块即可成功返回。
- 数据块最小复制是由参数dfs.namenode.replication.min指定,默认是1
第一块副本:优先客户端本地,否则随机
第二块副本:不同于第一块副本的不同机架。
第三块副本:第二块副本相同机架不同机器。
2. 读数据流程
文章图片
- 客户端通过调用DistributedFileSystem对象上的open() 来打开希望读取的文件
- DistributedFileSystem使用RPC调用namenode来确定文件中前几个块的块位置。对于每个块,namenode返回具有该块副本的datanode的地址,并且datanode根据块与客户端的距离进行排序。注意此距离指的是网络拓扑中的距离。比如客户端的本身就是一个DataNode,那么从本地读取数据明显比跨网络读取数据效率要高。
- DistributedFileSystem将FSDataInputStream(支持文件seek定位读的输入流)返回到客户端以供其读取数据。FSDataInputStream类转而封装为DFSInputStream类,DFSInputStream管理着datanode和namenode之间的IO。
- 客户端在流上调用read()方法。然后,已存储着文件前几个块DataNode地址的DFSInputStream随即连接到文件中第一个块的最近的DataNode节点。通过对数据流反复调用read()方法,可以将数据从DataNode传输到客户端。
- 当该块快要读取结束时,DFSInputStream将关闭与该DataNode的连接,然后寻找下一个块的最佳datanode。这些操作对用户来说是透明的。所以用户感觉起来它一直在读取一个连续的流
- 客户端从流中读取数据时,块是按照打开DFSInputStream与DataNode新建连接的顺序读取的。它也会根据需要询问NameNode来检索下一批数据块的DataNode位置信息。一旦客户端完成读取,就对FSDataInputStream调用close()方法
- 如果DFSInputStream与DataNode通信时遇到错误,它将尝试该块的下一个最接近的DataNode读取数据。并将记住发生故障的DataNode,保证以后不会反复读取该DataNode后续的块。此外,DFSInputStream也会通过校验和(checksum)确认从DataNode发来的数据是否完整。如果发现有损坏的块,DFSInputStream会尝试从其他DataNode读取该块的副本,也会将被损坏的块报告给namenode
1. Namenode 职责
- NameNode是HDFS的核心,集群的主角色,被称为Master。
- NameNode仅存储管理HDFS的元数据:文件系统namespace操作维护目录树,文件和块的位置信息。
- NameNode不存储实际数据或数据集。数据本身实际存储在DataNodes中
- NameNode知道HDFS中任何给定文件的块列表及其位置。使用此信息NameNode知道如何从块中构建文件
- NameNode并不持久化存储每个文件中各个块所在的DataNode的位置信息,这些信息会在系统启动时从DataNode汇报中重建
- NameNode对于HDFS至关重要,当NameNode关闭时,HDFS / Hadoop集群无法访问
- NameNode是Hadoop集群中的单点故障
- NameNode所在机器通常会配置有大量内存(RAM)
- DataNode负责将实际数据存储在HDFS中。是集群的从角色,被称为Slave。
- DataNode启动时,它将自己发布到NameNode并汇报自己负责持有的块列表
- 根据NameNode的指令,执行块的创建、复制、删除操作
- DataNode会定期(dfs.heartbeat.interval配置项配置,默认是3秒)向NameNode发送心跳,如果NameNode长时间没有接受到DataNode发送的心跳, NameNode就会认为该DataNode失效
- DataNode会定期向NameNode进行自己持有的数据块信息汇报,汇报时间间隔取参数dfs.blockreport.intervalMsec,参数未配置的话默认为6小时
- DataNode所在机器通常配置有大量的硬盘空间。因为实际数据存储在DataNode中
元数据(Metadata),又称中介数据,为描述数据的数据(data about data),主要是描述数据属性(property)的信息,用来支持如指示存储位置、历史数据、资源查找、文件记录等功能。
在HDFS中,元数据主要指的是文件相关的元数据,由NameNode管理维护。从广义的角度来说,因为NameNode还需要管理众多DataNode节点,因此DataNode的位置和健康状态信息也属于元数据。
2. 元数据管理概述
在HDFS中,文件相关元数据具有两种类型:
1. 文件自身属性信息 文件名称、权限,修改时间,文件大小,复制因子,数据块大小。
文章图片
2. 文件块位置映射信息 记录文件块和DataNode之间的映射信息,即哪个块位于哪个节点上。
按存储形式分为内存元数据和磁盘元数据文件两种,分别存在内存和磁盘上。
文章图片
- 内存元数据
为了保证用户操作元数据交互高效,延迟低,NameNode把所有的元数据都存储在内存中,我们叫做内存元数据。内存中的元数据是最完整的,包括文件自身属性信息、文件块位置映射信息。但是内存的致命问题是,断点数据丢失,数据不会持久化。因此NameNode又辅佐了元数据文件来保证元数据的安全完整。 - 磁盘元数据
- fsimage 内存镜像文件
是内存元数据的一个持久化的检查点。但是fsimage中仅包含Hadoop文件系统中文件自身属性相关的元数据信息,但不包含文件块位置的信息。文件块位置信息只存储在内存中,时由datanode启动加入集群的时候,向namenode进行数据块的汇报得到的,并且后续间断指定时间进行数据块报告。持久化的动作是一种数据从内存到磁盘的IO过程。会对namenode正常服务造成一定的影响,不能频繁的进行持久化。 - Edits log编辑日志
- fsimage 内存镜像文件
- 加载元数据顺序
fsimage和edits文件都是经过序列化的,在NameNode启动的时候,它会将fsimage文件中的内容加载到内存中,之后再执行edits文件中的各项操作,使得内存中的元数据和实际的同步,存在内存中的元数据支持客户端的读操作,也是最完整的元数据。
当客户端对HDFS中的文件进行新增或者修改操作,操作记录首先被记入edits日志文件中,当客户端操作成功后,相应的元数据会更新到内存元数据中。因为fsimage文件一般都很大(GB级别的很常见),如果所有的更新操作都往fsimage文件中添加,这样会导致系统运行的十分缓慢。
HDFS这种设计实现着手于:一是内存中数据更新、查询快,极大缩短了操作响应时间;二是内存中元数据丢失风险颇高(断电等),因此辅佐元数据镜像文件(fsimage)+ 编辑日志文件(edits)的备份机制进行确保元数据的安全。
NameNode维护整个文件系统元数据。因此,元数据的准确管理,影响着HDFS提供文件存储服务的能力。
3. 元数据管理相关目录文件
1. 元数据存储目录在Hadoop的HDFS首次部署好配置文件之后,并不能马上启动使用,而是先要对文件系统进行格式化操作:hdfs namenode -format
在这里要注意两个概念,一个是format之前,HDFS在物理上还不存在;二就是此处的format并不是指传统意义上的本地磁盘格式化,而是一些清除与准备工作。其中就会创建元数据本地存储目录和一些初始化的元数据相关文件。
namenode元数据存储目录由参数:dfs.namenode.name.dir指定,格式化完成之后,将会在$dfs.namenode.name.dir/current目录下创建如下的文件:
文章图片
其中的dfs.namenode.name.dir是在hdfs-site.xml文件中配置的,默认值如下:
文章图片
dfs.namenode.name.dir属性可以配置多个目录,各个目录存储的文件结构和内容都完全一样,相当于备份,这样做的好处是当其中一个目录损坏了,也不会影响到hadoop的元数据,特别是当其中一个目录是NFS(网络文件系统Network File System,NFS)之上,即使你这台机器损坏了,元数据也得到保存。
- Version
文章图片
- namespaceID/clusterID/blockpoolID
这些都是HDFS集群的唯一标识符。标识符被用来防止DataNodes意外注册到另一个集群中的namenode上。这些标识在联邦(federation)部署中特别重要。联邦模式下,会有多个NameNode独立工作。每个的NameNode提供唯一的命名空间(namespaceID),并管理一组唯一的文件块池(blockpoolID)。clusterID将整个集群结合在一起作为单个逻辑单元,在集群中的所有节点上都是一样的。 - storageType
说明这个文件存储的是什么进程的数据结构信息,如果是DataNode,storageType=DATA_NODE。 - cTime
NameNode存储系统创建时间,首次格式化文件系统这个属性是0,当文件系统升级之后,该值会更新到升级之后的时间戳; - layoutVersion
HDFS元数据格式的版本。添加需要更改元数据格式的新功能时,请更改此数字。当前的HDFS软件使用比当前版本更新的布局版本时,需要进行HDFS升级
1. SNN职责概述
文章图片
NameNode职责是管理元数据信息,DataNode的职责是负责数据具体存储,那么SecondaryNameNode的作用是什么?对很多初学者来说是非常迷惑的。它为什么会出现在HDFS中。从它的名字上看,它给人的感觉就像是NameNode的备份。但它实际上却不是。
当HDFS集群运行一段事件后,就会出现下面一些问题:
- edits logs会变的很大,fsimage将会变得很旧;
- namenode重启会花费很长时间,因为有很多改动要合并到fsimage文件上
- 如果频繁进行fsimage持久化,又会影响NameNode正常服务,毕竟IO操作是一种内存到磁盘的耗精力操作
SecondaryNameNode就是来帮助解决上述问题的,它的职责是合并NameNode的edit logs到fsimage文件中。
2. SNN checkpoint机制- 概述
Checkpoint核心是把fsimage与edits log合并以生成新的fsimage的过程。此过程有两个好处:fsimage版本不断更新不会太旧、edits log文件不会太大。 - 流程
文章图片
- 当触发checkpoint操作条件时,SNN发生请求给NN滚动edits log。然后NN会生成一个新的编辑日志文件:edits new,便于记录后续操作记录。
- 同时SNN会将edits文件和fsimage复制到本地(使用HTTP GET方式)。
- SNN首先将fsimage载入到内存,然后一条一条地执行edits文件中的操作,使得内存中的fsimage不断更新,这个过程就是edits和fsimage文件合并。合并结束,SNN将内存中的数据dump生成一个新的fsimage文件。
- SNN将新生成的Fsimage new文件复制到NN节点。
- 至此刚好是一个轮回,等待下一次checkpoint触发SecondaryNameNode进行工作,一直这样循环操作。
- 触发机制
Checkpoint触发条件受两个参数控制,可以通过core-site.xml进行配置
dfs.namenode.checkpoint.period=3600//两次连续的checkpoint之间的时间间隔。默认1小时 dfs.namenode.checkpoint.txns=1000000 //最大没有执行checkpoint事务的数量,满足将强制执行紧急checkpoint,即使尚未达到检查点周期。默认100万事务数量。
从上面的描述我们可以看出,SecondaryNamenode根本就不是Namenode的一个热备,只是将fsimage和edits合并。
5. Namenode 元数据恢复
1. NameNode存储多目录namenode元数据存储目录由参数:dfs.namenode.name.dir指定。
dfs.namenode.name.dir属性可以配置多个目录,各个目录存储的文件结构和内容都完全一样,相当于备份, 这样做的好处是当其中一个目录损坏了,也不会影响到hadoop的元数据,特别是当其中一个目录是NFS(网络文件系统Network File System,NFS)之上,即使你这台机器损坏了,元数据也得到保存。
- namespaceID/clusterID/blockpoolID
如果NameNode中的fsimage真的出问题了,还是可以用SecondaryNamenode中的fsimage替换一下NameNode上的fsimage,虽然已经不是最新的fsimage,但是我们可以将损失减小到最少!
5 . HDFS 小文件解决方案
1. Hadoop Archive归档 HDFS并不擅长存储小文件,因为每个文件最少一个block,每个block的元数据都会在NameNode占用内存,如果存在大量的小文件,它们会吃掉NameNode节点的大量内存。
Hadoop Archives可以有效的处理以上问题,它可以把多个文件归档成为一个文件,归档成一个文件后还可以透明的访问每一个文件。
- 创建 Achive
Usage: hadoop archive -archiveName name -p *
其中-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。
hadoop archive -archiveName test.har -p /smallfile /outputdir
这样就会在/outputdir目录下创建一个名为test.har的存档文件。
注意:Archive归档是通过MapReduce程序完成的,需要启动YARN集群。
- 查看Archive
- 查看归档之后的样子
hadoop fs -ls /outputdir/test.har
- 查看归档之前的样子
此外,Archive还提供了自己的har uri访问协议。如果用har uri去访问的话,索引、标识等文件就会隐藏起来,只显示创建档案之前的原文件:
Hadoop Archives的URI是:
har://scheme-hostname:port/archivepath/fileinarchive
scheme-hostname格式为hdfs-域名:端口。
- 提取Archive
按顺序解压存档(串行):
hadoop fs -cp har:///user/zoo/foo.har/dir1hdfs:/user/zoo/newdir[root@node1 ~]# hadoop fs -mkdir /smallfile1 [root@node1 ~]# hadoop fs -cp har:///outputdir/test.har/* /smallfile1 [root@node1 ~]# hadoop fs -ls /smallfile1
要并行解压存档,请使用DistCp,对应大的归档文件可以提高效率:
- Archive使用注意事项
- Hadoop archives是特殊的档案格式。一个Hadoop archive对应一个文件系统目录。Hadoop archive的扩展名是*.har;
- 创建archives本质是运行一个Map/Reduce任务,所以应该在Hadoop集群上运行创建档案的命令;
- 创建archive文件要消耗和原文件一样多的硬盘空间;
- archive文件不支持压缩,尽管archive文件看起来像已经被压缩过;
- archive文件一旦创建就无法改变,要修改的话,需要创建新的archive文件。事实上,一般不会再对存档后的文件进行修改,因为它们是定期存档的,比如每周或每日;
- 当创建archive时,源文件不会被更改或删除;
- Sequence File介绍
Sequence File是Hadoop API提供的一种二进制文件支持。这种二进制文件直接将键值对序列化到文件中。
文章图片
- Sequence File优缺点
- 优点
- 二级制格式存储,比文本文件更紧凑。
- 支持不同级别压缩(基于Record或Block压缩)。
- 文件可以拆分和并行处理,适用于MapReduce。
- 局限性
- 二进制格式文件不方便查看
- 特定于hadoop,只有Java API可用于与之件进行交互。尚未提供多语言支持
- 优点
- Sequence File格式
Hadoop Sequence File 是一个由二进制键/值对组成的。根据压缩类型,有3种不同的Sequence File格式:未压缩格式、record压缩格式、block压缩格式。
Sequence File由一个header和一个或多个record组成。以上三种格式均使用相同的header结构,如下所示:
文章图片
前3个字节为SEQ,表示该文件是序列文件,后跟一个字节表示实际版本号(例如SEQ4或SEQ6)。Header中其他也包括key、value class名字、 压缩细节、metadata、Sync marker。Sync Marker同步标记,用于可以读取任意位置的数据。
- . 未压缩格式
每隔几个record(100字节左右)就有一个同步标记
文章图片
- . 基于record压缩格式
每隔几个record(100字节左右)就有一个同步标记。
文章图片
- . 基于block压缩格式
block指的是record block,可以理解为多个record记录组成的块。注意,这个block和HDFS中分块存储的block(128M)是不同的概念。
Block中包括:record条数、压缩的key长度、压缩的keys、压缩的value长度、压缩的values。每隔一个block就有一个同步标记。
block压缩比record压缩提供更好的压缩率。使用Sequence File时,通常首选块压缩。
文章图片
推荐阅读
- EffectiveObjective-C2.0|EffectiveObjective-C2.0 笔记 - 第二部分
- Android中的AES加密-下
- 【读书笔记】贝叶斯原理
- 【韩语学习】(韩语随堂笔记整理)
- 【Hadoop踩雷】Mac下安装Hadoop3以及Java版本问题
- 人性的弱点-笔记
- 读书笔记:博登海默法理学|读书笔记:博登海默法理学 —— 正义的探索(1)
- D034+3组苏曼+《写作这回事》读书笔记
- 《自我的追寻》读书笔记3
- 最有效的时间管理工具(赢效率手册和总结笔记)