HDFS(分布式文件管理系统)什么是文件管理系统1 文件系统: 文件系统是一种存储和组织计算机数据的方法它使得对其访问和查找变得容易。2 文件名 : 在文件系统中文件名是用于定位存储位置。3 元数据Metadata:保存文件属性的数据如文件名文件长度文件所属用户组文件存储位置等。4 数据块Block:存储文件的最小单元。对存储介质划分了固定的区域使用时按这些区域分配使用。HDFS产生背景随着数据量的增加在一个操作系统存不下所有的数据那么久分配到更多的操作系统管理的磁盘中但将数据分散的存储在不同的操作系统中不便于管理和维护迫切需要一种系统来管理多台机器上的文件这就是分布式文件管理系统。HDFS只是分布式文件管理系统中的一种HDFS 优缺点优点:高容错性认为硬件总是不可靠的(提供副本机制,默认副本数是3)高吞吐量为大量数据访问的应用提供高吞吐量支持大文件存储支持存储TB-PB级别的数据缺点:低时间延迟数据访问的应用例如几十毫秒范围原因HDFS是为高数据吞吐量应用优化的这样就会造成以高时间延迟为代价大量小文件原因NameNode启动时将文件系统的元数据加载到内存因此文件系统所能存储的文件总数受限于NameNode内存容量,那么需要的内存空间将是非常大的。HDFS架构HDFS架构包含三个部分NameNode:名称节点NameNode是HDFS中最重要的进程它负责管理文件系统的命名空间、数据块映射以及数据块的位置信息。每个HDFS集 群只有一个活动的NameNode进程多个备份节点用于提高可用性。DataNode:数据节点DataNode是存储实际数据的进程它将文件划分为数据块并负责存储和检索这些数据块。每台机器上都会运行一个DataNode进程它们与NameNode进行通信以更新块列表和报告状态secondarynamenode:第二名称节点SecondaryNameNode并不是NameNode的备份节点它主要负责定期合并NameNode的编辑日志EditLog和镜像文 件FsImage以减少NameNode故障时的恢复时间。一、HDFS 写数据流程上传文件1.业务应用调用HDFS Client提供的API请求写入文件。2.HDFS Client(客户端)联系NameNodeNameNode在元数据中创建文件节点。3.业务应用调用write API写入文件。4.HDFS Client收到业务数据后从NameNode获取到数据块编号、位置信息后联系DataNode并将需要写入数据的5.DataNode建立起流水线。完成后客户端再通过自有协议写入数据到DataNode1再由DataNode1复制到DataNode2, DataNode3。6.写完的数据将返回确认信息给HDFS Client。7.所有数据确认完成后业务调用HDFS Client关闭文件。8.业务调用close, flush后HDFSClient联系NameNode确认数据写完成NameNode持久化元数据。假设客户端执行命令hdfs dfs -put local.txt /input/详细步骤创建文件请求Client向NameNode发起创建文件请求create。NameNode检查目标路径是否存在、客户端是否有写权限等。若通过NameNode在元数据中记录新文件信息此时文件块列表为空。建立数据流管道PipelineClient向NameNode询问“文件第一个块Block应该存放在哪些DataNode上”NameNode根据机架感知策略Rack Awareness返回一组DataNode地址默认3个副本。策略第1个副本放在本地节点若客户端在集群内或随机节点第2个副本放在不同机架的节点第3个副本放在与第2个副本同机架的不同节点。Client与最近的DataNodeDN1建立TCP连接DN1与DN2建立连接DN2与DN3建立连接形成一条流水线Pipeline。数据分块与写入Client将文件切分为多个数据包Packet默认64KB。Client将第一个Packet发送给DN1。DN1收到后立即缓存并转发给DN2DN2同样缓存并转发给DN3。这个过程是流式并行的。确认机制ACK每个DataNode在成功写入一个Packet后会向上游发送一个ACK确认包。当Packet经过整个Pipeline回到Client时Client才认为该Packet写入成功。如果某个DataNode写入失败Pipeline会被关闭NameNode会重新分配新的DataNode继续写入保证副本数。关闭文件与元数据更新当一个Block写满默认128MBClient会请求NameNode分配下一个Block的DataNode列表重复步骤2-4。所有数据块写完后Client调用close()方法。NameNode将文件的块列表、副本位置等元数据持久化到FsImage中完成文件创建。Client - NameNode (请求创建文件)Client - DN1 - DN2 - DN3 (建立Pipeline)Client - DN1 [Packet1] - DN2 [Packet1] - DN3 [Packet1]- ACK1 - ACK1 - ACK1 (确认)... (循环直到Block写完)Client - NameNode (更新元数据)二、HDFS 读数据流程下载文件1.业务应用调用HDFS Client提供的API打开文件。2.HDFS Client联系NameNode获取到文件信息数据块、DataNode位置信息。3.业务应用调用read API读取文件。4.HDFS Client根据从NameNode获取到的信息联系DataNode获取相应的数据块。(Client采用就近原则读取数据)。5.HDFS Client会与多个DataNode通讯获取数据块。6.数据读取完成后业务调用close关闭连接。假设客户端执行命令hdfs dfs -get /input/file.txt ./详细步骤文件定位请求Client向NameNode发起打开文件请求open。NameNode返回文件的块列表及每个块的位置信息即存放该块的DataNode地址。注意NameNode只返回有该块副本的DataNode列表按距离Client的远近排序本地 同机架 不同机架。选择DataNode读取Client根据返回的列表选择最近的一个DataNode网络拓扑距离最短建立连接开始读取数据。读取单位是PacketClient会校验数据的完整性通过校验和。跨块读取读完一个Block后Client关闭与当前DataNode的连接。向NameNode询问下一个Block的位置连接到新的DataNode继续读取。这个过程对Client是透明的看起来像在读一个连续的文件流。异常处理如果读取某个DataNode失败如节点宕机Client会尝试从其他存有该副本的DataNode读取并通知NameNode该节点异常。Client - NameNode (请求文件块位置)NameNode - Client (返回Block1: DN1,DN2,DN3; Block2: DN2,DN4...)Client - DN1 (读取Block1)Client - DN2 (读取Block2)... (直至读完所有块)常用指令1. 文件/目录增删改查# 1. 查看目录内容hdfs dfs -ls /inputhdfs dfs -ls -R /input # 递归查看查看子目录# 2. 创建目录hdfs dfs -mkdir /testhdfs dfs -mkdir -p /data/log/2024 # 递归创建多级目录# 3. 上传文件本地 → HDFShdfs dfs -put local.txt /input/hdfs dfs -copyFromLocal local.txt /input/ # 同上正式环境常用hdfs dfs -moveFromLocal local.txt /input/ # 上传后删除本地文件# 4. 下载文件HDFS → 本地hdfs dfs -get /input/file.txt ./local/hdfs dfs -copyToLocal /input/file.txt ./local/# 5. 查看文件内容hdfs dfs -cat /input/file.txthdfs dfs -text /input/file.txt.gz # 自动识别压缩格式如gz、seqhdfs dfs -tail /input/file.txt # 查看文件尾部常用于看日志# 6. 删除文件/目录hdfs dfs -rm /input/test.txthdfs dfs -rm -r /input/tmp # 递归删除目录慎用hdfs dfs -rm -skipTrash /input/tmp # 直接删除不经过回收站# 7. 复制/移动HDFS内部hdfs dfs -cp /input/a.txt /output/hdfs dfs -mv /input/a.txt /output/b.txt# 8. 统计文件大小hdfs dfs -du -h /input # 人性化显示大小hdfs dfs -df -h / # 查看HDFS总磁盘使用情况2. 权限与属性管理# 修改权限类似Linux chmodhdfs dfs -chmod 755 /inputhdfs dfs -chmod -R 777 /test # 递归修改# 修改属主/属组hdfs dfs -chown user1:group1 /input/file.txthdfs dfs -chgrp group1 /input/file.txt# 修改副本数针对已有文件hdfs dfs -setrep -w 2 /input/file.txt # 修改为2个副本-w等待完成hdfs dfs -setrep -R 3 /data # 递归修改目录下所有文件