构建高可靠hadoop集群之1-理解hdfs架构

本文主要参考 http://hadoop.apache.org/docs/r2.8.0/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html

主要内容是对该文章的翻译,部分内容参考其他的网络文章。

 

1.简介

hadoop分布式文件系统(HDFS)是一个分布式文件系统,运行于普通的硬件之上(例如pc或者廉价刀片服务器).HDFS和现有的分布式文件系统有许多相似之处。然而,不同之处也是很明显的。

HDFS是高容错,并用于部署在低成本的硬件之上。HDFS为应用数据提供很高的吞吐,使用有大量数据的应用。

HDFS实现了部分POSIX功能,允许通过流的方式访问文件系统数据。

2.假设和目标

  • 硬件故障

        硬件故障比异常更加普遍。一个HDFS实例可能包含了成千上万的服务器,每个服务器存储了文件系统数据的一部分。由于有大量的组件,而每个组件都有可能出现故障,所以总有一些部件是无法工作的。因此,检测到故障,并快速且自动恢复这些部件,就是HDFS的核心架构目标。

  • 流数据存储

     

    运行于HDFS上的应用有通过流方式访问数据集的需求。这类应用不是运行于通常目的的文件系统之上。HDFS主要设计目的是为了批量处理,而不是用户交互。所以重点就是高吞吐,而不是低延迟。

    http://www.cnblogs.com/beanmoon/archive/2012/12/17/2821548.html

    POSIX标准有许多的硬件要求,但这些要求并不符合HDFS要求。但POSIX在某些小且关键的方面可以用于提升数据吞吐率.
  • 大数据集

      运行于HDFS之上的应用具有大数据集。HDFS中的一个典型文件的大小介于G~T.因此,HDFS针对大文件进行优化。它应该提供高的总量数据带宽,并可以在一个集群中扩展到上千的节点。它可以在单一的实例中支持几千万的的文件。

  • 简单一致性

     HDFS应用需要个一次写入需多次读的文件存取模式。一个文件一旦创建,写入和关闭,就不需要改变,除非为了添加数据或者清空。数据只能添加到尾部,而不是任意点。

     这种假设简化了数据一致性问题,并使得高吞吐量成为可能。一个MR原因或者一个web爬虫应用特别适合这种模式。

  • 传输的成本大于计算成本

     如果计算能够离需要的数据近一些,那么无疑更有效。当需要的数据特别大的时候,这种情况就特别明显。因为这会最小化网络堵塞,并提升总体的吞吐量。假设:计算靠近数据总是比数据靠近计算来得好。

     HDFS提供了一个接口,让应用的计算更加靠近数据。

  • 在各种各样的硬件和软件平台之间迁移

     HDFS的设计目的之一就是让它更方便迁移。

 

3.名称节点和数据节点

HDFS是一个主从结构。一个HDFS集群包含了一个名称节点(namenode),这个节点负责管理文件系统名称空间,并调控客户端对文件的访问。此外,集群还有许多的数据节点(NAMENODE),通常一个节点上一个数据节点,数据节点管理节点上的存储。

HDFS提供一个系统名称空间,并允许用户的数据以文件的方式存储。在内部,一个文件通常被分割为多个块(也可能是一个块,根据文件大小和参数不同而定),这些数据块被存储在多个节点上。

名称节点执行文件系统名称空间操作,诸如打开,关闭,和重新命名文件和目录。名称节点也决定数据块和数据节点的映射关系。

数据节点负责为客户端提供读写请求,同时也负责块的创建,删除,和复制(根据名称节点的要求)。

名称节点和数据节点在设计的时候,就被要求是能够运行在普通的机器上的软件。这些机器典型地要求运行GNU/LIUX操作系统。

HDFS是使用java语言构建的。任意支持java的机器都可以运行名称节点和数据节点软件。使用java这种可移植语言,意味着,HDFS可以被部署在许多机器上。

典型的部署就是,一个专有的机器运行名称节点。机器中的其它节点运行数据节点软件。框架并不阻止一台机器上运行多个数据节点(但一般人不这么做,一般情况也不这儿做)。

单一名称节点的存在极大地简化了系统的框架。名称节点就是所有HDFS元数据的一个仲裁人和仓库。系统这样设计,并让用户的数据永远不会通过名称节点(非常重要)。

4.文件系统命名空间

HDFS支持传统文件组织。用户或者应用可以创建目录,并在目录中存储文件。文件系统名称空间层次类似于绝大部分现有的文件系统。

就是说HDFS也可以创建和移除文件,在目录之间移动文件,或者重新命名一个文件。HDFS支持用户配额和存取权限(模仿传统文件系统)。但HDFS并不支持软硬链接,虽然HDFS的框架并不阻碍这些特性的实现。

名称节点维护系统名称空间。对文件系统名称空间或者属性的任意修改都会被名称节点记录。一个应用可以设定HDFS复制文件的份数。

文件拷贝数被称为文件的复制因子,这些信息存储在名称节点。

 

5.数据复制

  • 复制定位:婴儿的第一步

     HDFS设计的目的就是为了在一个大型集群中可靠地存储非常大的文件。HDFS把每个文件存储为一系列的数据块。通过复制文件的数据块达到容错目的。数据块大小和复制因子可以按照具体文件来配置。

     除了最后一块,其它数据块大小一致。当要添加数据的时候, 用户可以不填满最后一块,而是直接开新快来存储数据。

     一个应用可以文件的复制个数。复制因子可以在文件创建的设定,之后也可以修改。HDFS中的文件只写一次(除了附加和清空),在任意时候,一个文件只有一个写入程序。

     名称节点决定文件的各种操作,除了复制因子。名称节点定期从数据节点接受心跳和块报告。能够收到心跳,意味着,数据节点工作正常。

     一个块报告包含节点上所有块的列表(清单)。

  • 复制的选择

    为了最小化全局带块的消耗,并减少读取延迟,HDFS力图从接近读取程序的复制中满足一个读请求。如果在读取节点的同一个架子上存储复制信息,那么复制信息就是一个更好的选择。如果HDFS

    集群扩展为多个数据中心,那么本地数据中心的选择比远程中心的更好。

     译注:这个告诉我们,如何搭建机架和数据中心,是很重要的,它会影响到数据读取的效率。

  • 安全模式

    在启动的时候,名称节点会进入一个特别的状态,这个状态称为安全模式。安全模式下,并不进行数据复制。

    名称节点从数据节点接受心跳和数据块报告。数据块报告包含了特定节点上数据块的清单。每个块有一个特定最小复制数。只有一个块的最小复制数满足名称节点检查要求,这个块才能认为是安全复制的。

    经过名称节点中安全复制数据块的检查(检查的比例可以配置,检查的过程大约要30秒左右)后,名称节点退出安全模式。然后,名称节点会确定那些没有满足安全复制的数据块清单,并为这些块做必要的安装复制。

6.文件系统元数据持久性

     hdfs名称空间由名称节点存储。名称节点使用编辑日志(editlog)来记录系统元数据的每个变化(这个日志是一个事务日志)。例如,在HDFS创建一个新文件,那么名称节点会在编辑日志中插入一条针对新文件的记录。

     类似地,如果修改一个文件的复制因子,名称节点也会插入一条编辑日志。名称节点使用本地操作系统的文件系统中的一个文件来存储编辑日志。

     整个文件系统名称空间,包括文件块映射信息和文件系统属性,存储在文件FsImage中。FsImage存储方式同Editlog.

     名称节点会再内存中存储整个文件系统名称空间和文件块映射信息。当名称节点启动的时候,或者可配瓶颈触发一个检查点的时候,名称节点从FsImage,EditLog读取信息。

     编辑日志的所有事务会应用到内存中的FSIMAGE中,然后内存中的fsimage会写到磁盘中的一个新的fsImage文件中。名称节点然后就可以清楚老的编辑日志,因为老日志的所有事务已经应用到持久的FSIMAGE中。

     这种操作称为一个检查点。检查点的目的就是为了确认文件系统元数据有一个一致的视图,检查的途径就是从文件系统元数据获得一个快照,并把它们存储在FSIMAGE。

     虽然读FSIMAGE是比较高效,但增量编辑FSIMAGE并不高效。所以,名称节点不是逐次编辑FSIMAGE,而是把这些编辑信息记录在编辑日志中(然后通过检查点更新).

     检查点可以按照特定的间隔触发(通过dfs.namenode.checkpoint.period来控制),间隔单位是秒,或者一个给定的累积文件系统事务数(dfs.namenode.checkpoint.txns).

     如果两个属相都有设定,那么任何之后,只有满足其中之一,就会触发检查点操作。

 

     数据节点使用本地文件系统来存储HDFS数据。数据节点并不关心HDFS文件。它们使用本地文件系统的单独文件来存储HDFS数据的每个数据块。

     名称节点不会在一个节点下创建所有文件。它们使用探索方法来确定每个目录的最佳文件数,并在必要的时候,创建子目录。

     在同个目录创建所有的本地文件并不是最好的选择,因为本地文件系统可能无法有效地在单个目录中支持巨量的文件(译注:在有巨多的文件的目录中ls就知道了,linux这个方面好像不如windows 的dir来得明智)。

     当一个数据节点启动的时候,它会扫描本地文件系统,并生成HDFS数据块和本地文件的映射清单,并把这个报告发送给名称节点。这个报告就是块报告(blockreport)

7.通信协议

    所有的HDFS通信协议基于TCP/IP。一个客户端通过名称节点的一个可配TCP端口来建立连接。客户端和名称节点谈论客户端协议。数据节点使用数据节点协议和名称节点谈论。

    一个远程过程调用(rpc)通过抽象的方式包装了客户端协议和数据节点协议。

    按照设计要求,名称节点用不初始化任何的PRC(不主动发起任何rpc),反之,名称节点只会应答数据节点和客户端的rpc请求。

8.强壮性

  • 数据磁盘故障,心跳和重新同步

     每个数据节点都会定期发送心跳信息给名称节点。网络断开会导致一部分的数据节点失去和名称节点的联系。名称节点通过心跳信息的缺失来侦测这种情况。

     名称节点把最近没有心跳信息的数据节点的状态标记为死亡(dead),并不再提交新的io请求给这些死亡节点。于是死亡几点上的数据对于HDFS而言不再可用。

     数据节点的死亡可能会导致部分数据块的复制因子低于特定的值。名称节点不断追踪哪些数据块需要被复制,并在必要的时候启动复制。

     重新复制可能是许多原因导致的:数据节点不可用,某个复制坏掉了,数据节点上的磁盘发生故障,或者文件的复制因子变大了。

     用于标记死亡状态的失联间隔目前设置得很保守(默认超过10分钟)  ,目的是避免不稳定的数据节点导致的复制风暴。

     用户可以设置更短一些的间隔(这种间隔内没有联系),把数据节点标记为陈旧(stale),以避免陈旧的节点被用作负载(进行读写操作,换言之,这些节点不再使用,但也不容易引起复制风暴)

  • 集群重平衡(均衡)

     HDFS架构可以满足数据重平衡的方案。一个方案可能自动把数据从一个节点移动到其它节点,如果特定节点的剩余空间低于阀值。

     在一种对特定文件有大量需求的情况下,方案可能会动态创建额外的复制,并重新平衡集群中的数据。这种类型的数据重平衡方案并不是隐式的(就是要手动发起)。

  • 数据完整

     有可能从节点传输来的数据是损坏的。原因可能是存储设备,网络故障,或者有bug的软件。HDFS客户端软件会进行HDFS文件的检验(使用checksum方式)。

     当一个客户端创建一个HDFS文件,它会计算文件中每个块的checksum,并在单独隐藏文件中保存这些checksum(这个文件和数据在同个hdfs名称空间)。

     当一个客户取数据的时候,会同时计算checksum,并看看是否和以前存的checcksum值一致。如果不是,那么,客户端可能会从其它节点使用复制块来替代。

  • 元数据磁盘故障

      FSIMAGE和EDITLOG是HDFS的核心数据结构。如果它们有问题,那么整个集群就瘫痪了。因此,如果有必要,可以在名称节点上存储多个拷贝(这些事可配的)。

      只要更新两个文件中的一个,那么两个文件都会被同步更新。由于需要同步多个拷贝,这样就可能降低名称节点的事务率(单位之间执行的事务个数)。然而,这种降低是可以接受的,因为即使HDFS的应用对数据非常依赖,但它们对元数据不是那么依赖(不是时时刻刻需要,偶尔访问即可)。当一个名称节点重启的时候,它会使用最近一致的FSIMAGE和editlog。

     另外一个提高容错弹性的选择是启用多名称节点的高可靠性。多个节点之间可以使用基于NFS的共性存储,或者使用一个分布式编辑日志(称为日志? journal)。

     journal是一个推荐的方案。

  •  快照

     Snapshots support storing a copy of data at a particular instant of time. One usage of the snapshot feature may be to roll back a corrupted HDFS instance to a previously known good point in time.

    快照能够保存特定瞬间的数据拷贝。一旦使用快照,就可以把一个破损的HDFS实力回滚到特定的时间点(译注:存储要求太高了。而且照相一次,要耗费多少时间了?)。

8.数据组织

  • 数据块   

     hdfs设计用于支持非常大的文件。需要用HDFS的用于都是需要处理大数据集的。这些应用写一次数据,但会读取一次或者多次,并且要求这些读能否以流速度的方式进行。HDFS一次写多次读的文件操作。一个典型的HDFS块大小是128m。因此,每个HDFS文件按照128m的方式进行分块,如果有可能的话,每个块都应该在不同的节点上。

     (所以,需要根据应用的情况,分析下应该使用到多少节点,部署事先应该有计算过)

  • 缓存(阶段-staging)   

     一个客户端关于创建文件的请求是不会立即达到名称节点的。事实上,开始的时候,HDFS客户端会在本地缓冲中缓存文件数据。应用的写被透明引导到本地缓冲。

    当本地文件所累积的数据达到一定量的时候,客户端会联系名称节点(译注:缓存以提高效率,是很平常很正确的选择)。名称节点随后把文件名称插入到文件系统结构中,并为文件分配一个块。

    然后,名称节点把数据节点和目标数据块的信息返回给客户端的请求。再然后,客户端把缓冲中的数据发送给指定的数据节点。当文件关闭的时候,本地缓冲中尚未发送的数据会被传输给数据节点,客户端然后告诉名称节点,文件被关闭了。

    在这个时刻,名称节点提交创建事务,并把有关数据存储在持久存储中。如果数据节点在文件关闭前死亡,那么文件就会丢失。

    以上的方案是在谨慎考虑后,被基于HDFS的应用采用的。这些原因需要流式写文件。如果一个客户端直接写远程文件,但又没有使用客户端的缓冲,那么网速和网路堵塞会对系统的吞吐量造成客观的影响。

    这个方案没有先例。

    更早的文件系统等,例如afs(译注:这文件系统和nfs一样都是分布式文件系统,但前者读起来方便,写比较麻烦,和hdfs有点像),使用客户端缓冲来提升性能。

    POSIX中部分要求已经被实现,以期获得更好的文件上传性能。

  • 复制管道

     当一个客户端写数据到HDFS文件中的时候,数据是先写入到本地缓冲。假定这个HDFS文件的复制因子是3.

     客户端本地缓冲中的数据累积到一定程度后,从名称节点获取一个数据节点清单。然后,客户端开始把这些数据传输给数据节点。

     第一个数据节点并非一次接受一个完整的缓冲数据,而是分开来一次次做的。首先接受一小部分,然后写入到本地仓库,然后把数据传输给清单中的第二个数据节点。第二数据节点和第一个节点一样操作,然后数据发送到第三个节点。

     就这样,数据就是从一个节点传输到另外一个节点,好像管道传输一样。

9.存取

      HDFS可以使用应用,以多个途径访问。

      最原始的方式是文件系统JAVA API。 还有包装java api的c语言api,以及rest api(译注:rest看起来比较复杂,及时通过http来访问)。

      此外,一个http浏览器也可以用户浏览HDFS实例中的文件。通过使用NFS网关,HDFS可以挂载到本地文件系统。

  • FS SHELL    

     HDFS允许用户数据按照目录和文件的方式组织。HDFS提供了一个命令行界面,这个界面称为FS SHELL。

     FS SHELL提供的语法和其它shell的语法类似(bash,csh),用户很容易上手。

     如果应用需要使用脚本,可以通过fs shell来访问hdfs中的数据。

  • dfsadmin 

     DFSADMIN 命令集用于管理hdfs集群。例如:

     bin/hdfs dfsadmin -safemode enter    --把集群置为安全模式

     bin/hdfs dfsadmin -report         -- 生成一个报告

     bin/hdfs dfsadmin -refreshNodes     --刷新数据节点

  • 浏览器界面

    一个典型的Hdfs安装会配置一个web服务器,服务器会把hdfs的名称空间通过特定端口(可配)发布。这样用户就可以使用web浏览器来查看HDFS名称空间,并查看文件的内容。   

10.空间回收(分配)

  •  文件删除和取消删除   

     如果有配置垃圾箱(译注:core-site.xml中 fs.trash.interval 非0就是开启),那么通过FS SHELL移除的文件不会立刻从HDFS移除。hdfs会把这些文件移动到一个垃圾目录(每个用户都有自己的垃圾目录/user/<username>/.Trash).

     如果文件还在垃圾箱中,就可以立刻恢复。

     最近删除的文件会被移动到当前垃圾目录(/user/<username>/.Trash/Current),在一个可配置的间隔后,HDFS会创建检查点(/user/<username>/.Trash/<date>),并删除过期的检查点。 详细信息可以参阅 expunge command of FS shell.

     当垃圾过期后,名称节点从名称空间删除指定文件。相关的数据块被释放。注意,因为这个机制,用户删除一个文件后,hdfs可能需要过一段时间才会释放空间。

     如何绕过垃圾箱机制,下面是一个例子:

     hadoop fs -rm -r -skipTrash delete/test2

  •  降低复制因子

     When the replication factor of a file is reduced, the NameNode selects excess replicas that can be deleted. The next Heartbeat transfers this information to the DataNode. The DataNode then removes the corresponding blocks and the corresponding free space appears in the cluster. Once again, there might be a time delay between the completion of the setReplication API call and the appearance of free space in the cluster.

     当降低复制因子后,名称节点会把多余的复制块删除掉。下一个心跳时候,会把这个信息传递给数据节点。数据节点会移除对应的块。随后集群中会出现对应的可用空间。

     再一次,调低复制因子到看到集群可用空间增加(通常)之间,会存在一定延迟。

 

汇总:

    本文简要描述了hdfs的架构,总体上还是很清楚的,原文还带有图,不过就个人来看,觉得这些图不是很容易理解,还不如文字形象。

    文章覆盖了hdfs架构的各个核心方面,包括原理,性能,高可靠等等。

   

转载于:https://www.cnblogs.com/lzfhope/p/6973240.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值