广西建设学院网站,房产信息查询平台,绍兴网站的优化,百度软件下载目录
编辑
一、HDFS基础 1.1 概述 1.2 HDFS的设计目标 1.2.1 硬件故障 1.2.2 流式数据访问 1.2.3 超大数据集 1.2.4 简单的一致性模型 1.2.5 移动计算而不是移动数据 1.2.6 跨异构硬件和软件平台的可移植性 1.3 基础概念 1.3.1 块#xff08;Block#xff09; 1.3.2 复制…
目录
编辑
一、HDFS基础 1.1 概述 1.2 HDFS的设计目标 1.2.1 硬件故障 1.2.2 流式数据访问 1.2.3 超大数据集 1.2.4 简单的一致性模型 1.2.5 移动计算而不是移动数据 1.2.6 跨异构硬件和软件平台的可移植性 1.3 基础概念 1.3.1 块Block 1.3.2 复制Replica 1.3.3 名字节点Namenode 1.3.4 Datanode 1.3.5 FileSystem 二、 HDFS架构 2.1 总体架构 2.1.1 角色功能 2.1.1.1 NameNode 2.1.1.2 DataNode 2.1.1.3 Client 2.1.2 元数据持久化 2.1.3 安全模式 2.1.4 SNNSecondaryNameNode 2.2 主从架构分析 2.2.1 单节点主从架构分析 2.2.1.1 主从分析 2.2.1.2 主从架构问题 2.3 解决方案 2.3.1 单点故障(HA集群方案) 2.3.1.1 总体架构 2.3.1.2 架构说明 2.3.1.3 架构角色说明 2.3.1.3.1 NameNode active 2.3.1.3.2 NameNode standby 2.3.1.3.3 JournalNode 2.3.1.3.4 zkfc(FailoverController) 2.3.1.3.5 ZooKeeper 2.3.2 压力过大内存受限(联帮机制Federation) 2.3.2.1 Federation 产生背景 2.3.2.1.1 单组Namenode架构 2.3.2.1.2 单组Namenode局限性 2.3.2.1.3 为什么要引入Federation 2.3.2.2 Federation 介绍 2.3.2.2.1 Federation架构 2.3.2.3 Federation主要优点 2.3.2.3.1 Namespace的可扩展性 2.3.2.3.2 Performance性能 2.3.2.3.3 Isolation隔离 2.3.2.4 Federation 主要缺点 1交叉访问问题 2管理性问题
2.3.2.5 Federation局限性 三、HDFS读写流程 3.1 写流程 3.2 读流程 一、HDFS基础 1.1 概述
Hadoop分布式文件系统(HDFS)是指被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统Distributed File System。HDFS在最开始是作为Apache Nutch搜索引擎项目的基础架构而开发的。HDFS是Apache Hadoop Core项目的一部分。 1.2 HDFS的设计目标 1.2.1 硬件故障
硬件故障对于HDFS来说应该是常态而非例外。HDFS包含数百或数千台服务器计算机每台都存储文件系统的一部分数据。事实上HDFS存在大量组件并且每个组件具有非平凡的故障概率这意味着某些组件始终不起作用。因此检测故障并从中快速自动恢复是HDFS的设计目标。 1.2.2 流式数据访问
在HDFS上运行的应用程序不是通常在通用文件系统上运行的通用应用程序需要对其数据集进行流式访问。HDFS用于批处理而不用于用户的交互式使用相对于数据访问的低延迟更注重数据访问的高吞吐量。
可移植操作系统接口Portable Operating System Interface of UNIX, POSIX标准设置的一些硬性约束对HDFS来说是不需要的因此HDFS会调整一些POSIX特性来提高数据吞吐率事实证明是有效的。 1.2.3 超大数据集
在HDFS上运行的应用程序具有大型数据集。HDFS上的一个文件大小一般在吉字节GB到太字节TB。因此HDFS需要设计成支持大文件存储以提供整体较高的数据传输带宽能在一个集群里扩展到数百上千个节点。一个HDFS实例需要支撑千万计的文件。 1.2.4 简单的一致性模型
HDFS应用需要“一次写入多次读取”访问模型。假设一个文件经过创建、写入和关闭之后就不会再改变了。这一假设简化了数据一致性问题并可实现高吞吐量的数据访问。MapReduce应用或网络爬虫应用都非常适合这个模型。将来还需要扩充这个模型以便支持文件的附加写操作。 1.2.5 移动计算而不是移动数据
当应用程序在其操作的数据附近执行时计算效率更高。当数据集很大时更是如此这可以最大限度地减少网络拥塞并提高系统的整体吞吐量。HDFS为应用程序提供了接口使其自身更靠近数据所在的位置。 1.2.6 跨异构硬件和软件平台的可移植性
HDFS的设计考虑到了异构硬件和软件平台间的可移植性方便了HDFS作为大规模数据应用平台的推广。
从Hadoop这些年的发展来看HDFS依靠上述特性成为不断演进变革的大数据体系的坚实基石。 1.3 基础概念 1.3.1 块Block
Block是HDFS文件系统处理的最小单位一个文件可以按照Block大小划分为多个Block不同于Linux文件系统中的数据块HDFS文件通常是超大文件因此Block大小一般设置得比较大默认为128MB。 1.3.2 复制Replica
HDFS通过冗余存储来保证数据的完整性即一个Block会存放在N个Datanode中HDFS客户端向Namenode申请新Block时Namenode会根据Block分配策略为该Block分配相应的Datanode replica这些Datanode组成一个流水线pipeline数据依次串行写入直至Block写入完成。 1.3.3 名字节点Namenode
Namenode是HDFS文件系统的管理节点主要负责维护文件系统的命名空间Namespace或文件目录树Tree和文件数据块映射BlockMap以及对外提供文件服务。
HDFS文件系统遵循POXIS协议标准与Linux文件系统类似采用基于Tree的数据结构以INode作为节点实现一个目录下多个子目录和文件。INode是一个抽象类表示File/Directory的层次关系对于一个文件来说INodeFile除了包含基本的文件属性信息也包含对应的Block信息。
数据块映射信息则由BlockMap负责管理在Datanode的心跳上报中将向Namenode汇报负责存储的Block列表情况BlockMap负责维护BlockID到Datanode的映射以方便文件检索时快速找到Block对应的HDFS位置。
HDFS每一步操作都以FSEditLog的信息记录下来一旦Namenode发生宕机重启可以从每一个FSEditLog还原出HDFS操作以恢复整个文件目录树如果HDFS集群发生过很多变更操作整个过程将相当漫长。
因此HDFS会定期将Namenode的元数据以FSImage的形式写入文件中这一操作相当于为HDFS元数据打了一个快照在恢复时仅恢复FSImage之后的FSEditLog即可。
由于Namenode在内存中需要存放大量的信息且恢复过程中集群不可用HDFS提供HA主/备Namenode实现故障迁移Failover以及Federation多组Namenode提供元数据服务以挂载表的形式对外提供统一的命名空间特性以提高稳定性和减少元数据压力。 1.3.4 Datanode
Datanode是HDFS文件系统的数据节点提供基于Block的本地文件读写服务。定期向Namenode发送心跳。Block在本地文件系统中由数据文件及元数据文件组成前者为数据本身后者则记录Block长度和校验和checksum等信息。扫描或读取数据文件时HDFS即使运行在廉价的硬件上也能通过多副本的能力保证数据一致性。 1.3.5 FileSystem
HDFS客户端实现了标准的Hadoop FileSystem接口向上层应用程序提供了各种各样的文件操作接口在内部使用了DFSClient等对象并封装了较为复杂的交互逻辑这些逻辑对客户端都是透明的。 二、 HDFS架构 2.1 总体架构 HDFS是一个典型的主/备Master/Slave架构的分布式系统由一个名字节点Namenode(Master) 多个数据节点Datanode(Slave)组成。其中Namenode提供元数据服务Datanode提供数据流服务用户通过HDFS客户端与Namenode和Datanode交互访问文件系统。
如上图所示HDFS把文件的数据划分为若干个块Block每个Block存放在一组Datanode上Namenode负责维护文件到Block的命名空间映射以及每个Block到Datanode的数据块映射。 2.1.1 角色功能 2.1.1.1 NameNode
1完全基于内存存储文件元数据、目录结构、文件block的映射
2需要持久化方案保证数据可靠性
3提供副本放置策略 2.1.1.2 DataNode
1基于本地磁盘存储block(文件的形式)
2并保存block的校验和数据保证block的可靠性
3与NameNode保持心跳汇报block列表状态 2.1.1.3 Client
1和NameNode交互文件元数据和NameNode交互文件元数据
2和DataNode交互文件block数据 2.1.2 元数据持久化
1任何对文件系统元数据产生修改的操作Namenode都会使用一种称为EditLog的事务日志记录下来
2使用FsImage存储内存所有的元数据状态
3使用本地磁盘保存EditLog和FsImage
4EditLog具有完整性数据丢失少但恢复速度慢并有体积膨胀风险
5FsImage具有恢复速度快体积与内存数据相当但不能实时保存数据丢失多
6NameNode使用了FsImageEditLog整合的方案
滚动将增量的EditLog更新到FsImage以保证更近时点的FsImage和更小的EditLog体积 2.1.3 安全模式
1HDFS搭建时会格式化格式化操作会产生一个空的FsImage
2当Namenode启动时它从硬盘中读取Editlog和FsImage
3将所有Editlog中的事务作用在内存中的FsImage上
4并将这个新版本的FsImage从内存中保存到本地磁盘上
5然后删除旧的Editlog因为这个旧的Editlog的事务都已经作用在FsImage上了
6Namenode启动后会进入一个称为安全模式的特殊状态。
7处于安全模式的Namenode是不会进行数据块的复制的。
8Namenode从所有的 Datanode接收心跳信号和块状态报告。
9每当Namenode检测确认某个数据块的副本数目达到这个最小值那么该数据块就会被认为是副本安全(safely replicated)的。
10在一定百分比这个参数可配置的数据块被Namenode检测确认是安全之后加上一个额外的30秒等待时间Namenode将退出安全模式状态。
11接下来它会确定还有哪些数据块的副本没有达到指定数目并将这些数据块复制到其他Datanode上。 2.1.4 SNNSecondaryNameNode
1在非Ha模式下SNN一般是独立的节点周期完成对NN的EditLog向FsImage合并减少EditLog大小减少NN启动时间
2根据配置文件设置的时间间隔fs.checkpoint.period 默认3600秒
3根据配置文件设置edits log大小fs.checkpoint.size规定edits文件的最大值默认是64MB
Primary NameNode 和Secondary NameNode的数据合并流程如下图 2.2 主从架构分析 2.2.1 单节点主从架构分析 2.2.1.1 主从分析
1主从集群结构相对简单主与从协作
2主单点数据一致好掌握 2.2.1.2 主从架构问题
1单点故障集群整体不可用
2压力过大内存受限 2.3 解决方案 2.3.1 单点故障(HA集群方案) 2.3.1.1 总体架构 2.3.1.2 架构说明
HA使用active NameNode和standbyNameNode两个节点解决单点问题两个NameNode节点通过JournalNode集群共享状态通过ZKFC(**FailoverController**)选举active监控NameNode的状态实现自动备源DataNode会同时向两个NameNode节点发送心跳。 2.3.1.3 架构角色说明 2.3.1.3.1 NameNode active
1接受Client的rpc请求并处理自己写一份editlog同时向JournalNode集群发送一份editlog
2同时接受DataNode的块报告block report, 块位置更新block location updates和心跳heartbeat 2.3.1.3.2 NameNode standby
NameNode standby是NameNode active的一个热备一旦切换active状态可以及时对外提供服务
1同样的会接受JournalNode上面的editlog并执行更新与NameNode active的元数据保持同样的状态
2同时接受DataNode的块报告block report, 块位置更新block location updates和心跳heartbeat 2.3.1.3.3 JournalNode
用于同步active NameNode和standby NameNode之间的数据本身由一组JournalNode节点组成的集群一般是奇数保证高可用。 2.3.1.3.4 zkfc(FailoverController)
主要用来监控NameNode节点的健康状态zkfc会向zookeper集群发送心跳让自己被选举如果自己被选举主时会通过rpc调用NameNode让NameNode变成active状态。 2.3.1.3.5 ZooKeeper
ZooKeeper 分布式应用程序服务的组件接收zkfc心跳和NameNode注册信息选举出zkfc和NameNode的主。 2.3.2 压力过大内存受限(联帮机制Federation) 2.3.2.1 Federation 产生背景 2.3.2.1.1 单组Namenode架构
HDFS主要有两大模块
1、Namespace命名空间由目录、文件和块组成它支持所有命名空间相关的文件操作如创建、删除、修改查看所有文件和目录。 2、Block Storage Service块存储服务包括Block管理和存储两部分。 1Block管理: 通过控制注册以及阶段性的心跳来保证Datanode的正常运行处理Block的报告信息和维护块的位置信息支持Block相关的操作如创建、删除、修改、获取Block的位置信息管理Block的冗余信息、创建副本、删除多余的副本等。 2存储: Datanode提供本地文件系统上Block的存储、读写、访问等。 通常情况下单组Namenode能够满足集群大部分需求单点故障问题可以通过启用HA解决单组Namenode包含一主一备两个Namenode通过Zookeeper保障及控制Failover而Zookeeper本身具有高可用特性好像完全不用担心单点故障造成集群不可用的问题一切看起来似乎非常完美。然而随着集群规模不断的增长似乎又不是那么完美了。 2.3.2.1.2 单组Namenode局限性
单组Namenode只允许整个集群有一个活动的Namenode管理所有的命名空间。随着集群规模的增长在1000个节点以上的大型Hadoop集群中单组Namenode的局限性越发的明显主要表现在以下几个方面
1扩展性Namenode内存使用和元数据量正相关。180GB堆内存配置下元数据量红线约为7亿而随着集群规模和业务的发展即使经过小文件合并与数据压缩仍然无法阻止元数据量逐渐接近红线。 2可用性随着元数据量越来越接近7亿CMS GC频率也越来越高期间也曾发生过一次在CMS GC过程中由于大文件“get Block location”并发过高导致的promotion fail。 3性能随着集群规模增长Namenode响应的RPC QPS也在逐渐提高。越来越高并发的读写与Namenode的粗粒度元数据锁使Namenode RPC响应延迟和平均RPC队列长度都在慢慢提高。 4隔离性由于Namenode没有隔离性设计单一对Namenode负载过高的应用会影响到整个集群的服务能力
既然单组Namenode存在上述局限性那么为什么要通过Federation的方式横向拓展Namenode纵向拓展Namenode为什么不行不选择纵向拓展Namenode的原因主要体现在以下三个方面
1启动时间长Namenode启动需要将元数据加载到内存中具有128 GB Java Heap的Namenode启动一次大概需要40分钟到1个小时那512GB呢 2调试困难对大JVM Heap进行调试比较困难优化Namenode的内存使用性价比比较低。 3集群易宕机Namenode在Full GC时如果发生错误将会导致整个集群宕机。 2.3.2.1.3 为什么要引入Federation
1采用Federation的最主要的原因是简单Federation能够快速的解决大部分单Namenode的问题。
2Federation是简单鲁棒的设计由于联邦中各个Namenode之间是相互独立的。Federation整个核心设实现大概用了3.5个月。大部分改变是在Datanode、Config和Tools而Namenode本身的改动非常少这样Namenode的原先的鲁棒性不会受到影响。比分布式的Namenode简单虽然这种事先的扩展性比起真正的分布式的Namenode要小些但是可以迅速满足需求。
3Federation良好的向后兼容性已有的单Namenode的部署配置不需要进行太大的改变就可以继续工作。 2.3.2.2 Federation 介绍 2.3.2.2.1 Federation架构 为了水平扩展名称服务Federation使用多组独立的Namenodes/Namespaces。所有的Namenodes是联邦的也就是说他们之间相互独立且不需要互相协调各自分工管理自己的区域。Datanode被用作通用的数据块存储设备每个DataNode要向集群中所有的Namenode注册且周期性的向所有Namenode发送心跳和块报告并执行来自所有Namenode的命令。
Federation架构与单组Namenode架构相比主要是Namespace被拆分成了多个独立的部分分别由独立的Namenode进行管理。
Block Pool块池
1Block Pool允许一个命名空间在不通知其他命名空间的情况下为一个新的block创建Block ID。同时一个Namenode失效不会影响其下Datanode为其他Namenode服务。 2每个Block Pool内部自治也就是说各自管理各自的block不会与其他Block Pool交流。一个Namenode挂掉了不会影响其他NameNode。 3当Datanode与Namenode建立联系并开始会话后自动建立Block Pool。每个block都有一个唯一的标识这个标识我们称之为扩展块ID,在HDFS集群之间都是惟一的为以后集群归并创造了条件。 4Datanode中的数据结构都通过块池ID索引即Datanode中的BlockMapstorage等都通过BPID索引。 5某个Namenode上的NameSpace和它对应的Block Pool一起被称为NameSpace Volume。它是管理的基本单位。当一个NN/NS被删除后其所有Datanode上对应的Block Pool也会被删除。当集群升级时每个NameSpace Volume作为一个基本单元进行升级。
ClusterID 增加一个新的ClusterID来标识在集群中所有的节点。当一个Namenode被格式化的时候这个标识被指定或自动生成这个ID会用于格式化集群中的其它Namenode。 2.3.2.3 Federation主要优点 2.3.2.3.1 Namespace的可扩展性
HDFS的水平扩展但是命名空间不能扩展通过在集群中增加Namenode来扩展Namespace,以达到大规模部署或者解决有很多小文件的情况。 2.3.2.3.2 Performance性能
在之前的框架中单个Namenode文件系统的吞吐量是有限制的增加更多的Namenode能增大文件系统读写操作的吞吐量。 2.3.2.3.3 Isolation隔离
一个单一的Namenode不能对多用户环境进行隔离一个实验性的应用程序会加大Namenode的负载减慢关键的生产应用程序在多个Namenode情况下不同类型的程序和用户可以通过不同的Namespace来进行隔离。 2.3.2.4 Federation 主要缺点 1交叉访问问题
由于Namespace被拆分成多个且互相独立一个文件路径只允许存在一个Namespace中。如果应用程序要访问多个文件路径那么不可避免的会产生交叉访问Namespace的情况。比如MR、Spark任务都会存在此类问题。 2管理性问题
启用Federation后HDFS很多管理命令都会失效比如“hdfs dfsadmin、hdfs fsck”等除此之外“hdfs dfs cp/mv”命令同样失效如果要在不同Namespace间拷贝或移动数据需要使用distcp命令指定绝对路径。
2.3.2.5 Federation局限性
在解决NameNode扩展能力方面社区虽然提供了Federation但这个方案有很强的局限性
1HDFS路径Scheme需要变为ViewFsViewFs路径和其他Scheme路径互不兼容比如DistributedFileSystem无法处理ViewFs为Scheme的路径也就是说如果启用则需要将Hive meta、ETL脚本、MR/Spark作业中的所有HDFS路径均的scheme改为viewfs。 2如果将fs.defaultFS的配置从hdfs://ns1/变为viewfs://ns/将导致旧代码异常通过脚本对用户上万个源码文件的分析常用的HDFS路径风格多样包括hdfs:///user、hdfs://ns1/user、/user等如果fs.defaultFS有所更改hdfs:///user将会由于缺失nameservice变为非法HDFS路径。 3ViewFs路径的挂载方式与Linux有所区别 如果一个路径声明了挂载那么其同级目录都需要进行挂载比如/user/path_one挂载到了hdfs://ns1/user/path_one上那么/user/path_two也需要在配置中声明其挂载到哪个具体的路径上。 如果一个路径声明了挂载那么其子路径不能再声明挂载比如/user/path_one挂载到了hdfs://ns1/user/path_one上那么其子路径也自动并且必须挂载到hdfs://ns1/user/path_one上。
4一次路径请求不能跨多个挂载点 由于HDFS客户端原有的机制一个DFSClient只对应一个nameservice所以一次路径处理不能转为多个nameservice的多次RPC。
对于跨挂载点的读操作只根据挂载配置返回假结果。
对于跨挂载点的renamemove路径操作会抛出异常。
5Federation架构中NameNode相互独立NameNode元数据、DataNode中块文件都没有进行共享如果要进行拆分需要使用DistCp将数据完整的拷贝一份存储成本较高数据先被读出再写入三备份的过程也导致了拷贝效率的低效。
6Federation是改造了客户端的解决方案重度依赖客户端行为。方案中NameNode相互独立对Federation没有感知。另外HDFS为Scheme的路径不受Federation挂载点影响也就是说如果对路径进行了namespace拆分后如果因为代码中的路径或客户端配置没有及时更新导致流程数据写入老数据路径那么请求依然是合法但不符合预期的。 三、HDFS读写流程 3.1 写流程 HDFS客户端通过调用DistributedFileSystem# create来实现远程调用Namenode提供的创建文件操作Namenode在指定的路径下创建一个空的文件并为该客户端创建一个租约在续约期内将只能由这一个客户端写数据至该文件随后将这个操作记录至EditLog编辑日志。NameNode触发副本放置策略返回一个有序的DataNode列表客户端将使用这些信息创建一个标准的Hadoop FSDataOutputStream输出流对象。
HDFS客户端开始向HdfsData-OutputStream写入数据由于当前没有可写的BlockDFSOutputStream根据副本数向Namenode申请若干Datanode组成一条流水线来完成数据的写入。
客户端的数据以字节byte流的形式写入chunk以chunk为单位计算checksum校验和。若干个chunk组成packet数据以packet的形式从客户端发送到第一个Datanode再由第一个Datanode发送数据到第二个Datanode并完成本地写入以此类推直到最后一个Datanode写入本地成功可以从缓存中移除数据包packet。
客户端执行关闭文件后HDFS客户端将会在缓存中的数据被发送完成后远程调用Namenode执行文件来关闭操作。
Datanode在定期的心跳上报中以增量的信息汇报最新完成写入的BlockNamenode则会更新相应的数据块映射以及在新增Block或关闭文件时根据Block映射副本信息判断数据是否可视为完全持久化满足最小备份因子。
1Client和NameNode连接创建文件元数据
2NameNode判定元数据是否有效
3NameNode触发副本放置策略返回一个有序的DataNode列表
4Client和DataNode建立Pipeline连接
5Client将块切分成packet64KB并使用chunk512Bchucksum4B填充
6Client将packet放入发送队列dataqueue中并向第一个DataNode发送
7第一个DataNode收到packet后本地保存并发送给第二个DataNode
8第二个DataNode收到packet后本地保存并发送给第三个DataNode
9这一个过程中上游节点同时发送下一个packet 3.2 读流程 HDFS客户端远程调用Namenode查询元数据信息获得这个文件的数据块位置列表返回封装DFSIntputStream的HdfsDataInputStream输入流对象。
客户端选择一台可用Datanode服务器请求建立输入流。
Datanode向输入流中写原始数据和以packet为单位的checksum。
客户端接收数据。如遇到异常跳转至步骤2直到数据全部读出而后客户端关闭输入流。当客户端读取时可能遇到Datanode或Block异常导致当前读取失败。正由于HDFS的多副本保证DFSIntputStream将会切换至下一个Datanode进行读取。与HDFS写入类似通过checksum来保证读取数据的完整性和准确性。
1为了降低整体的带宽消耗和读取延时HDFS会尽量让读取程序读取离它最近的副本。
2如果在读取程序的同一个机架上有一个副本那么就读取该副本。
3如果一个HDFS集群跨越多个数据中心那么客户端也将首先读本地数据中心的副本。
好了今天的HDFS内容就分享到这里欢约大家点赞收藏有疑问也欢迎大家评论留言