HDFS体系结构,优缺点,可靠性和文件读写

本文深入探讨Hadoop分布式文件系统(HDFS)的产生背景、体系结构、读写流程及优缺点,解析其高容错性、适合大数据处理和流式文件访问的特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

产生背景

以文件为基本存储单位的缺点

  1. 文件大小不同,难以实现负载均衡。
  2. 处理一个文件时,只能利用一个节点资源,无法动用集群。

HFDS的定义

  • 源自于Google的GFS论文
  • 发表于2003年10月
  • HDFS是GFS克隆版
  • Hadoop Distributed File System
  • 易于扩展的分布式文件系统
  • 运行在大量普通廉价机器上,提供容错机制
  • 为大量用户提供性能不错的文件存取服务

体系结构

DFS是一个主/从(Mater/Slave)体系结构,从最终用户的角度来看,它就像传统的文件系统一样,可以通过目录路径对文件执行CRUD(Create、Read、Update和Delete)操作。但由于分布式存储的性质,HDFS集群拥有一个NameNode和一些DataNode。NameNode管理文件系统的元数据(关于数据的数据),DataNode存储实际的数据。客户端通过同NameNode和DataNodes的交互访问文件系统。客户端联系NameNode以获取文件的元数据,而真正的文件I/O操作是直接和DataNode进行交互的。 下图为HDFS总体结构示意图
在这里插入图片描述

1.1.1 NameNode

NameNode可以看作是分布式文件系统中的管理者,主要负责管理文件系统的命名空间、集群配置信息和存储块的复制等。NameNode会将文件系统的Meta-data存储在内存中,这些信息主要包括了文件信息、每一个文件对应的文件块的信息和每一个文件块在DataNode的信息等。
Master节点,只有一个,管理HDFS的名称空间,管理数据块映射信息、配置副本策略、处理客户端读写请求。

1.1.2 Secondary namenode

并非NameNode的热备; 辅助NameNode,分担其工作量; 定期合并fsimage和edits,推送给NameNode; 在紧急情况下,可辅助恢复NameNode。

1.1.3 DataNode

DataNode是文件存储的基本单元,它将Block存储在本地文件系统中,保存了Block的Meta-data,同时周期性地将所有存在的Block信息发送给NameNode。
Slave节点,存储实际的数据块 执行数据块读/写

1.1.4 Client

文件切分;与NameNode交互,获取文件位置信息; 与DataNode交互,读取或者写入数据; 管理HDFS; 访问HDFS。

1.1.5 文件写入

  1. Client向NameNode发起文件写入的请求。
  2. NameNode根据文件大小和文件块配置情况,返回给Client它所管理部分DataNode的信息。
  3. Client将文件划分为多个Block,根据DataNode的地址信息,按顺序写入到每一个DataNode块中。

1.1.6 文件读取

  1. Client向NameNode发起文件读取的请求。
  2. NameNode返回文件存储的DataNode的信息。
  3. Client读取文件信息。

HDFS典型的部署是在一个专门的机器上运行NameNode,集群中的其他机器各运行一个DataNode;也可以在运行NameNode的机器上同时运行DataNode,或者一台机器上运行多个DataNode。一个集群只有一个NameNode的设计大大简化了系统架构。

fsimage和edits

  1. NameNode中两个很重要的文件,

  2. fsimage是元数据镜像文件(保存文件系统的目录树);edits是元数据操作日志(记录每次保存fsimage之后到下次保存之间的所有hdfs操作)。

  3. 内存中保存了最新的元数据信息(fsimage和edits)。

  4. edits过大会导致NameNode重启速度慢,Secondary NameNode负责定期合并它们。

    合并的流程图:
    在这里插入图片描述

数据块的映射关系

  1. 包括两种:文件与数据块映射关系,DataNode与数据块映射关系;
  2. NameNode启动的时候,可通过心跳信息重构映射信息,DataNode运行过程中定时汇报当前block信息;映射关系保存在NameNode内存中。
  3. NameNode重启速度慢(需要加载通过合并fsimage与edits文件生成的最新目录树以及DataNode的块信息)

数据块(block)

  1. 在HDFS中,文件被切分成固定大小的数据块,默认大小为64MB,也可自己配置。
  2. 为何数据块如此大,因为数据传输时间超过寻道时间(高吞吐率)。
  3. 文件的存储方式:按大小被切分成若干个block,存储到不同节点上,默认情况下每个block有三个副本。
    对于block块的恢复详细信息可以查看如下blog
    http://blog.youkuaiyun.com/macyang/article/details/7983188

HDFS的默认副本存放策略

Hadoop 0.17 之后:副本1-同Client的节点上;副本2-不同机架中的节点上;副本3-同第二个副本的机架中的另一个节点上;其他副本:随机挑选。如下图示例:
在这里插入图片描述

HDFS优缺点

优势

  1. 高容错性

    数据自动保存多个副本。它通过增加副本的形式,提高容错性。
    某一个副本丢失以后,它可以自动恢复,这是由 HDFS 内部机制实现的。

  2. 适合批处理

    它是通过移动计算而不是移动数据。
    它会把数据位置暴露给计算框架。

  3. 适合大数据处理

    处理数据达到 GB、TB、甚至PB级别的数据。
    能够处理百万规模以上的文件数量,数量相当之大。
    能够处理10K节点的规模。

  4. 流式文件访问

    一次写入,多次读取。文件一旦写入不能修改,只能追加。
    它能保证数据的一致性。

  5. 可构建在廉价机器上

    它通过多副本机制,提高可靠性。
    它提供了容错和恢复机制。比如某一个副本丢失,可以通过其它副本来恢复。

劣势

  1. 低延时数据访问

    比如毫秒级的来存储数据,它做不到。
    它适合高吞吐率的场景,就是在某一时间内写入大量的数据。

  2. 小文件存储

    存储大量小文件(这里的小文件是指小于HDFS系统的Block大小的文件(默认64M))的话,它会占用 NameNode大量的内存来存储文件、目录和块信息。这样是不可取的,因为NameNode的内存总是有限的。
    小文件存储的寻道时间会超过读取时间,它违反了HDFS的设计目标。

  3. 并发写入、文件随机修改

    一个文件只能有一个写,不允许多个线程同时写。
    仅支持数据 append(追加),不支持文件的随机修改。

HDFS可靠性机制

常见错误情况:文件损坏;网络或者机器失效;NameNode挂掉;
文件的完整性:通过CRC32校验,如果有损坏,用其他副本替代损坏文件;
Heartbeat:DataNode定期向NameNode发送heartbeat;
元数据信息:FsImage、Editlog进行多份备份,当NameNode宕机后,可手动还原。

HDFS物理网络环境

在这里插入图片描述

HDFD的读写流程

这个网站很详细很好:http://bradhedlund.com/2011/09/10/understanding-hadoop-clusters-and-the-network/

HDFS文件读取:
在这里插入图片描述

  1. 首先调用FileSystem对象的open方法,其实是一个DistributedFileSystem的实例
  2. DistributedFileSystem通过rpc获得文件的第一批个block的locations,同一block按照重复数会返回多个locations,这些locations按照hadoop拓扑结构排序,距离客户端近的排在前面.
  3. 前两步会返回一个FSDataInputStream对象,该对象会被封装成DFSInputStream对象,FSDInputStream可以方便的管理datanode和namenode数据流。客户端调用read方法,FSDInputStream最会找出离客户端最近的datanode并连接。
  4. 数据从datanode源源不断的流向客户端。
  5. 如果第一块的数据读完了,就会关闭指向第一块的datanode连接,接着读取下一块。这些操作对客户端来说是透明的,客户端的角度看来只是读一个持续不断的流。
  6. 如果第一批block都读完了,FSDInputStream就会去namenode拿下一批blocks的location,然后继续读,如果所有的块都读完,这时就会关闭掉所有的流。

HDFS读取发生异常处理

如果在读数据的时候,FSDInputStream和datanode的通讯发生异常,就会尝试正在读的block的排第二近的datanode,并且会记录哪个datanode发生错误,剩余的blocks读的时候就会直接跳过该datanode。FSDInputStream也会检查block数据校验和,如果发现一个坏的block,就会先报告到namenode节点,然后FSDInputStream在其他的datanode上读该block的镜像
HDFS读操作设计思考
客户端直接连接datanode来检索数据并且namenode来负责为每一个block提供最优的datanode,namenode仅仅处理block location的请求,这些信息都加载在namenode的内存中,hdfs通过datanode集群可以承受大量客户端的并发访问。

HDFS文件写入

在这里插入图片描述

如果在写的过程中某个datanode发生错误,会采取以下几步:
1. pipeline被关闭
2. 为了防止丢包,ack quene里的packet会同步到data quene
3. 把产生错误的datanode上当前在写但未完成的block删
4. block剩下的部分被写到剩下的两个正常的datanode
5. namenode找到另外的datanode去创建这个块的复制
这些操作对客户端来说是无感知的。
(客户端执行write操作后,写完的block才是可见的,正在写的block对客户端是不可见的,只有调用sync方法,客户端才确保该文件被写操作已经全部完成,当客户端调用close方法时会默认调用sync方法。是否需要手动调用取决你根据程序需要在数据健壮性和吞吐率之间的权衡。)

HDFS与其他系统的结合

1)HDFS与MapReduce结合
MapReduce作业的输入数据来自HDFS,最终结果也写入HDFS
Mapreduce和HDFS是低耦合的,Mapreduce可以与其他分布式系统结合。HDFS之上可以是其他框架。
2)HDFS与Hbase结合
HDFS为Hbase提供可靠的数据存放服务(操作日志文件WAL和数据索引文件HFile等)


原文链接:https://blog.youkuaiyun.com/woshiwanxin102213/article/details/19990487

<think>好的,我现在需要回答用户关于HDFSHadoop中的作用以及如何通过Shell命令、Web界面Java API进行操作的问题。用户还提到具体的版本环境:Hadoop 3.3.5、Ubuntu 16.04、JDK 1.8、Eclipse,以及需要实验教程。首先,我应该先明确HDFS的核心作用,然后分步骤讲解不同操作方法,并确保命令代码正确,符合用户的环境。 首先,HDFS的作用。HDFSHadoop的分布式文件系统,设计用于存储大量数据,具有高容错性,适合部署在廉价硬件上。它通过数据分块、复制分布式存储来实现高可靠性高吞吐量。需要简明扼要地解释这些点,可能还要提到主从架构,NameNodeDataNode的作用。 接下来是Shell命令操作。用户需要具体的命令示例,比如hdfs dfs -ls,-mkdir,-put,-get,-cat,-rm等。注意Hadoop 3.3.5的Shell命令可能与旧版略有不同,但基本命令应该一致。需要确保命令正确,并给出每个命令的说明示例。 然后是Web界面访问。Hadoop 3.x的Web界面默认端口可能旧版不同,比如NameNode的Web UI端口是9870,而旧版是50070。需要确认Hadoop 3.3.5的具体端口,并指导用户如何通过浏览器访问,查看集群状态、存储情况等。 Java API操作部分,用户可能需要一个简单的示例代码,比如创建文件读写数据等。需要确保代码兼容Hadoop 3.3.5,并且使用正确的依赖版本。可能需要提到在Eclipse中配置项目,添加Hadoop的JAR文件,处理可能的依赖冲突,比如使用hadoop-common、hadoop-hdfs等依赖,或者Maven配置。注意Hadoop 3.x的API可能有一些变化,比如使用ConfigurationFileSystem类的方法。 实验教程部分需要分步骤指导,包括环境准备(安装Hadoop、配置环境变量、格式化HDFS)、Shell操作步骤、Web访问步骤、Java API开发步骤(创建项目、编写代码、运行)。可能需要提醒用户确保Hadoop服务正在运行,如NameNodeDataNode,以及可能的权限问题,比如在Shell命令中可能需要使用hdfs用户操作。 还需要注意引用用户提供的参考内容中的解压Hadoop的部分,可能需要在环境准备部分提到解压配置步骤,引用[^1]中的解压命令,但用户提供的引用是关于Hadoop 3.2.0的,而用户现在用的是3.3.5,但步骤应该是类似的,所以可以引用那个步骤。 在写作过程中,要确保使用正确的LaTeX格式,行内公式用$...$,独立公式用$$...$$,但这个问题可能不涉及数学公式,所以可能不需要。但如果有变量或代码文件名,可能需要用行内代码格式。同时,生成相关问题,比如关于HDFS原理、不同操作方式的优缺点、故障处理等。 最后,检查所有步骤是否正确,命令代码是否适用于指定版本,特别是Hadoop 3.3.5是否有特别需要注意的地方,比如端口号变化或API变动。例如,Hadoop 3.x默认使用端口9870,而之前的版本使用50070,这点需要确认。另外,Java API中FileSystem的获取方式是否有变化,比如推荐使用FileSystem.get(URI, Configuration)等方法。 可能需要提醒用户注意Hadoop配置文件(core-site.xml, hdfs-site.xml)的正确配置,如fs.defaultFS指向正确的NameNode地址,以及Hadoop的环境变量设置,如JAVA_HOME是否正确指向JDK 1.8。 总结回答结构:先介绍HDFS的作用,然后分Shell、Web、Java API三个部分讲解操作步骤,每个部分给出具体示例注意事项,最后提供实验教程步骤相关问题。</think>### HDFSHadoop中的作用及操作方法 #### 一、HDFS的核心作用 HDFSHadoop Distributed File System)是Hadoop的分布式文件系统,设计用于存储超大规模数据集(TB/PB级),具有高容错性、高吞吐量可扩展性。其核心特性包括: 1. **分布式存储**:数据被分割为块(默认128MB)并分布在集群节点上。 2. **冗余备份**:每个数据块默认保存3个副本,保障容错性。 3. **主从架构**: - **NameNode**:管理元数据(如文件目录结构、块位置)。 - **DataNode**:存储实际数据块并定期向NameNode报告状态。 #### 二、HDFS操作方式 ##### 1. Shell命令操作 通过`hdfs dfs`命令直接操作HDFS,常用命令如下: ```bash # 查看HDFS根目录内容 hdfs dfs -ls / # 创建目录 hdfs dfs -mkdir /user/test # 上传本地文件HDFS hdfs dfs -put local_file.txt /user/test/ # 下载HDFS文件到本地 hdfs dfs -get /user/test/hdfs_file.txt ./download/ # 查看文件内容 hdfs dfs -cat /user/test/hdfs_file.txt # 删除文件或目录 hdfs dfs -rm /user/test/hdfs_file.txt hdfs dfs -rm -r /user/test ``` ##### 2. Web界面访问 Hadoop 3.3.5的Web界面默认端口为: - **NameNode状态**:`http://<namenode_ip>:9870` 可查看集群存储使用情况、DataNode状态及文件浏览(如下图)。 ![HDFS Web界面](https://example.com/hdfs-web.png) ##### 3. Java API操作 在Eclipse中配置Hadoop依赖(需`hadoop-common`、`hadoop-hdfs`等JAR包),示例代码: ```java import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; public class HDFSOperations { public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); conf.set("fs.defaultFS", "hdfs://localhost:9000"); try (FileSystem fs = FileSystem.get(conf)) { // 创建目录 fs.mkdirs(new Path("/user/test_java")); // 上传文件 fs.copyFromLocalFile( new Path("localfile.txt"), new Path("/user/test_java/hdfsfile.txt") ); // 下载文件 fs.copyToLocalFile( new Path("/user/test_java/hdfsfile.txt"), new Path("downloaded.txt") ); } } } ``` #### 三、实验教程步骤(Hadoop 3.3.5 + Ubuntu 16.04) 1. **环境准备**: - 解压Hadoop安装包: `tar -zvxf hadoop-3.3.5.tar.gz` - 配置`JAVA_HOME`(JDK 1.8)Hadoop环境变量。 - 格式化HDFS: `hdfs namenode -format` 2. **启动HDFS服务**: ```bash # 启动NameNodeDataNode sbin/start-dfs.sh ``` 3. **Shell命令实践**: 按第二部分示例逐步执行命令操作文件。 4. **Web界面验证**: 浏览器访问`http://localhost:9870`,确认文件是否上传成功。 5. **Java API开发**: - 在Eclipse中创建Java项目,导入Hadoop依赖。 - 编写并运行上述示例代码,检查本地与HDFS文件同步。 #### 四、常见问题处理 - **端口冲突**:若Web界面无法访问,检查`hdfs-site.xml`中`dfs.namenode.http-address`配置。 - **权限错误**:在Shell命令前添加`sudo -u hdfs`或修改HDFS目录权限: `hdfs dfs -chmod 777 /user`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值