Hadoop 中的拆分大小与块大小

Split size vs Block size in Hadoop

Hadoop 中分割大小和块大小之间的关系是什么?正如我在 this 中所读到的,分割大小必须是块大小的 n 倍(n 是一个整数且 n > 0),这是正确的吗? split size和block size有什么必然关系吗?

HDFS架构中有块的概念。 HDFS 使用的典型块大小为 64 MB。当我们将一个大文件放入 HDFS 时,它被分成 64 MB 的块(基于块的默认配置),假设你有一个 1GB 的文件并且你想将该文件放入 HDFS,那么将有 1GB / 64MB = 16 split/blocks 这些块将分布在 DataNode 中。根据您的集群配置,这些 blocks/chunk 将驻留在不同的 DataNode 上。

数据拆分基于文件偏移量。拆分文件并将其存储到不同的块中的目的是并行处理和数据故障转移。

块大小和拆分大小之间的差异。

Split 是数据的逻辑拆分,主要用于在 Hadoop 生态系统上使用 Map/Reduce 程序或其他数据处理技术进行数据处理。拆分大小是用户定义的值,您可以根据您的数据量(您正在处理的数据量)选择自己的拆分大小。

Split在Map/Reduce程序中主要用来控制Mapper的个数。如果您没有在 Map/Reduce 程序中定义任何输入拆分大小,则默认 HDFS 块拆分将被视为输入拆分。

示例:

假设你有一个100MB的文件,HDFS默认的block配置是64MB,那么它会被分成2个split,占用2个blocks。现在您有一个 Map/Reduce 程序来处理此数据,但您没有指定任何输入拆分,然后根据块数(2 个块)输入拆分将被考虑用于 Map/Reduce 处理和 2 个映射器将被分配到这份工作。

但是假设,您在 Map/Reduce 程序中指定了拆分大小(例如 100MB),那么两个块(2 个块)将被视为 Map/Reduce 处理的单个拆分,并且 1将为这项工作分配映射器。

假设,您在 Map/Reduce 程序中指定了拆分大小(例如 25MB),那么 Map/Reduce 程序将有 4 个输入拆分,并且将为该作业分配 4 个映射器。

结论:

  1. 拆分是输入数据的逻辑划分,而块是数据的物理划分。
  2. 如果未指定输入拆分,HDFS 默认块大小为默认拆分大小。
  3. 拆分是用户定义的,用户可以在他的 Map/Reduce 程序中控制拆分大小。
  4. 一次拆分可以映射到多个块,一个块可以有多个拆分。
  5. map任务(Mapper)的个数等于split的个数
  • 假设我们有一个 400MB 的文件,其中包含 4 条记录(e.g : 400MB 的 csv 文件,它有 4 行,每行 100MB)

  • 如果HDFS Block Size配置为128MB,那么4条记录将不会均匀分布在blocks中。它看起来像这样。

  • 块 1 包含整个第一条记录和第二条记录的 28MB 块。
  • 如果映射器要在 块 1 上 运行,则映射器无法处理,因为它没有完整的第二条记录。

  • 这正是 输入拆分 解决的问题。 输入拆分 遵守逻辑记录边界。

  • 假设输入拆分大小为200MB

  • 因此 输入拆分 1 应该同时包含记录 1 和记录 2。并且输入拆分 2 不会从记录 2 开始,因为记录 2 有已分配给输入拆分 1。输入拆分 2 将从记录 3 开始。

  • 这就是为什么输入拆分只是数据的逻辑块。它指向以块为单位的开始和结束位置。

  • 如果输入拆分大小是块大小的 n 倍,则输入拆分可以容纳多个块,因此整个作业所需的 Mappers 数量较少因此并行度较低。 (映射器的数量是输入拆分的数量)

  • 输入拆分大小=块大小是理想的配置。

希望对您有所帮助。

Split 的创建取决于所使用的 InputFormat。下图解释了 FileInputFormat 的 getSplits() 方法如何决定两个不同文件的拆分。
请注意 Split Slope (1.1) 所扮演的角色。

对应的Java进行拆分的来源是:


上面的 computeSplitSize() 方法扩展为 Max(minSize, min(maxSize, blockSize)),其中 min/max大小可以通过设置mapreduce.input.fileinputformat.split.minsize/maxsize

来配置