Hadoop - 适用于不同大小(200-500mb)的不可分割文件的块大小

时间:2013-06-21 11:13:39

标签: hadoop hdfs

如果我需要对(不可拆分的)数千个大小在200到500mb之间的gzip文件进行顺序扫描,那么这些文件的块大小是多少?

为了这个问题,让我们说完成的处理速度非常快,因此重新启动映射器并不昂贵,即使对于大块大小也是如此。

我的理解是:

  1. 块大小几乎没有上限,因为对于我的群集大小,适当数量的映射器有“大量文件”。
  2. 为确保数据位置,我希望每个gzip文件都在1个块中。
  3. 但是,gzip压缩文件的大小各不相同。如果我选择~500mb的块大小(例如我所有输入文件的最大文件大小),如何存储数据?选择“非常大”的块大小(如2GB)会更好吗?在这两种情况下,HDD容量都被过度浪费了吗?

    我想我真的在问这些文件是如何实际存储的,并且是在hdfs块之间拆分的 - 以及试图了解不可拆分文件的最佳实践。

    更新:具体示例

    假设我在三个200 MB文件上运行MR作业,存储如下图所示。

    如果HDFS按照案例A存储文件,则可以保证3个映射器能够处理每个“本地”文件。但是,如果文件存储在案例B中,则一个映射器需要从另一个数据节点获取文件2的一部分。

    鉴于有足够的空闲块,HDFS是否存储文件,如案例A或案例B所示?

    HDFS strategies

2 个答案:

答案 0 :(得分:3)

如果您有不可拆分的文件,那么最好使用较大的块大小 - 与文件本身一样大(或者更大,没有区别)。

如果块大小小于整个文件大小,那么您可能会遇到所有块都不在同一数据节点上并且您丢失数据局部性的可能性。这对于可拆分文件来说不是问题,因为将为每个块创建一个地图任务。

至于块大小的上限,我知道对于某些旧版本的Hadoop,限制为2GB(超过该块的内容无法获得) - 请参阅https://issues.apache.org/jira/browse/HDFS-96

存储具有较大块大小的较小文件没有任何缺点 - 要强调这一点,请考虑1MB和2 GB文件,每个文件的块大小为2 GB:

  • 1 MB - 1个块,名称节点中的单个条目,每个数据节点副本上物理存储1 MB
  • 2 GB - 1个块,名称节点中的单个条目,每个数据节点副本上物理存储2 GB

除了所需的物理存储之外,Name节点块表没有任何缺点(两个文件在块表中都有一个条目)。

唯一可能的缺点是复制较小块与较大块所需的时间,但另一方面,如果数据节点从群集中丢失,则执行2000 x 1 MB块复制比单个块慢2 GB块。

更新 - 一个有效的例子

看到这引起了一些混乱,继承了一些有用的例子:

假设我们的系统具有300 MB的HDFS块大小,为了简单起见,我们有一个只有一个数据节点的伪集群。

如果要存储1100 MB文件,则HDFS会将该文件拆分为最多 300 MB块,并将其存储在特殊块索引文件中的数据节点上。如果您要转到数据节点并查看它将索引块文件存储在物理磁盘上的位置,您可能会看到如下内容:

/local/path/to/datanode/storage/0/blk_000000000000001  300 MB
/local/path/to/datanode/storage/0/blk_000000000000002  300 MB
/local/path/to/datanode/storage/0/blk_000000000000003  300 MB
/local/path/to/datanode/storage/0/blk_000000000000004  200 MB

请注意,该文件不能完全被300 MB整除,因此文件的最后一个块的大小按块大小调整为文件的模数。

现在,如果我们使用小于块大小的文件(例如1 MB)重复相同的练习,并查看它将如何存储在数据节点上:

/local/path/to/datanode/storage/0/blk_000000000000005  1 MB

再次注意,存储在数据节点上的实际文件是1 MB, NOT 一个200 MB文件,带有299 MB零填充(我认为这是混乱的来源)。 / p>

现在,块大小确实起到效率的作用,在名称节点中。对于上面两个示例,名称节点需要维护文件名的映射,块名称和数据节点位置(以及总文件大小和块大小):

filename     index     datanode
-------------------------------------------
fileA.txt    blk_01    datanode1
fileA.txt    blk_02    datanode1
fileA.txt    blk_03    datanode1
fileA.txt    blk_04    datanode1
-------------------------------------------
fileB.txt    blk_05    datanode1

您可以看到,如果您对fileA.txt使用1 MB的块大小,则上面的映射中需要1100个条目而不是4个(这将需要名称节点中的更多内存)。同时撤回所有块将会更加昂贵,因为你要对datanode1进行1100次RPC调用,而不是4次。

答案 1 :(得分:1)

我将尝试通过示例突出显示块分割参考文件大小的差异。在HDFS中你有:

Splittable FileA size 1GB
dfs.block.size=67108864(~64MB)

针对此文件的MapRed作业:

16 splits and in turn 16 mappers.

让我们用压缩(不可拆分)文件来看看这个场景:

Non-Splittable FileA.gzip size 1GB
dfs.block.size=67108864(~64MB)

针对此文件的MapRed作业:

16 Blocks will converge on 1 mapper.

最好主动避免这种情况,因为这意味着任务跟踪器必须获取16个数据块,其中大多数数据块不是任务跟踪器的本地数据。

最后,块,拆分和文件的关系可以总结如下:

                                                             block boundary
|BLOCK           |    BLOCK       |   BLOCK        |   BLOCK ||||||||
|FILE------------|----------------|----------------|---------|
|SPLIT            |                |                |        |

拆分可以扩展到块之外,因为拆分取决于InputFormat类定义如何拆分文件,这可能与块大小不一致,因此拆分超出了包括搜索点来源。