Google 三架马车中,第一架即是 GFS(Googel File system )
文件系统从垂直伸缩到水平伸缩
早期,为了提升计算机的运算以及存储能力,主要靠的是垂直伸缩的方式。摩尔定律提出集成电路上晶体管的数目每两年会增加一倍。当时,半导体行业大致按照摩尔定律发展了半个多世纪。
独立硬盘冗余阵列(RAID, Redundant Array of Independent Disks)可以认为是一种垂直伸缩。其基本思想是把多个磁盘组装起来称为一个磁盘阵列,使之性能达到甚至超过一个价格昂贵、容量巨大的硬盘。根据 RAID 实现方式的不同,可以有不同的效果,包括提升容量、磁盘容错、处理性能。
互联网时代,计算机硬件的性能提升早已放缓,公司购买大型计算机的成本是很大的,所以开始出现水平伸缩的方式,通过分布式技术,在集群中不断增加计算机来提升计算能力。将 RAID 的思想应用到分布式集群,就产生了分布式文件系统,分布式存储技术的典型代表就是 HDFS。
HDFS (Hadoop Distributed File System) 被设计用来搭建大规模的分布式集群,提供海量数据的读写、存储。
HDFS 的特点和设计目标:
硬件容错 大规模集群有大量节点,硬件会有一定的损坏概率,所以 HDFS 支持错误检测,快速和自动的恢复服务。
流式访问 HDFS 支持流式访问数据,被设计用于批量处理而非用户交互。重点是高吞吐量访问而不是低延迟。(换句话受,HDFS 为高吞吐量而设计,以高延迟为代价)
存储大文件 HDFS 适合存储大型文件,并将文件分块存储到不同的节点上。
简单一致性模型 一次写入,多次读取。支持追加数据,不支持修改数据内容。这样的设计简化了一致性模型,支持高吞吐量的访问。
移动计算比移动数据更划算 程序比数据小得多,那么将程序分发到数据所在得地方进行计算。比如 Mapreduce 任务在多个节点上分别运行后再分别聚合的思路。
跨平台 HDFS 作为大数据存储,被广泛应用于多种大数据平台。
HDFS 架构
HDFS 的架构如上图所示。可以看到其中的关键组件包括一个 NameNode(NN) 和多个 DataNode(DN),事实上大部分的分布式技术都是类似这样的主从(Master-Slave) 结构。
HDFS 中文件被切分文多个数据块(Block)存储在多个 DataNode 中,块大小默认为 128M,数据块副本默认为3。
NameNode 管理 HDFS 文件系统的元数据(Metadata)和控制客户端(Client)对文件的访问请求。文件操作比如打开、关闭、重命名等都由 NameNode 执行,响应操作记录也存储在其中。文件的数据块副本数和对应的 DataNode 地址也由 NameNode 维护存储。
DataNode 管理相应节点的存储,响应 NameNode 命令,读写用户的文件对应的数据块,定期向 NameNode 发送心跳信息,汇报本身及其所有 block 信息、健康状况。
数据副本存放
上图展示了 HDFS 数据副本存放的示意。从 NameNode 的元数据信息中可以看到,对于文件 part-0 ,其副本份数是 2,block ID 分别为 1 和 3。其中 block1 存放在 DataNode1 和 DataNode3 中,这样即使某个 DataNode 宕机,也不会影响文件的访问。
HDFS 数据块分布在不同的 DataNode 上,所以文件系统可以并行地进行读写操作,实现告诉访问。
大型的 HDFS 集群往往有多个机架。当副本个数为 3 时,往数据块副本存放策略是一个当前运行客户端的节点上,另外两个副本放在其它机架的不同节点上,从而保证数据的可靠性和读写性能。
以上就是 HDFS 的基本存储原理。
HDFS 高可用 (High Availability,HA)
NameNode 节点中存储有以下两个文件,存储重要的元数据信息。
fsimage: NameNode 的快照,元数据的镜像,包含了文件系统中的所有目录和文件inode的序列化信息
edits: 记录文件系统的改动
NameNode 把对文件系统的修改存储到 edits 中,启动时从 fsimage 读取文件状态,从 edits 应用编辑操作,随着 edits 越来越大,NameNode 的启动时间会变长。
在 Hadoop 2.X 之前有 Secondary NameNode,按一定规则将 edits 文件和 fsimage 文件合并,合并后 NameNode 会启用新的 edits 文件,这样会减小 edits 文件的文件大小,控制 edits 文件的大小会减少 NameNode 在启动阶段解析加载 edits 文件的时长。
但是,在 hadoop2.0 之前,NameNode 只有一个,存在单点问题(虽然 Hadoop1.0 有secondary NameNode,checkpointnode,buckcupnode 这些,但是单点问题依然存在),在 hadoop2.0 引入了 HA 机制。
Hadoop 2.X 引入 Active NameNode 和 Standby NameNode ,提供主备切换避免单点故障。HA 其本质上就是要保证主备 NN 元数据一致,即保证 fsimage 和 edits 在备 NN 上也是完整的。元数据的同步很大程度取决于 edits 的同步,而这步骤的关键就是共享文件系统。提供两种方式。
NFS 网络共享文件系统的方式
提供共享文件的 NAS 设备。NFS 作为 Active NameNode 和 Standby NameNode 之间数据共享的存储。Active NameNode 会把最近的 edits 文件写到 NFS,而 Standby NameNode 从 NFS 中把数据读过来。这个方式的缺点是,如果 Active NameNode 或者 Standby NameNode 有一个和 NFS 之间网络有问题,则会造成他们之前数据的同步出问题。
QJM(Quorum Journal Manager )方式
QJM 由JournalNode(JN)组成,一般是奇数点结点组成。每个 JournalNode 对外有一个简易的 RPC 接口,以供 NameNode 读写 edits 到 JN 本地磁盘。当写 edits 时,NameNode 会同时向所有 JournalNode 并行写文件,只要有 N/2+1 结点写成功则认为此次写操作成功,遵循 Paxos 协议。
JN日志节点是一个轻量级的,所以可以和Hadoop的其他守护线程放在一起,不需要额外设备。
完成 HA 除了元数据的同步,还需要一个完善的主备选举切换机制,依赖于 Zookeeper。
关于 HA 详细内容可参考
HDFS 联邦(Federation)
如下图 HDFS 有两个重要层级,命名空间(Namespace)和 块存储服务(Block Storage)。但是之前介绍的 HDFS 结构都是单 NameNode 的(注意上文说得 HA 并不提供 Namespace 的扩展),单 NameNode 命名空间受限,整个 HDFS 文件系统的吞吐量受限于单个 NameNode 的吞吐量,比如存储大量小文件时,NameNode 会越来越大,并且单个 NameNode 无法隔离应用程序。
联邦 HDFS 提供了扩展命名空间的策略,如下图所示。
块池(Block Pool)
一个块池是一系列属于单个命名空间的块集合,DataNodes 为集群中的所有块池存储块。每个块池都是独立管理。这就允许命名空间为新块生成 Block IDs 时不需要与其他命名空间协调。一个 NameNode 故障不会阻止 DataNode 为集群中的其他 NameNodes 提供服务。
一个命名空间和它的块池一起被称为命名空间卷(Namespace Volume)。命名空间卷是一个独立的自我管理单位。当一个 NameNode/namespace 被删除时,对应的在 DataNodes 上的块池也会被删除。在集群升级期间,每个命名空间卷作为一个单元来进行升级。
ClusterID
ClusterID 用于标识集群中所有的节点。当一个 NameNode 被格式化时,ClusterID 就会人工提供或者自动生成,同时这个 ID 用于将剩余其他 NameNode 格式化到集群中。
HDFS 联邦的主要好处:
命名空间可扩展 - 联邦增加了命名空间的水平扩展性。大型部署或使用大量小文件的部署使用命名空间扩展可以允许将更多 NameNodes 添加到集群中,这对于大型部署或使用大量小文件部署是非常有益的(这样就能避免单 个NameNode 内存有限的问题)。
性能 - 文件系统吞吐量将不受单个名称节点的限制。向集群添加更多NameNode可扩展文件系统读/写的吞吐量。
隔离 - 单个 NameNode 在多用户环境中不提供隔离。例如,一个实验应用程序可能会使 NameNode 过载,并降低主要应用程序的速度。通过使用多个 NameNode,可以将不同类别的应用程序和用户隔离到不同的命名空间。
以上便是本文的全部内容,关于 HDFS 的文件读写,容错等内容会在下一篇文章通过漫画的形式介绍。
参考文献
HDFS 官方文档:https://hadoop.apache.org/docs/r2.9.2/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html
极客时间大数据专栏
欢迎关注的我微信公众号