文章链接
HDFS 特征
分布式存储
HDFS 以分布式方式存储数据,它将数据分成小块, 并将其存储在集群的不同节点上。这种方式下, Hadoop 分布式文件系统提供了一种映射(MapReduce)减少处理大数据子集的方法,分为更小的碎片,存储在多个节点上并行执行。MapReduce 是 Hadoop 的核心,但 HDFS 提供了所有这些功能。
Block 块
HDFS 将大文件分割成为块的小块,块是文件系统中最小的数据单元,每个块存储在不同的节点上,每个块的默认副本为 3 个,一个块的每个副本存储在不同的节点上,以提供容错功能,这些块在不同节点上的位置由NameNode决定,客户机和管理员在块的位置上没有任何控制权。
HDFS 默认块大小为 128 MB,可以根据需要增加,这与块大小为 4 KB 的OS文件系统不同。如果数据大小比HDFS 的块小,则块大小等于数据大小。例如,如果文件大小为 129 MB,为其创建 2 个块,一个块的默认大小为 128 MB,另一个块的大小仅为 1 MB,而不是 128 MB,因为这样会浪费空间。Hadoop 很智能,不会浪费掉127 MB 的剩余空间,所以它只为 1 MB 数据分配 1 MB 块。
这样存储数据的主要优点,是节省磁盘搜索时间,另一个优点是在映射器一次处理一个块的情况下进行处理。
复制
Hadoop HDFS 为每个块创建副本,所有块被复制并存储在集群的不同节点上,它试图在每个Rack(机架)上放置至少一个副本。
什么是 Rack(机架) ?
DataNode 被布置在机架中,机架中的所有节点都由一个交换机连接,因此,如果一个交换机或整个机架关闭,则可以从另一个机架访问数据。我们将在机架感知部分进一步了解。
默认复制数量是 3 , 可以根据需要通过编辑配置文件(hdfs-site.xml)将其更改为所需值。
高可用性
数据块的复制和跨集群存储在多个节点上提供了高可用性的数据,即使一个网络链路节点或某些硬件发生故障,我们也可以很容易地从不同的路径或不同的节点获取数据,因为数据至少复制在 3 个节点上,这就是 HDFS 支持高可用性功能的方式。
数据可靠性
数据在 HDFS 中留有副本,被可靠地存储。由于副本的原因,即使某些节点崩溃或某些硬件出现故障,块也高度可用。配置集群平衡策略(如果 1 个节点发生故障,存储在该节点上的块将被复制;如果突然发生故障的节点变为活动的,则消除该节点上的冗余副本。在这种情况下,我们需要配置平衡策略,以根据实际情况创建或销毁副本),只需运行很少的命令,就可以满足。这就是如何可靠地存储数据,并提供容错性和高可用性。
容错
HDFS 为 Hadoop 和生态系统中的其他组件提供了容错存储层。HDFS 与硬件一起工作,硬件随时都有很高的崩溃几率,为了使整个系统具有高度的容错性,HDFS 在不同的地方复制和存储数据。默认情况下,任何数据都存储在 3 个不同的位置。因此,即使其中一个已损坏,另一个由于任何原因在一段时间内不可用,也可以从第 3 个访问数据,极大的降低了数据丢失的可能性。这种创建副本的方式,帮助我们获得 Hadoop 的容错特性。
可扩展性
意味着可以扩展或收缩集群。在Hadoop HDF中,可扩展性有两种方式:
- 在集群的节点上添加更多的磁盘
编辑配置文件,并为新添加的磁盘创建相应的条目,但是需要进行停机维护,所以通常更喜欢使用第二种方式,即水平缩放。
- 水平缩放,在不停机的情况下,动态地向集群添加更多节点,这就是所谓的水平缩放。
我们可以在集群中实时添加任意数量的节点,而不需要停机,这是 Hadoop 提供的一个独特功能。
高吞吐量程序访问
HDFS 提供对应用程序数据的高吞吐量访问,吞吐量是在单位时间内完成的工作量。它描述了从系统访问数据的速度,通常用于测量系统的性能。当我们想执行一个任务或一个动作时,工作就会在不同的系统之间被划分和共享。因此,所有系统都将独立地、并行地执行分配给它们的任务。所以这项工作将在很短的时间内完成。通过这种方式,HDFS 提供了良好的吞吐量。通过并行读取数据,我们将大大
减少实际读取数据的时间。
HDFS IO
Read
每当客户机想要读取任何文件时,客户机都需要与 NameNode 交互,因为NameNode 是唯一存储数据节点元数据的地方,NameNode 指定存储数据的从属服务器的地址或位置,客户机将与指定的数据节点交互并从中读取数据,出于安全身份验证目的,NameNode 向客户机提供令牌,向数据节点显示令牌以读取文件。

Write
正如在读文件时看到的,客户机需要与 NameNode 节点交互。同样,对于写入文件,客户机也需要与NameNode 交互,NameNode 提供客户机的地址。一旦客户端完成第一个块的写入,第一个数据节点将把同一个块复制到其他数据节点。因此,此数据节点在接收到块后,开始将此块复制到第三个数据节点。第三个向第二个发送确认,第二个数据节点向第一个数据节点发送确认,然后第一个数据节点发送最终确认(在默认复制数量为 3 的情况下)。

每当客户端需要写入任何数据时,它都需要与 NameNode 交互。客户机与 HDFS 系统 API 交互,并向名称节点发送请求。
NameNode 共享写入数据的位置,客户机与其中写入数据的 DataNode 交互,并开始通过 FS 数据输出流写入数据,一旦数据被写入和复制,DataNode 将向客户机发送一个确认消息,通知数据被完全写入。
当数据节点复制数据块时,客户机只发送一个数据副本,而与我们的复制数量无关。因此,在Hadoop HDFS中写入文件的成本并不高,可以并行地在多个数据节点上写入多个块。
HDFS 交互
HDFS Shell
HDFS 提供了一套特有的、基于 Hadoop 抽象文件系统的 API,支持以流的形式访问文件系统中的数据。
- hadoop fs
fs 指的是文件系统,hadoop fs 命令应用最广泛,既用于普通文件系统,又用于分布式文件系统。
- hadoop dfs
dfs 指的是分布式文件系统,hadoop dfs 命令仅针对分布式文件系统,该命令已淘汰,由 hdfs dfs取代。
- hdfs dfs
用于分布式文件系统,取代 hadoop dfs。(旧用法)
下面针对 hadoop fs 命令进行详细讲解:

-help
说明:查看命令详细信息
[root@hadoop ~]# hadoop fs -help ls
-mkdir
说明:创建目录
[root@hadoop ~]# hadoop fs -mkdir /blogs
[root@hadoop ~]# hadoop fs -mkdir -p /blogs/a/b/c/
# -p 它会创建路径中的各级父目录
-ls
说明:列举目录
[root@hadoop ~]# hadoop fs -ls /cosyblogs
[root@hadoop ~]# hadoop fs -ls -R /cosyblogs
# -R 递归列举
-put
说明:从本地文件系统中上传单个或多个源路径到目标文件目录
[root@hadoop ~]# hadoop fs -put /home/a.txt /blogs
[root@hadoop ~]# hadoop fs -put /home/b.txt /home/c.txt /cosyblogs
-get
说明:下载文件到本地文件目录
[root@hadoop ~]# hadoop fs -get /blogs/a.txt /opt
[root@hadoop ~]# hadoop fs -get /blogs/a.txt /blogs/b.txt /opt
-rm
说明:删除指定的文件
[root@hadoop ~]# hadoop fs -rm /blogs/emp.sql
[root@hadoop ~]# hadoop fs -rm -r /blogs/a/b/c/
# -r 递归删除
-du
说明:显示目录中所有文件的大小,或者当只指定一个文件时,显示此文件的大小
[root@hadoop ~]# hadoop fs -du /blogs
[root@hadoop ~]# hadoop fs -du /blogs/a.txt
-cat
说明:将指定文件的内容输出到stdout
[root@hadoop ~]# hadoop fs -cat /blogs/a.txt
-tail
说明:将文件尾部 1K 字节的内容输出到stdout
[root@hadoop ~]# hadoop fs -tail /blogs/a.txt
-cp
说明:将文件从源路径复制到目标路径。这个命令允许有多个源路径,此时目标路径必须是一个目录
[root@hadoop ~]# hadoop fs -cp /blogs/a.txt /cosy/b.txt /home
-mv
说明:此命令在控制台打印输出版本信息
[root@hadoop ~]# hadoop fs -mv /cosyblogs/c.txt /blogs
[root@hadoop ~]# hadoop fs -mv /blogs/c.txt /blogs/d.txt
# 路径相同,文件名不同,则视为重命名该文件
-getmerge
说明:接受一个源目录和一个目标文件作为输入,并且将源目录中所有的文件连接成本地目标文件
[root@hadoop ~]# hadoop fs -getmerge /blogs/*.txt /home/abc.txt
-appendToFile
说明:向 hdfs 上的文件追加内容
[root@hadoop ~]# hadoop fs -appendToFile /home/*.txt