4

我了解 HDFS 中的块系统是底层文件系统之上的逻辑分区。但是当我发出cat命令时如何检索文件。

假设我有一个 1 GB 的文件。我的默认HDFS块大小是 64 MB。

我发出以下命令:

hadoop -fs copyFromLocal my1GBfile.db input/data/

上面的命令将文件my1GBfile.db从我的本地机器复制到输入/数据目录HDFS:

我有 16 个要复制和复制的块( 1 GB / 64 MB ~ 16 )。

如果我有 8 datanodes,则单个数据节点可能没有所有块来重新构建文件。

当我发出以下命令时

hadoop -fs cat input/data/my1GBfile.db | head 

现在会发生什么?

文件是如何重组的?虽然块只是逻辑分区,但 1 GB 的文件是如何物理存储的。它存储在 HDFS 上。每个数据节点是否获取文件的某些物理部分。因此,通过将输入的 1GB 文件分成 64 MB 的块,我们可能会在记录级别(比如在行之间)打破一些东西。这是如何处理的?

我签入了我的数据节点,我确实看到了一个blk_1073741825,当在编辑器中打开它时,它实际上显示了文件的内容。

那么,生成的文件块是否不合逻辑但真实partition的数据发生了?

请帮助澄清这一点

4

4 回答 4

7

到目前为止,我从您的问题中了解到,根据我的理解,我的回答是这样的...

首先,您需要了解黑白 HDFS 块大小和 inputSplit 大小的区别。

块大小 - HDFS 的块大小 (64/128/256 MB) 实际上包含原始 (1 GB) 文件的数据。并且在内部/最终,这些数据存储在文件系统(ext 等)上的块(4/8 KB)中。因此,HDFS 的块大小是原始文件的物理分区。

InputSplit - 将文件分解为输入拆分,输入拆分是文件的逻辑分区。逻辑分区意味着——它只会有块地址/位置的信息。Hadoop 使用存储在文件块中的数据(输入拆分)的这种逻辑表示。当 MapReduce 作业客户端计算输入拆分时,它会计算出块中第一条完整记录的开始位置以及块中最后一条记录的结束位置。

如果块中的最后一条记录不完整,则输入拆分包括下一个块的位置信息和完成记录所需的数据的字节偏移量。

希望,上面阐明了黑白块大小和输入拆分大小的差异。

现在来回答你关于'hadoop fs -cat /'工作的问题----->

所有关于块位置的信息都作为元数据存储在 NameNode 中。如果一个节点在记录级别被拆分,则 DataNode 将块的地址/位置信息发送到 NameNode。

因此,当客户端向 Hadoop 发出“cat”命令时,基本上客户端会向 NameNode 发送一个请求,即“我想读取 fileA.txt,请提供该文件中存储在各个位置的所有块的位置”。NameNode 的职责是提供存储在各种 DataNode 上的块的位置。

基于这些位置,客户端直接与 DataNodes 联系以获取这些块。最后,客户端以相同的顺序/方式读取所有这些块,这些块存储在 HDFS 中(这里 NameNode 将文件的所有块的地址返回给客户端) - 从而将完整的文件发送给客户端。

希望,我可以澄清你的疑问。

于 2015-01-03T12:02:27.427 回答
4

块实际上只是数据节点上的文件。当您cat在 HDFS 中创建文件时,您的机器直接从它们各自的数据节点流式传输这些块并在本地重建整个文件。

于 2014-07-23T22:34:32.200 回答
1

当您将文件保存到 HDFS 时,文件被分割成称为块的 (每个块的大小默认为 128MB,但可以配置此值)。块被复制(默认为 3 次),每个副本都保存在 Hadoop 集群中的不同(尽可能)节点上。这就是为什么建议在具有复制 3 的集群中至少有三个数据节点的原因。

这里解释了块的物理放置位置:

对于常见的情况,当复制因子为 3 时,HDFS 的放置策略是,如果 writer 在 datanode 上,则将一个副本放在本地机器上,否则在与 writer 相同机架的随机 datanode 上,另一个副本在不同(远程)机架中的节点,最后一个节点位于同一远程机架中的不同节点上。

要检查文件 $FILENAME 中块的位置,请使用:

hdfs fsck $FILENAME -files -blocks -locations

这将向您显示块的数量、它们的状态以及保存块及其副本的所有节点的 IP 地址。

现在处理文件时会发生什么?(*) Hadoop 将寻找最接近发出读取命令的机器的块,以最大限度地减少延迟。从文档中引用:

为了最小化全局带宽消耗和读取延迟,HDFS 尝试满足来自离读取器最近的副本的读取请求。如果与读取器节点在同一机架上存在副本,则首选该副本来满足读取请求。如果 HDFS 集群跨越多个数据中心,则驻留在本地数据中心的副本优先于任何远程副本。

分区

关于分区,这些在 MapReduce 和 Spark 的上下文中发挥作用,它们是构成并行基础的数据的逻辑划分。转换在数据分区上并行执行。

请注意,由于“数据”可能包含一个或多个文件,因此分区可以包含来自不同文件的块。

(*)您写道:“在编辑器中打开时实际上显示文件的内容”......作为旁注:通常打开大文件进行编辑不是一个好主意!在这种情况下,可以只打开一个块。

于 2022-01-03T12:27:22.770 回答
0

除了先前的答案,您还可以获得有关使用 Java API 的块的信息。例如,您可以在此类中使用FilterFileSystem类和FilterFileSystem方法。因此,您可以看到如何将文件拆分为块并存储在集群中。链接到 JavaAPI:http ://hadoop.apache.org/docs/current/api/org/apache/hadoop/fs/FilterFileSystem.html

于 2014-07-28T09:01:33.587 回答