深入理解HDFS:最强辅助SecondaryNameNode

前言

现在业内使用的大多数分布式框架都是主从结构,HDFS也不例外。在HDFS框架中,我们可以理解NameNode是主,DataNode为从,但是HDFS框架并非只有这两个组件,今天我们就来聊一聊HDFS中的最强辅助——SecondaryNameNode。

NameNode的工作

在了解SecondaryNameNode之前,我们先来看下NameNode是做什么的。在一个文件系统中,有一个元数据的概念,关于一个文件的路径/名称/大小/修改日期等描述信息,我们称之为这个文件的元信息。在windows中我们右键文件选择属性,看到的就是元数据。

文件系统中,为了便于管理存储介质上的,给每个目录、目录中的文件、子目录都起了名字,这样形成的层级结构,称之为命名空间。因为同一个目录中不能有同名的文件或目录,所以在一个命名空间中,通过目录+文件名称的方式能够唯一的定位一个文件。而这些数据也都属于元数据的一种。

在HDFS中,命名空间就存储在NameNode的内存中。另外还使用一个称为EditLog的事务日志来永久记录文件系统元数据发生的所有更改。熟悉mysql的朋友,可以参考一下binlog。例如,我们在HDFS中创建一个新文件会导致NameNode在EditLog中插入一条记录来表明这一点。同样,更改文件的操作也将被记录到EditLog中。NameNode将EditLog保存在本地主机的磁盘上,如果NameNode宕机重启后,内存中的元数据信息丢失,也可以通过逐条读取EditLog记录到内存中来恢复元数据。虽然NameNode使用EditLog解决了内存中元数据易丢失的问题。但是EditLog会随着时间变得越来越大,重启后恢复所需要的时间也会越来越长。为了避免这种情况,HDFS引入了为检查点机制(checkpoint)。NameNode定期将内存中的命名空间镜像写到磁盘中名为fsimage的文件中,待到恢复时只需将最近的检查点的fsimage文件读取到内存中,再执行这个检查点之后的EditLog即可恢复命名空间数据。

最强辅助SecondaryNameNode

尽管我们有了EditLog和检查点机制,但是当HDFS数据量大的时候,两个检查点之间的数据依然会非常大。NameNode重启后恢复期间,HDFS的服务是不可用的,这使得我们不得不再次寻求更快的恢复速度,所以我们有了SecondaryNameNode来辅助NameNode。

首先,创建检查点checkpoint的两大条件:

  • SecondaryNameNode每隔1小时创建一个检查点
  • Secondary NameNode每1分钟检查一次,从上一检查点开始,edits日志文件中是否包括100万个事务,也会创建检查点

当满足创建检查点的条件时,SecondaryNameNode首先请求原NameNode进行EditLog的滚动,这样新的编辑操作就能够进入新的文件中;再通过HTTP GET方式读取NameNode中的fsimage及EditLog;然后,SecondaryNameNode读取fsimage到内存中,然后执行EditLog中的每个操作,并创建一个新的统一的fsimage文件;再通过HTTP PUT方式将新的fsimage发送到原NameNode;随后NameNode用新的fsimage替换旧的fsimage,同时系统会更新fsimage文件到记录检查点的时间。这个过程结束后,NameNode就有了最新的fsimage文件和更小的edits文件。因为合并操作需要占用大量的CPU时间,并需要占用与原命名空间一样甚至更多的内存,来执行合并操作,所以将这个操作放到SecondaryNameNode而不是直接在NameNode上完成。

总结

SecondaryNameNode是为了让NameNode更快处理fsimage与EditLog的合并而诞生的。为了完成这个操作,SecondaryNameNode往往拥有和NameNode同样的性能。因此称它为最强辅助也不足为过啦。


关注 零一大数据,获取更多技术干货

HDFS核心概念——Block

什么是Block?

物理磁盘中有块的概念,磁盘的物理Block是磁盘操作最小的单元,读写操作均以Block为最小单元,一般为512 Byte。文件系统在物理Block之上抽象了另一层概念,文件系统Block物理磁盘Block的整数倍。通常为几KB。Hadoop提供的df、fsck这类运维工具都是在文件系统的Block级别上进行操作。

HDFS的Block块比一般单机文件系统大得多,默认为128M。HDFS的文件被拆分成block-sized的chunk,chunk作为独立单元存储。比Block小的文件不会占用整个Block,只会占据实际大小。例如, 如果一个文件大小为1M,则在HDFS中只会占用1M的空间,而不是128M。

为什么HDFS的Block这么大?

HDFS读取文件时,需要定位Block的位置,如果Block设置得太小,就会导致Block的数量非常的多,在定位所有Block的时候就会非常耗时。假设定位到Block所需的时间为10ms,磁盘传输速度为100M/s。如果要将定位到Block所用时间占传输时间的比例控制1%,则Block大小需要约100M。但是如果Block设置过大,在MapReduce任务中,Map或者Reduce任务的个数 如果小于集群机器数量,会使得作业运行效率很低。HDFS将Block大小设置为128MB,是为了最小化查找(seek)时间,控制定位文件与传输文件所用的时间比例。

PS:你也可以自己根据业务情况设置

使用Block抽象有什么好处?

使用Block拆分,可以使单个文件大小超过磁盘大小,使构成文件的Block分布在整个集群。lock的抽象也简化了存储系统,对于Block,我们无需关注其权限,所有者等内容,因为这些内容都在文件级别上进行控制的。
Block作为容错和高可用机制中的副本单元,即以Block为单位进行复制。


Block的复制

我们在文章初识HDFS:Hadoop分布式文件系统中提到过——HDFS是运行在廉价硬件上的分布式文件系统,并且硬件故障是不可避免的。

如下图的存储方式,假如上图中任意一台DataNode宕机,这个文件将无法完整读取。

为了解决这个问题,HDFS引入了Block副本的概念。即一个Block在不同的DataNode中保存多份,这样就算其中一个节点宕机了,其他节点中的Block副本也能保证数据的完整可读性。如下图:

机架感知策略

机架感知是HDFS为了应对整个机架(Rack)断电或者断网时服务不受影响而采取的一种Block存储策略。

Block副本的存储策略是:

  1. 如果本地机器是DataNode节点,那么第一个Block副本存储在本地机器上,否则将在本机器同机架中随机选取一台DataNode机器存储;
  2. 第二个Block副本会存储在另外一个机架(此处称为Rack1)的某个DataNode节点上;
  3. 第三个Block副本会存储在Rack1机架的另一个DataNode节点上。
  4. 如果你设置的Block副本数超过3个,那其余的副本将在保证每个机架的副本不超上限((副本数-2)/机架数+2)的情况下,随机分布在集群中。

第二个Block副本存储在不同的机架中解决了整机架断电或断网的隐患;而第三个副本存储在与第二个副本同机架的节点上,是为了减少再次跨机架传送所带来的时间成本。

总结

Block是HDFS为了跨机器存储大文件而抽象出来的概念,它使得存储超大文件成为了可能。副本机制保证了数据的安全性。Hadoop生态中,大部分计算程序都是以Block为基本单位进行运算的,所以Block在HDFS是非常重要的概念。

初识HDFS:Hadoop分布式文件系统

HDFS是什么?

​HDFS是Hadoop中的一个存储子模块

HDFS (全称Hadoop Distributed File System),即hadoop的分布式文件系统

File System文件系统:操作系统中负责管理和存储文件信息的软件;具体地说,它负责为用户创建文件,存入、读出、修改、转储、删除文件等

当数据集大小超出一台计算机的存储能力时,就有必要将它拆分成若干部分,然后分散到不同的计算机中存储。管理网络中跨多台计算机存储的文件系统称之为分布式文件系统(distributed filesystem)。

Hadoop分布式文件系统(HDFS)是一种旨在商品硬件上运行的分布式文件系统。它与现有的分布式文件系统有许多相似之处。但是,与其他分布式文件系统的区别很明显。HDFS具有高度的容错能力,旨在部署在低成本硬件上。HDFS提供对应用程序数据的高吞吐量访问,并且适用于具有大数据集的应用程序。HDFS放宽了一些POSIX要求,以实现对文件系统数据的流式访问。HDFS最初是作为Apache Nutch Web搜索引擎项目的基础结构而构建的。HDFS是Apache Hadoop Core项目的一部分。


HDFS的设想和目标

  • 硬件故障:硬件故障是正常现象,而非例外。HDFS实例可能包含数百或数千个服务器计算机,每个服务器计算机都存储文件系统数据的一部分。存在大量组件并且每个组件的故障概率都很低的事实意味着HDFS的某些组件始终无法运行。因此,检测故障并从故障中快速自动恢复是HDFS的核心体系结构目标。
  • 流数据访问:在HDFS上运行的应用程序需要对其数据集进行流式访问。它们不是通常在通用文件系统上运行的通用应用程序。HDFS设计用于批处理,而不是用户交互使用。重点在于数据访问的高吞吐量,而不是数据访问的低等待时间。POSIX提出了许多针对HDFS的应用程序不需要的硬性要求。在一些关键领域中,POSIX语义已经被交易以提高数据吞吐率。
  • 大数据集:在HDFS上运行的应用程序具有大量数据集。HDFS中的典型文件大小为GB到TB。因此,HDFS已调整为支持大文件。它应提供较高的聚合数据带宽,并可以扩展到单个群集中的数百个节点。它应该在单个实例中支持数千万个文件。
  • 简单一致性模型:HDFS应用程序需要文件一次写入多次读取访问模型。一旦创建,写入和关闭文件,除了追加和截断外,无需更改。支持将内容追加到文件末尾,但不能在任意点更新。该假设简化了数据一致性问题并实现了高吞吐量数据访问。MapReduce应用程序或Web爬网程序应用程序非常适合此模型。
  • “移动计算比移动数据便宜”:如果应用程序所请求的计算在其所操作的数据附近执行,则效率会更高。当数据集的大小很大时,尤其如此。这样可以最大程度地减少网络拥塞,并提高系统的整体吞吐量。假设通常是将计算迁移到更靠近数据的位置,而不是将数据移动到应用程序正在运行的位置。HDFS为应用程序提供了接口,使它们自己更靠近数据所在的位置。
  • 跨异构硬件和软件平台的可移植性:HDFS的设计目的是可以轻松地从一个平台移植到另一个平台。这有助于将HDFS广泛用作大量应用程序的首选平台。

HDFS的局限性

HDFS从设计之初就有非常明确的应用场景,适用什么类型的应用,不适合什么类型的应用,有一个相对明确的设计指导。有些场景就不适合使用HDFS来存储数据,比如:

  • 低延时的数据访问:对延时要求在毫秒级别的应用,不适合采用HDFS。HDFS是为高吞吐数据传输设计的,因此可能牺牲延时HBase更适合低延时的数据访问。
  • 大量小文件:文件的元数据(如目录结构,文件block的节点列表,block-node mapping)保存在NameNode的内存中, 整个文件系统的文件数量会受限于NameNode的内存大小。经验而言,一个文件/目录/文件块一般占有150字节的元数据内存空间。如果有100万个文件,每个文件占用1个文件块,则需要大约300M的内存。因此十亿级别的文件数量在现有商用机器上难以支持。
  • 多方读写,需要任意的文件修改:HDFS采用追加(append-only)的方式写入数据。不支持文件任意offset的修改。不支持多个写入器(writer)。

NameNode和DataNodes

HDFS具有主/从体系结构。HDFS群集由单个NameNode和管理文件系统名称空间并控制客户端对文件的访问的主服务器组成。此外,还有许多数据节点,通常是集群中每个节点一个,用于管理与它们所运行的节点相连的存储。HDFS公开了文件系统名称空间,并允许用户数据存储在文件中。在内部,文件被分成一个或多个块,这些块存储在一组DataNode中。NameNode执行文件系统名称空间操作,例如打开,关闭和重命名文件和目录。它还确定块到DataNode的映射。数据节点负责处理来自文件系统客户端的读写请求。DataNode还会执行块创建,删除。

NameNode和DataNode是旨在在商用机器上运行的软件。这些机器通常运行GNU / Linux操作系统(OS)。HDFS是使用Java语言构建的;任何支持Java的机器都可以运行NameNode或DataNode软件。使用高度可移植的Java语言意味着HDFS可以部署在各种各样的机器上。典型的部署有专用的计算机,该计算机仅运行NameNode软件。集群中的每台其他计算机都运行DataNode软件的一个实例。该架构并不排除在同一台机器上运行多个DataNode,而是在实际部署中很少出现这种情况。

群集中单个NameNode的存在极大地简化了系统的体系结构。NameNode是所有HDFS元数据的仲裁器和存储库。该系统的设计方式使用户数据永远不会流过NameNode。


文件系统命名空间

HDFS支持传统的分层文件组织。用户或应用程序可以创建目录并将文件存储在这些目录中。文件系统名称空间层次结构与大多数其他现有文件系统相似。可以创建和删除文件,将文件从一个目录移动到另一个目录或重命名文件。HDFS支持用户配额和访问权限。HDFS不支持硬链接或软链接。但是,HDFS体系结构并不排除实现这些功能。

尽管HDFS遵循FileSystem的命名约定,但某些路径和名称(例如/.reserved和.snapshot)被保留。功能,如透明加密和快照使用预约路径。

NameNode维护文件系统名称空间。对文件系统名称空间或其属性的任何更改均由NameNode记录。应用程序可以指定应由HDFS维护的文件副本的数量。文件的副本数称为该文件的复制因子。此信息由NameNode存储。


数据复制

HDFS旨在在大型群集中的计算机之间可靠地存储非常大的文件。它将每个文件存储为一系列块。复制文件的块是为了容错。块大小和复制因子是每个文件可配置的。

文件中除最后一个块外的所有块都具有相同的大小,而在添加了对可变长度块的支持后,用户可以在不填充最后一个块的情况下开始新的块,而不用配置的块大小。

应用程序可以指定文件的副本数。复制因子可以在文件创建时指定,以后可以更改。HDFS中的文件只能写入一次(追加和截断除外),并且在任何时候都只能具有一个写入器。

NameNode做出有关块复制的所有决定。它定期从群集中的每个DataNode接收心跳信号和Blockreport。接收到心跳信号表示DataNode正常运行。Blockreport包含DataNode上所有块的列表。

总结

HDFS使得每一台计算节点都具有了数据访问能力,在Hadoop生态中有着非常重要的作用。在以Spark为核心的新一代大数据框架中,HDFS依旧是承担着数据存储的重要角色。


微信关注 零一大数据,获取更多技术干货

为什么会有第一代大数据技术Hadoop和第二代大数据技术Spark?

hadoop开启了人们大规模普及化使用大数据的历史阶段。

但hadoop在计算方面有问题,所以更多用spark来做大数据计算。

大数据要解决的三大核心问题:存储、多种计算范式、处理速度

1.存储:用户使用数据时并不关心数据是存储在多台机器上的。hadoop的hdfs很好地解决了大数据的存储问题。

2.有多种计算方式:以SQL为核心的数据仓库技术、流处理技术、机器学习、图计算。Spark又集成了R语言。R语言以前都是在单机上运行,现在可以在分布式系统上运行。最理想的是安装一套系统就可以解决所有问题。

3.处理速度:大数据时代处理速度更为重要。

※  大数据和数据规模没有关系。一个计算是否是大数据,主要看1.对数据价值提取的程度,比如有100M的数据,但需要对这100m数据进行复杂的pagerank或机器学习,这时就可以称为大数据,或者对数据处理速度要求特别高。当然1TB或1PB的数据也可以称为大数据。所以规模不是问题,主要是我们要从数据中提取什么样的价值以及以什么样的速度提取。

作为第一代技术hadoop很好地解决了存储的问题,但没有很好地解决多种计算范式和处理速度的问题。

spark很好地解决了多种计算范式和处理速度问题。安装spark后相当于安装了机器学习、流处理、图计算和R语言。

hadoop+spark=A Winning Combination

hadoop最重要的是hdfs。

hadoop又推出了yarn这个资源管理框架。

MapReduce是道格根据google的三篇论文创造出来的计算框架,把分布式计算分为map和reduce阶段,mapper把很大的问题分解成若干个小问题,reducer把小问题计算结果进行reduce。但mapreduce每次计算都是基于磁盘的,即每次计算都要读写磁盘,导致在两种情况下不适用:1.对数据多步骤迭代的。如对数据进行1万次迭代,mapreduce就需要读写1万次磁盘,这是没有必要而且效率低,2.效率上要求计算在分/秒级别出结果,mapreduce也不能胜任。

Spark用一套软件同时解决了流处理、机器学习、图试算问题,而且功能更强大,速度更快。

Spark Shell上不仅可以直接写SQL也可以写各种业务逻辑直接操作spark大数据集群。这是非常方便的。

Spark本身已经非常完善了。现在又发布了1.5.1。

hadoop最新版本推荐使用2.6.0。

spark在多步骤迭代时可以比hadoop快100多倍,spark还可以直接操作hadoop中的所有类型的数据、NoSQL等。

hadoop要解决多种范式就需要安装storm/impala/Giraph等,需要多个团队维护。而且多个技术团队间的交互不好。而spark一站就可以解决所有问题。

spark代码非常简练,GraphX只有两三千行代码,Giraph就要七八万行。

SparkSQL也只有三四千行,对于技术人员来说这就是空前的机遇,因为一切问题都来自于源码,一切问题的答案也来自于源码。这对于取得技术的制高点是至关重要的。