数据处理技术-HDFS

本文详细介绍了HDFS(HadoopDistributedFileSystem)的作用、设计目标、NameNode和DataNode的角色,阐述了为何选择HDFS而非本地存储,以及HDFS的优点(高容错、数据复制、批处理优势)和缺点(不适合低延迟访问和小文件存储)。此外,还概述了HDFS写入数据的流程和使用方法。

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

如上一篇博客所讲,HDFS是Hadoop的一个组件。HDFS到底用来干甚么?为什么使用它?如何使用它?我将在本篇博客中详细赘述。

HDFS全称Hadoop Distributed File System,Hadoop我们已经知道了,后面的Distributed File System是个什么玩意儿?

分布式文件系统Distributed File System

这是一种文件系统的架构,允许用户在网络中的多台计算机上访问和处理存储的文件,就如同这些文件存储在本地计算机上一样。特点是有高度的可用性、可扩展性和性能。
除了HDFS,还有GFS(Google File System), EFS(Amazon Elatic File System)等等。
分布式文件系统在物理结构上是由计算机集群中的多个节点构成的,这些节点分为两类:

  • 主节点/名称节点 - Master Node/ NameNode
  • 从节点/数据节点 - Slave Node/ DataNode
    需要注意的一点,如果你使用主节点这个叫法,那么必须配合使用从节点;反过来也是。
    请添加图片描述

设计目标

分布式文件系统的设计目标主要包括透明性、并发控制、可伸缩性、容错以及安全需求等。
对于HDFS来说:

  • 可以提供一定程度的访问透明性,完全支持位置透明性和伸缩透明性。——透明性。
    - 访问透明性:用相同的操作访问本地资源和远程资源
    - 位置透明性:不需要知道资源的物理或网络位置就能够访问它们。
    - 伸缩透明性:系统和应用能够进行拓展而不改变系统结构或应用算法。
  • 并发控制的机制非常简单,任何时间都只允许有一个程序在写入某个文件(也就是说上锁了)。——并发控制。
  • 建立在大规模廉价机器上的分布式文件系统集群,具有很好的可伸缩性(支持节点的动态加入或退出)——可伸缩性。
  • 采用多副本机制,一个文件拥有在不同位置的多个副本。并且采取故障自动检测、恢复机制。——容错性。
  • 采用Java语言开发,具有很好的跨平台能力。可以在不同的操作系统和计算机上实现同样的客户端和服务器程序。——硬件和操作系统的异构性。

HDFS中的NameNode和DataNode

  • NameNode负责管理分布式文件系统的命名空间,它不存储实际的数据块,但维护关于文件系统中所有文件的元数据信息。保存了两个核心的数据结构:FsImage和EditLog。
  • DataNode负责数据的存储和读取,也就是数据实际存放的节点。
  • FsImage: 用于存储关于整个文件系统的完整元数据快照。FsImage包含了HDFS中所有文件的详细元数据信息,包括文件的权限、结构、数据块的位置等。FsImage是HDFS核心元数据的静态表示,被用于持久化存储和系统恢复。
  • EditLog: 记录所有对文件系统元数据的修改活动。
    请添加图片描述

HDFS用来干甚么?

HDFS是Hadoop数据存储管理的基础。也就是说,它的作用是用来保存数据的。

为什么不能保存在本地?

如果数据集比较小或者简单的应用场景,那么保存在本地然后进行数据处理是完全可以的。但是我们之所以用Hadoop不就是因为数据量足够大、数据处理需求足够多吗?你说,啊但是我一台电脑也能达到几个T的空间啊,大不了就多加几个盘,再不行我多加一个NaS,几百个T呢。朋友,你的想法太单纯了!还记得之前博客说的吗,大数据起点单位是PB,1PB=1024TB,比T多了整整一个数量级。光空间这块,你拿什么和HDFS比?已经完败了!更不用说HDFS还有更高的容错性与可用性。一个节点数据丢失了,还有其他节点的备份。对于本地计算机来说,谁有意识将同一个数据在不同的盘里放备份?HDFS直接帮你做了这一步!(但是相对应的,如果你设置3个备份,理论上实际能存放的数据只能到整体空间的1/3)

为什么使用HDFS?

前面一个小节其实已经简单说明了原因。为了让大家更清晰HDFS的强大之处,还是要仔细说说使用HDFS的原因。
之所以选择HDFS存储数据,因为HDFS具有以下优点:

  1. 高容错性
    数据自动保存多个副本。通过增加副本的形式提高容错性。某一个节点副本丢失之后,它可以自动恢复。数据节点会通过周期性的心跳和块报告定期和名称节点通信。

    • 心跳信号的间隔默认约为每3秒一次。心跳不仅表明DataNode的健康状态,也是DataNode向NameNode报告自己还在活动的机制。DataNode向上级NameNode打卡自己没有摸鱼,在正常工作。
    • 如果NameNode检测到某个DataNode长时间未发送心跳,它会认为该DataNode已经失效,所有存储在失效DataNode上的数据块将被标记为需要复制,并触发复制因子(复制因子:HDFS默认将每个数据块复制3份,通常1个副本存放在本地节点,另外2个副本存放在不同的机架上的其他节点;这个复制因子是可手动配置的)修复流程,以将副本数恢复到正常水平。
    • 块报告通常是每小时一次。块报告包含了该DataNode上所有HDFS数据块的详细列表。通过这些报告,NameNode可以了解整个文件系统的块位置和存储信息。
    • 块报告包括每个数据块的块ID和块元数据,如版本信息和时间戳等。这些信息帮助NameNode维护整个HDFS的元数据,并确保数据分布的一致性和正确性。
    • NameNode使用收到的块报告来更新其全局视图,确保数据一致性。如果发现某个数据块的副本数低于预设的复制因子,NameNode将指示其他DataNode创建更多副本,以满足冗余要求。
      请添加图片描述
  2. 适合批处理
    移动计算而不是移动数据。与其将大量数据传输到计算资源所在的位置,不如将计算任务发送到存储数据的节点上去执行。这样做的好处是可以显著减少网络带宽的消耗,提高整体处理效率,特别是在处理大规模数据集时。

    • 在实际的Hadoop集群中,NameNode在调度MapReduce等作业时,会尽可能地选择存有所需数据块的DataNode或与该DataNode网络距离较近的节点来执行任务。这样做可以最大限度地利用数据本地性,减少计算过程中数据移动的需要。
  3. 适合大数据处理
    前面已经说了,因为它是搭建在一个计算机集群当中的。能处理的数据大小,主要取决于集群空间大小,当然,为了处理某个数据而扩充集群也是可以的。

  4. 流式文件访问
    一次写入,多次读取。文件一旦写入不能修改,只能追加。这样可以保证数据的一致性。

    • 如果你需要修改一个已经上传的文件,最直接的方法是在本地进行修改,然后将修改后的文件重新上传到HDFS,覆盖原有文件或作为一个新文件保存。
    • 虽然HDFS默认不允许修改文件中的内容,但它允许在现有文件的末尾追加数据。如果你的需求仅限于向文件末尾添加数据,可以利用这一特性。
    • 在HDFS中,对文件的任何更新或追加操作都会自动应用到该文件的所有副本。也就是说,如果你上传了一个修改过的文件覆盖原文件,或者在原文件上进行了追加操作,HDFS将自动更新所有的副本,以保证数据的一致性和可靠性。
  5. 可构建在廉价机器上
    便宜啊,实惠啊。

HDFS缺点

提到了优点,也必须得说一下缺点。毕竟不能一味地吹嘘某个东西很好,要客观看待事物。

  1. 不适合低延时数据访问。
    因为hdfs被设计为支持大数据处理,特别优化了高吞吐量的数据访问,而不是低延时。这意味着它非常不适合于快速的随机访问。并且因为副本机制,任何对文件的读写操作都可能涉及跨多个节点的网络通信。尤其是写操作,需要将数据块同时写入多个节点,确保所有副本都同步更新,这增加了操作的延时。
  2. 不适合小文件存储。
    • 每个文件和每个数据块在HDFS中都有相应的元数据(如权限信息、块的位置等),这些元数据存储在NameNode的内存中。如果有大量的小文件,每个文件和它的数据块都需要相应的元数据,这会消耗大量的内存资源。对于NameNode而言,内存是一个宝贵的资源,过多的小文件将极大地增加NameNode的内存压力,降低系统的效率。
    • 并且,在HDFS中,文件默认被分割成至少一个数据块(默认大小为128MB或256MB)。对于小于块大小的文件,它们不会占满一个完整的数据块,但每个文件仍然至少被存储为一个数据块。如果有大量小文件,会造成大量的数据块未被充分利用,这种空间的浪费会导致存储效率低下。
    • 对于1MB的文件存储在HDFS中,默认块大小为128MB的情况下,该文件只会占用1MB的实际存储空间,并不会占满整个128MB的数据块。每个块的大小定义了该块可以占用的最大空间,但实际使用的空间取决于文件的实际大小。
      这意味着,尽管块的容量是128MB,但如果文件只有1MB,那么只有1MB的空间被使用,剩余的127MB空间在该块中仍然可用,但不能用于存储其他文件的数据。这是因为在HDFS中,一个文件的数据块不会与另一个文件共享。因此,对于包含许多小文件的系统来说,这种方式可能导致存储效率低下,因为大量的存储空间没有被充分利用。
  3. 不允许文件随机修改
    这也是前面提到的,因为要保证数据的一致性。

HDFS写入数据流程

这是一个涉及客户端、NameNode和DataNodes之间交互的过程。具体的步骤如下:

步骤1: 客户端请求

  • 开始写入:当用户或应用程序决定写入数据到HDFS时,客户端发起一个写操作请求。这通常通过使用Hadoop的API,如在Java程序中使用FileSystem.create()方法或通过Hadoop的命令行工具。

步骤2: 与NameNode交互

  • 获取权限和位置:客户端首先与NameNode通信以获取写数据的权限。如果用户有权写入数据,NameNode会进行下一步。
  • 查找DataNode:NameNode选择一组DataNode来存储将要写入的数据块。选择标准基于DataNode的可用性、存储空间和距离客户端的近程原则。

步骤3: 写数据到DataNodes

  • 数据流管道:NameNode回复客户端,提供一组可以写入数据块的DataNodes的地址。客户端直接与这些DataNode建立连接,并按照NameNode指定的顺序,形成一个“管道”。
  • 数据块写入:客户端将数据分割成多个块(默认大小如128MB或256MB),然后按顺序发送到管道中的第一个DataNode。每个DataNode接收到块数据后,存储该数据块的副本,并将数据块转发给管道中的下一个DataNode。这个过程一直持续到所有选定的DataNodes都接收到数据块。

步骤4: 确认和关闭

  • 写入确认:每个DataNode写入数据后会向客户端发送确认。一旦所有的DataNodes都成功写入它们的数据块并确认,客户端完成这个数据块的写操作。
  • 完成操作:当所有数据块都被写入后,客户端通知NameNode写操作已经完成,NameNode随后更新元数据,包括新写入文件的数据块列表和它们的位置。

如何使用HDFS?

两种方式。一种是客户端直接通过cmd和hdfs取得联系。两外一种是通过Java API,编写Java代码来和hdfs取得联系。

shell命令和Linux命令是基本一致的,需要在命令前面加一个‘-’,并且写出是hdfs
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ayu阿予

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值