Hadoop 基础知识---之HDFS篇

Hadoop基础知识

HDFS基础知识

HDFS简介

起源      

源于Google发布的GFS论文

HDFS是Hadoop DistributeFile System 的简称,是Hadoop的一个分布式文件系统。

设计目标

大文件存储:支持TB-PB级的数据量

高容错:运行在商业硬件上,而商业硬件并不可靠

高吞吐量:为大量数据访问的应用提供高吞吐量支持

适应场景:

大文件访问

流式数据访问

不适合的场景

存储大量小文件

随机读取,低延迟读取

 

HDFS设计目标

硬件错误是常态

副本冗余机制

流式数据访问

批量读而非随机读

关注吞吐量而非相应时间                    

流式数据特点是:像流水一样,不是一次过来而是一点一点“流”过来。而你流式数据也是一点一点处理。如果全部收到数据以后在处理,那么延迟会很大,而且在很多场合会消耗大量内存。

大规模数据集    

典型文件大小GB-TB级别

关注横向现行扩展

简单一致性模型

一次写,多次读

支持追加,不允许修改

 

HDFS的基本概念

数据块(block)

大文件会被分割成多个block进行存储,block大小默认为128MB。----小于一个块大小的文件不会占据整个块的空间                                                 

每一个block会在多个datanode上存储多份副本,默认是3份。

NameNode

记录文件系统的元数据------单一主元数据服务器,其中包括每个文件,文件位置以及这些文件及其所在的DataNode内的所有数据块的内存映射。

维护文件系统树及整棵树内所有的文件和目录                  

 

DataNode

存储和管理数据块

将信息上报给NameNode

HDFS的架构

采用Master/Slave主从架构 
NameNode

记录文件系统的元数据

服务器位置信息和副本数

DataNode                        

存储和管理数据库

将信息上报给NameNode

Client

HDFS 对外接口

从NameNode获取文件信息

连接DataNode读写文件      

                                   

NameNode的作用       

Namenode始终在内存中保存metadata(metadata里面保存的是元数据,比如整个文件系统的结构),用于处理“读请求”。但是我们把东西放在内存中,内存是易失的。

所以到有“写请求”到来时,namenode会首先写editlog到磁盘,成功返回后,才会修改内存,并且向客户端返回。

Hadoop会维护一个fsimage文件,也就是namenode中metadata的镜像,但是fsimage不会随时与namenode内存中的metadata保持一致,而是每隔一段时间通过合并editlog来更新内容。Secondary namenode就是用来更新fsimage的。

 

 

管理文件系统的命名空间     

文件系统元数据信息:所有目录和文件

记录命名空间的改动和本身属性的改动

命名空间镜像文件:fsimage

编辑日志文件:editLog

保持数据块的节点信息     

不持久化保存,重启系统是DataNode重建

协调客户端(client)对文件的访问

 

fsimage和EditLog
fsimage     

最新的元数据检查点
fsimage: filesysystem image的简写,文件镜像。

客户端修改文件时候,先写到Editlog,成功后才更新内存中的metadata信息。只有对文件操作成功的时候,才会写到editlog。

Fsimage是文件meta信息的持久化的检查点。                         

 

当namenode失败的时候,文件metadata信息可以通过:加载fsimage文件到内存中,在editlog中应用响应的操作。

 

Fsimage文件中包含文件metadata信息,不包含文件块位置的信息。

Namenode把文件块位置信息存储在内存中,这些位置信息是,在datanode加入集群的时候,namenode询问datanode得到的,并且不断的更新。

 

EditLog

命令空间的变化

 

Fsimage,EditLog合并

SecondaryNamenode 周期性合并,生成新的fsimage,EditLog记录新的变化。         

 

 

1. namespaceID :是文件系统的唯一标识符,在文件系统首次格式化之后生成的

2. cTime :表示 NameNode 存储时间的创建时间,由于笔者我的 NameNode 没有更新过,所以这里的记录值为 0,以后对 NameNode 升级之后,cTime 将会记录更新时间戳

3. storageType :说明这个文件存储的是什么进程的数据结构信息(如果是 DataNode,storageType=DATA_NODE)

4. blockpoolID:是针对每一个Namespace 所对应的 blockpool 的 ID,上面的这个 BP-391569129-10.6.3.43-1450226754562 就是在我的 nameserver1 的 namespace下的存储块池的 ID,这个 ID 包括了其对应的NameNode 节点的 ip 地址。

5. layoutVersion :表示 HDFS 永久性数据结构的版本信息, 只要数据结构变更,版本号也要递减,此时的 HDFS 也需要升级,否则磁盘仍旧是使用旧版本的数据结构,这会导致新版本的 NameNode 无法使用

6. clusterID :是系统生成或手动指定的集群 ID

 

$dfs.namenode.name.dir/current/seen_txid这个文件非常重要,是存放 transactionId 的文件,format 之后是 0,它代表的是 namenode 里面的 edits_*文件的尾数,namenode 重启的时候,会按照 seen_txid 的数字,循序从头跑 edits_0000001~ 到 seen_txid 的数字。所以当你的 hdfs 发生异常重启的时候,一定要比对seen_txid 内的数字是不是你 edits 最后的尾数,不然会发生建置 namenode 时 metaData 的资料有缺少,导致误删 Datanode 上多余 Block 的资讯。

 

Secondary NameNode工作原理

Secondary NameNode作用

1.      对HDFS元数据的冷备份,预防NameNode出现故障丢失数据。

2.      解决EditLog增大的问题

其工作流程如下:

如上图,Secondary NameNode主要是做Namespace image和Edit log合并的。

当客户端执行写操作,则NameNode会在Editlog记录下来(有点像oracle的online redo log file),并在内存中保存一份文件系统的元数据。

Namespace image(fsimage)文件是文件系统元数据的持久化检查点,不会再写操作后马上更新,因为fsimage写非常慢(这个比较像datafile)。

由于EditLog不断增长,在NameNode重启时,会造成长时间NameNode处于安全模式,不可用状态,是非常不符合Hadoop的设计初衷。所以要周期性合并Edit log,但是这个工作由NameNode来完成,会占用大量资源,这就出现了Secondary NameNode,它可以进行image检查点的处理工作。步骤如下:

(1)      Secondary NameNode请求NameNode进行Editlog的滚动(即创建一个新的Editlog),将新的编辑操作记录到新生成的Edit log文件。

(2)      通过http get方式,读取NameNode上的fsimage和edit文件,到Secondary NameNode上。

(3)      读取fsimage到内存中,即加载fsimage到内存,然后执行edits中所有操作(类似Oracle Data Guard,应用redo log),并生成一个新的fsimage文件,即这个检查点被创建(fsimage.chpt)。

(4)      通过http post方式,将新的fsimage文件传送到NameNode。

(5)      NameNode使用新的fsimage替换原来的fsimage文件,让(1)创建的edits替代原来的edits文件;并且更新fsimage文件的检查点时间。

整个处理过程完成。

SecondaryNameNode的处理,是将fsimage和edits文件周期的合并,不会造成NameNode重启时造成长时间不可访问的情况。

                                                            

DataNode的作用

DataNode是文件系统的工作节点,它们根据客户端或者是NameNode的调度存储和检索数据,并且定期向NameNode发送它们所存储的块(block)的列表。

集群中的每个服务器都运行一个DataNode后台程序,这个后台程序负责把HDFS数据块读写到本地的文件系统。当需要通过客户端读/写某个数据时,先有NameNode告诉客户端去哪个DataNode进行具体的读/写操作,然后,客户端直接与这个DataNode服务器上的后台程序进行通信,并且对相关的数据块进行读/写操作。

存储并检索数据块

供客户端或NameNode调度

定期向NameNode发送存储块的列表

NameNode中保存文件和块之间的所属关系

DataNode中保存数据块和本地文件的对应关系

                                                                                                                   

HDFS读写操作图

读取数据流程

客户端要访问HDFS中的一个文件

首先从namenode获得组成这个文件的数据块位置列表

根据列表知道存储数据块的datanode

访问datanode获取数据

NameNode并不参与数据实际传输

 

写入数据流程

客户端请求namenode创建新文件

客户端将数据写入DFSOutputStream

建立pipeline依次将目标数据块写入多个datanode,建立多个副本

HDFS的忌讳

低延迟场景  

将HDFS用于对数据访问要求低延迟的场景:由于HDFS是为高数据吞吐量应用而设计的,必然以高延迟为代价。

存储大量小文件      

HDFS中元数据(文件的基本信息)存储在namenode的内存中,而namenode为单点,小文件数据大到一定程度,namenode内存就吃不消了。

 

 

HDFS架构优势

降低namenode工作负载      

NameNode不处理数据

 

并行读写任务    

NameNode将任务分配给DataNode,可以并行处理读写任务。

充分利用带宽。

 

 

数据块block

HDFS中数据读写的最小单位

磁盘块:512字节

文件系统块:几千字节

HDFS块:128MB(默认)

不足128MB的块在实际磁盘中不会占用128MB的空间。

块大小的选择

目标:最小化寻址开销,降到1%以下

块太小:寻址时间占比高

块太大,map数太少,作业变慢。

采用块存储的优势

文件的数据块可分布于不同磁盘

元数据和块分开存储,元数据统一管理

通过数据备份,提供数据容错能力和可用性

多个副本,提高读取性能,结合hadoop计算框架,计算跟着数据走  

 

数据块和副本 

副本考量

数量

布局

可靠性,写入带宽,读取带宽折中

默认副本数3
默认布局
第1个放在客户端所在节点

第2个同机架的不同节点

第3个放在不同机架的另外一个节点

很好的稳定性,负载均衡,较好的写入带宽,读取性能,块均匀分布

                         

 

HDFS网络拓扑

带宽稀缺,距离标准
简单衡量

网络看作树,节点间距离是到共同祖先的距离总和

 

HDFS可靠性

冗余副本策略    
机架策略
心跳机制

DataNode周期性向NameNode发送心跳信号和块报告

NameNode根据报告验证元数据

复制副本

DataNode失效造成某些块副本数下降(复制对用户透明)

其它原因:副本本身损坏,磁盘错误,复制因子增大

 

安全模式

在启动Hadoop集群的时候,集群的运行会首先进入到安全模式(SafeMode)下。在此阶段,DataNode会像NameNode上传它们数据块的列表,让NameNode得到块的位置信息,并对每个文件对应的数据块副本进行统计。当最小副本条件满足时,即一定比例的数据块都达到最小副本数,系统就会退出安全模式,而这需要一定的延迟时间。当最小副本条件未达到要求时,就会对副本数不足的数据块安排DataNode进行复制,直至达到最小副本数。而在安全模式下,系统会处于只读状态,NameNode不会处理任何块的复制和删除命令。

 

Namenode启动时首先进入安全模式

只读状态,无法修改

直到datanode上报的block数达到阈值

上报的block个数/要求的个数,默认0.999

离开安全模式

自然离开:上报block数达到阈值

 

安全模式恢复
引起安全模式的原因

Block上报不足-----datanode没启动,磁盘坏了,服务器坏了

NameNode磁盘满------检查log,会有相关exception

用户强制关机等操作不当(特别注意!)----block损坏,checksum不一致。

故障查询

找到datanode不能正常启动的原因,重新启动

清理namenode磁盘

谨慎操作,有问题找星环,注意数据丢失

 

 

校验和
元数据保护

Hadoop用户期望在存储或处理数据时没有丢失或者损坏。然而,每一个磁盘或者网络的读写IO操作都可能导致数据错误,当流经过系统的海量数据和HADOOP的处理极限一样大的,数据损坏的机会是很高的。

通常的数据校验方法是在数据第一次进入系统时计算数据的校验和,当它在一个不可信的通道传播时有可能导致数据孙河在此校验。如果新生成的数据的校验和与原始的不能精确匹配,那么就认为它是损坏的。这个技术没有提供修复数据的方法----它仅仅监测错误。它有可能是校验和损坏而不是数据损坏,但是这个几率很小,因为校验和比数据小的多。

    一个普遍使用的监测错误的是CRC-32(32-bitcyclic redundancy check),它对任意大小的输入产生一个32位的校验和。CRC-32用在Hadoop的checksumfilesystem 中用来做校验和处理,同时HDFS使用一个更有效的变体叫CRC-32C。

 

HDFS中的数据完整性

HDFS校验所有写入/读取的数据。每dfs.bytes-perchecksum的byte数据会产生一个单独的校验和。默认是512byte,因为CRC-32校验和长度是4byte,存储开销小于1%。

Datanode在接触数据存储之前,负责检查数据及校验。这适用于他们从客户端接收的数据和复制时从其它datanode接收的数据。客户端把数据发送到datanode组成的pipeline,pipeline中的最后一个datanode检查校验和。如果这个datanode检测到错误,客户端接收到一个IOException的子类,需要它处理(例如,重新执行操作)。

当客户端从datanode读取数据时,他们也会检查校验和,把它与存储了这个数据的datanode比较。每一个datanode都保存了校验和验证日志,所以它知道它的每一个bolock的最后验证时间。当客户端验证成功一个block,它告诉datanode,datanode会更新它的日志。像这样保持统计信息在监测损坏磁盘时很有价值。

除了客户端读取时会检验block之外,每一个datanode运行一个datablockscanner,它会周期性监测datanode中所存储的所有block。这样做是为了房子物理存储媒介的位衰落。

    由于HDFS存储了block的副本,它可以通过拷贝好的副本来“恢复”损坏的block。它的工作方式是如果客户端读取block时发现一个错误,在抛出一个checksumexception之前,它会试图从namenode读取的block和datanode报告给namenode,nodenode标记这个block为损坏的,这样它不会把客户端定位到它或把它拷贝到别的datanode。然后它从其它的datanode上拷贝一个副本,这样复制银子回复到期望水平。一旦复制完毕,删除损坏的副本。

 

HDFS2     

Hadoop2.X中的HDFS(version 2.0)相比于Hadoop1.X增加了两个重要功能,HA和Federation。HA解决了Hadoop1.XNameNode中一直存在的单点故障问题,HA策略通过热备的方式为主。NameNode提供一个备用者,并且这个备用者的状态一直和主NameNode的元数据保持一致,一旦主NameNode挂了,备用NameNode可以立马转换为主NameNode,从而提供不间断的服务。另外,Federation特性,主要是允许一个HDFS集群中存在多个NameNode同时对我提供服务,这些NameNode分管一部分目录(水平切分),彼此之间相互隔离,但共享底层的DataNode存储资源。   

HDFS HA

解决NameNode单点故障

HDFS Federation

解决NameNode内存瓶颈,允许HDFS中多个NameNode

HDFS 快照

保存HDFS某一时间的只读镜像

 

HDFS HA

单点问题

一个集群中只有一个NameNode,宕机或者升级维护需要停止整个集群

解决可用性问题:7*24服务

解决办法

1.x 版本中,secondarynamenode 恢复时间慢,部分数据丢失

2.x 版本中,HA QJM,热切换

 

HDFS2.0 HA的架构

1.      两个NameNode,分别是active和standby,某一时刻只有一个active,可以切换,active修改记录写在共享存储中的Editlog,standby监听。

2.      DataNode同时向两个NameNode发送数据块列表,做到热切换。

3.      Active修改记录写在共享存储中的editlog,standby监听。

4.      Zookeeper FailoverController监控NameNode的运行情况,当active挂掉,快速切换,切断原active的连接,防止脑裂fencing。

 

上面的图里,可以看出HA的大致架构,其设计上的考虑包括:

利用共享存储来在两个NN间同步edits信息。

以前的HDFS是share nothing but NN,现在是NN又share storage,这样其实是转移了单点故障的位置,但中高端的存储设备内部都有各种RAID以及冗余硬件包括电源以及网卡等,比服务器的可靠性还是略有提高。通过NN内部每次元数据变动后的flush操作,加上NFS的close-to-open,数据的一致性得到了保证。社区现在试图把元数据存储放到Zookeeper上,以去除对共享存储的依赖。

DataNode同时向两个NN汇报块信息。

这是让Standby NN保持集群最新状态的必须步骤。

用于监视和控制NN进程的FaioverController进程。不能在NN进程内进行性等信息同步,最简单的原因,一次Full GC就可以让NN挂起十几分钟,所以,必须有一个独立的短小精悍的watchdog来专门负责监控。这也是一个松耦合的设计,以便于扩展或者更改,目前版本里是Zookeeper来做同步锁,但用户可以方便的把这个Zookeeper FailoverController替换为其他的HA方案。

隔离(Fencing),防止脑裂,保证在任何时候只有一个主NN,包括三个方面:

共享存储fencing,确保只有一个NN可以写入edits。

客户端fencing,确保只有一个NN可以享用客户端的请求。

DataNode fencing,确保只有一个NN可以向Datanode下发命令,譬如删除块,复制块,等。

 

HA方案(NFS)

失效隔离措施fencing

切断原active的连接防止脑裂

共享存储:只有一个namenode能写

客户端:只有一个namenode响应请求

DataNode:只有一个Namenode能下命令

NFS限制

HA能力受限于共享目录

NFS本身的单点失效,冗余硬盘,网络,电源

 

Hadoop Journal Node作用

NameNode之间共享数据(NFS,QuorumJournal Node(用的多))

两个NameNode为了数据同步,会通过一组称作JournalNodes的独立进程进行相互通信。当Active状态的NameNode的命令空间有任何修改的时候,会告知大部分的Journal Nodes进程。Standby状态的NameNode有能力读取JournalNodes中的变更信息,并且一直监控editlog的变化,把变化应用于自己的命名空间。Standby可以确保集群出错时,命名空间状态已经完全同步了。

Hadoop 中的NameNode好比是人的心脏,非常重要,绝对不可以停止工作。在Hadoop 1时代,只有一个NameNode。如果NameNode数据丢失或者不能工作,那么整个集群就不能恢复了。这是Hadoop 1中的单点问题,也是Hadoop 1不可靠的表现。

Hadoop 2.2.0(HA)中HDFS的高可靠指的是可以同时启动2个NameNode。其中一个处于工作状态,另一个处于随时待命状态。这样,当一个NameNode所在的服务器宕机时,可以在数据不丢失的情况下,手工或者自动切换到另一个NameNode提供服务。这些NameNode之间通过共享数据,保证数据的状态一致。多个NameNode之间共享数据,可以通过Network Filesystme或者Quorum Journal Node。前者是通过linux共享的文件系统,属于操作系统的配置;后者是Hadoop自身的东西,属于软件配置。

Quorum Journal Node方式:

集群启动时,可以同时启动两个NameNode。这些NameNode只有一个是Active的,另一个属于standby状态。Active状态意味着提供服务,standby状态意味着处于休眠状态,只进行数据同步,时刻准备着提供服务。

在一个典型的HA集群中,每个NameNode是一台独立的服务器。在任一时刻,只有一个NameNode处于active状态,另一个处于standby状态。其中,active状态的NameNode负责所有的客户端操作,standby状态的NameNode处于从属地位,维护者数据状态,随时准备切换。

两个NameNode为了数据同步,会通过一组称作JournalNodes的独立进程进行相互通信。当active状态的NameNode的命令空间有任何修改时,会告知大部分的JournalNodes进程。Standby状态的namenode有能力读取JournalNodes的变更信息,并且一直监控editlog的变化,把变化应用于自己的命名空间。Standby可以确保在集群出错时,命名空间状态已经完全同步了。

为了确保快速切换,standby状态的NN有必要知道集群中所有数据块的位置。为了做到这一点,所有的DataNode必须配置两个NN的地址,发送数据块位置信息和心跳给他们两个。

对于HA集群而言,确保同一时刻只有一个NN处于active状态是至关重要的。否则,两个NN的数据状态就会产生分歧,可能丢失数据。为了确保这一点,JounalNodes必须确保同一时刻只有一个NN可以向自己写数据。

运行的JournalNodes进程非常轻量,可以部署在其它的服务器上。注意:必须允许至少3个节点,当然可以运行更多,但是必须是奇数个。

QJM(Qurom Journal Manager)

背景

CDH4之前,在HDFS集群中NN存储单点故障(SPOF)。对于只有一个NN的集群,如果NN集群出现故障,那么整个集群将无法使用,知道NN重新启动。

NN主要在以下两个方面影响HDFS集群:

(1)NN集群发生意外,比如宕机,集群将无法使用,知道管理员重启NN。

(2)NN集群需要升级,包括软件,硬件升级,此时集群也将无法使用。

HDFS的HA功能通过配置Active/Standby两个NN实现在集群中对NN的热备来解决上述问题。如果出现故障,如机器崩溃或者机器需要升级,这是可通过此种方式将NN很快的切换到另外一台机器。

架构                             

HDFS HA的解决方案可谓百花齐放,Linux HA, VMware FT,sharedNAS+NFS,BookKeeper,QJM/QuorumJournal Manager,BackupNode等等。目前普遍采用的是shared NAS+NFS,因为简单易用,但是需提供一个HA的共享存储设备。而社区以及把基于         QJM/Quorum JournalManager的方案merge到trunk了。Cloudera提供的发行版中也包含了这个feature,这种方案也是社区在未来发行版中默认的HA方案。

在HA具体实现方法不同的情况下,HA框架的流程是一致的。不一致的就是如何存储和管理日志。在Active NN和Standby NN之间要用共享的存储日志的地方,Active NN把Editlog写到这个共享的存储日志的地方,Standby NN去读取日志然后执行,这样Active和Standby NN内存中的HDFS元数据保持着同步。一份发生主从切换Standby NN可以尽快接管Active NN的工作。(虽然要经历一小段时间让原来Standby追上原来的Active,但是时间很短。)

存储日志的地方,目前采用最多的就是用共享存储NAS+NFS。缺点是:

(1)      这个存储设备要求时HA的,不能挂掉。

(2)      主从切换时需要fencing方法让原来Active NN不在写Editlog,否则的话会发生brain-split,因为如果不阻止原来Active停止向共享存储写Editlog,那么就有两个Active NN了,这样就会破坏HDFS的元数据了。对于防止brain-split,在QJM出现之前,常见的方法就是在发生主从切换的时候,把共享存储上存放的Editlog的文件夹对原来Acitve NN的写权限拿掉,那么就可以保证同时至多只有一个Active NN,防止了破坏HDFS元数据。

Cloudera为解决这个问题提出了QJM/QuromJournal Manager,这是一个基于Paxos算法实现的HDFS HA方案。

利用2N+1台JournalNode存储Editlog
最多容忍N台服务器挂掉
基于Paxos算法

Paxos算法是一种基于消息传递的一致性算法。这个算法被认为是类似算法中最有效的。

Paxos算法解决的问题是一个分布式系统如何就某个值(决议)达成一致。

一个典型场景是,在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点都执行相同的操作序列,那么他们最后能得到一个一致的状态。为保证每个节点执行相同的命令序列,需要在每一条指令上执行一个“一致性算法”以保证每个节点看到的指令一致。

QJM设计方案

通过读写多个存储节点,达到高可用性,并引入数据一致性算法,防止异常造成的数据不一致性。

QJM的基本原理是用2N+1台JournalNode存储Editlog,每次写数据操作有大多数(>=N+1)返回成功时即认为该次写成功,保证数据高可用性。这个算法能容忍的是最多有N台机器挂掉,如果多于N台挂掉,这个算法就失效。

QJM写操作

写操作由主节点来完成,当主节点调用flush操作,会调用RPC同时向2N+1个JournalNode服务器写日志,只要有N+1个节点返回成功,写操作就说成功。

主节点会标记返回失败的JN节点,下次写日志将不再写该节点,直到下次调用滚动日志操作,如果此时该JN节点恢复正常,之后主节点会向其写日志。虽然该节点对事部分日志,由于主节点写入了多份,因此相应的日志并没有丢失。

为了保证写入每个日志文件txid的连续性,主节点保证分配的txid是连续的,同时JN节点在接受写日志的时候,首先会检查txid是否跟上次写继续,如果不联系向主节点报错,连续则写入日志文件。

QJM读操作

1.      从每个JN节点拿出所有日志,按txid从小到大排序

2.      消化日志,从小到大消化。集合中一个不行换一个。

 

当从节点除非读日志的时候,会经历如下几个步骤:

1.      选择日志文件,建立输入流

从节点遍历出所有还没有消化的日志文件,同时过滤inprocess状态的文件。对于每个JN节点上的日志文件,均按照txid从小到大进行排序放入一个集合。每个JN节点在从节点端均对应这样一个集合。再将每个JN节点间相同的日志文件进行归类为一组(组内日志会检查fisrtTxid是否相等,及其lastTxid是否相等);每个组之间再按照txid从小到大进行排序,这样方便从节点按照txid顺序消化日志;同时也会判断每个组之间txid是否连续。

2.      消化日志

准备好输入流以后,开始消化日志,从节点按照txid先后顺序从每个日志组里面消化日志。在每个日志组里面,首先会检查起始txid是否正确,如果正确,从节点先消化第一个日志文件,如果消化第一个日志文件失败则消化第二个日志文件,以此类推,如果日志组内文件遍历完还没有找到需要的日志,则该日志消化失败,消化每个日志的如果消化的上一个txid等于该日志文件的lastTxid,则该日志文件消化结束。

 

优势

不需要额外的共享存储,降低了发咋读和维护成本。

不需要单独配置fencing实现,QJM内置了fencing

不存在单点失效

系统鲁棒性可配置,能容忍最多N台机器宕机

不会因为一台JN延迟影响性能,也不会因为JN数量增多而影响性能

 

HDFS存储架构的局限性

HDFS双层架构

当前HDFS架构有两层,如下:

NameSpace

管理目录,文件,数据块

-----支持常见的文件系统操作,如创建文件,修改文件,删除文件。

Block Management

----- 块管理:块的修改及副本复制存放,创建数据块,删除数据块等。

----- 物理存储:存储实际的数据块。

 

当前的HDFS实现架构如下:

1.      NN实现Namespace和Block的管理

DN提供了物理的存储和访问Block数据,DN注册到NN的block管理层,为HDFS提供Storage层。

2.      DN注册到NN,然后与NN进行通信,但是实际上DN与NN的block管理层通信,而不

会参与NameSpace管理。

3.      因此block管理层一部分在DN中,一部分在NN中。

 

Block Identification:每个文件都是由一个或多个block组成,每个block有一个64位的数字ID,全局唯一。当前的集群中仅有一个Namespace和一个block pool来做storage。

局限性
Namespace和block managemeng高耦合
Namenode扩展性 

-----namenode只能存放在单个namenode上,而namenode在内存中存储了整个分布式文件系统中的元数据信息,这限制了集群中数据块,文件和目录的数目。

制约性能

-----文件操作的性能制约与单个NN的吞吐量

隔离性

某个用户提交的负载很大的job会减慢其它用户的job。

 

Federation 原理

为什么采用Federation

采用Federation的最主要原因是简单,Federation能够快速的解决了大部分单NameNode的问题。

Federation整个核心设计实现大概用了4个月。大部分改变是在DataNode,Config和Tools,而NameNode本身的改动非常少,这样NameNode原先的鲁棒性不会受到影响。这使得该方案与之前的HDFS版本兼容。

Federation架构

为了水平扩展namenode,Federation使用了多个独立的namenode/namespace。这些namenode之间是联合的,也就是说,他们之间互相独立且不需要互相协调,各自分工,管理自己的区域。分布式的datanode被用作通用的数据库存储存储设备。每个datanode要向集群中所有的namenode注册,且周期性地向所有Namenode发送心跳和块报告,并执行来自所有NameNode的命令。

一个block pool由属于同一个Namespace的数据块组成,每个datanode可能会存储集群中所有block pool的数据块。

每个block pool内部自治,也就是说各自管理各自的block,不会与其他的block pool交流。一个namenode挂掉了,不会影响其他namenode。

某个namenode上的namespace和它对应的block pool 一起被称为namespace volume。它(namespace volume)是管理的基本单位。当一个namenode/namespace被删除后,其所有datanode上对应的block pool也会被删除。当集群升级时,每个namespace volume作为一个基本单元进行升级。

 

多个NameNode/Namespace
每个NameNode拥有一个存储池block pool

----相互独立不需要协调,各自管理部分目录

都可以对外服务

一个Name service挂了不影响其他的

Datanode向所有namenode发送心跳和块报告,为所有存储池服务

 

Federation命令空间管理

Federation中存在多个命名空间,如何划分和管理这些命名空间非常关键。在Federation中采用“文件名hash”的方法,应为该方法的locality 非常差,比如:查看某个目录下面的文件,如果采用文件名hash的方法存放文件,则这些文件可能被放到不同namespace中,HDFS需要访问所有namespace,代价过大。为了方便管理多个命名空间,HDFS Federation采用了经典的Client Side Mount Table。

如上图所示,下面四个深色三角形代表一个独立的命名空间,上方浅色的三角形代表从客户角度去访问的子命名空间。各个深色的命名空间Mount到浅色的表中,客户可以访问不同的挂载点来访问不同的命名空间,这就如同在Linux系统中访问不同挂载点一样。这就是HDFS Federation中命名空间管理的基本原理:将各个命名空间挂载到全局mount-table中,就可以做将数据到全局共享;同样的命名空间挂载到个人的mount-table中,这就成为应用程序可见的命名空间视图。

主要优点
扩展性和隔离性

支持多个namenode水平扩展整个文件系统的namespace。可按照应用程序的用户和种类分离namespace volume,进而增强了隔离性。

通用存储服务

Block Pool抽象层为HDFS的架构开启了创新之门。分离blockstorage layer使得:

(1)      新的文件系统(non-HDFS)可以在block storage上构建

(2)      新的应用程序(如Hbase)可以在直接使用block storage层

(3)      分离的block storage层为将来完全分布式namespace打下基础

 

Erasure Code

Erasure Code可以认为是RAID的通式,任何RAID都可以转换为特定的Erasure Code。。在传统的RAID中,仅支持少量的磁盘分布,当系统中存在多个分发点和多节点时,RAID将无法满足需求。比如RAID5只支持一个盘失效,即使是RAID6也仅支持两个盘失效,所以支持多个盘失效的算法也就是erasure code是解决这一问题的办法。

原始n份数据,增加m份,通过n+m中的任意n份,还原出原始数据。定义中包含了encode和decode两个过程,将原始的n份数据变为n+m份是encode,之后这n+m份数据可存放在不同的device上,如果有任意小于m份的数据失效,仍然能通过剩下的数据还原出来。

使用场景

凡是需要通过冗余来进行高可用的场景。但总体来说,主要运用于存储和数字编码领域。

1) 阵列

如果磁盘阵列需要使用高级特性,比如需要能够容错两个磁盘失效(RAID6),那么可以用n+2的模式;如果想容错4个磁盘失效,则可使用n+4的模式。

2) 云存储

erasure code是云存储的核心技术,最初诸如hadoop, GFS,CEPH等都采用的是n-way replication来做冗余,但是这样会带来极大的成本开销,因此几乎各大公司都在用erasure code替代n-way replication,之后我还会简要介绍一下具体他们使用的模式。

3) P2P领域

erasure code 的理论起码也有20年的历史了,但真正实践可能也就最近几年的时间,在P2P领域,动态的分布和智能的容错,特别是对短暂失效是非常关键的。以往的算法或多或少都有点山寨的感觉,而借助erasure code之后,将会使P2P的算法更具有数学的严谨性。

4) 数字编码

erasure code本身就是出自编码理论,所以在这一块具有先天的优势。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值