【问题标题】:Hadoop - appropriate block size for unsplittable files of varying sizes (200-500mb)Hadoop - 不同大小的不可分割文件的适当块大小(200-500mb)
【发布时间】:2013-06-21 11:13:39
【问题描述】:

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

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

我的理解是:

  1. 几乎没有块大小的上限,因为对于我的集群大小而言,适当数量的映射器有“大量文件”。
  2. 为确保数据本地化,我希望每个 gzip 文件位于 1 个块中。

但是,gzip 压缩文件的大小不同。如果我选择 ~500mb 的块大小(例如我所有输入文件的最大文件大小),如何存储数据?选择一个“非常大”的块大小会更好吗,比如 2GB?在这两种情况下是否过度浪费了 HDD 容量?

我想我真的在问文件实际上是如何存储和跨 hdfs 块拆分的 - 以及试图了解不可拆分文件的最佳实践。

更新:一个具体的例子

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

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

鉴于有大量空闲块,HDFS 是按照案例 A 还是案例 B 存储文件?

【问题讨论】:

    标签: hadoop hdfs


    【解决方案1】:

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

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

    至于块大小的上限,我知道对于某些旧版本的 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 物理存储在每个数据节点副本上

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

    唯一可能的缺点是复制较小块和较大块所需的时间,但另一方面,如果数据节点从集群中丢失,则任务复制 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,不是 200 MB 的文件,299 MB 的零填充(我认为这是混乱的来源)。

    现在,块大小确实影响效率的地方在于名称节点。对于上面两个例子,name node 需要维护一个文件名的映射,到块名和数据节点位置(以及总文件大小和块大小):

    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 次。

    【讨论】:

    • 如果我将 3 200 MB 文件存储在 300 MB 块中会怎样?每隔一个文件会被分成两个块,还是我在每个块中留下 100 MB 未使用的空间?将块大小设置为 max(filesize)max(filesize)*20 可能会对性能(当文件不可拆分时)或存储“浪费”产生巨大影响,具体取决于文件在块之间的实际分布方式。
    • 如果存储 200 MB 的文件,块大小为 300 MB 块大小,则不会浪费。它不像传统文件系统上的块大小,未使用的 100 MB 不会被浪费。 HDFS 中唯一的低效率是如果您存储的大文件的块大小太小,在这种情况下,主要是 Name Node 的内存需求来跟踪文件的每个块
    • 好吧,假设整个设置已调整为仅处理这 200 MB 文件。如果我理解正确,每个 200 MB 文件将存储在单独的 300 MB 块中。当然,每个块中仍有 100 MB 可用于其他文件,但如果我存储 200 MB 文件,我实际上会在每个块中留下 100 MB 未使用的空间,不是吗?
    • 好的,我再试一次 - 如果文件小于块大小,那么它们将存储在与文件本身大小相同的文件中的数据节点上。如果文件大于数据块,例如 1100MB,那么您将在数据服务器上存储多个 300 MB 块(3 x 300 MB),剩余的 200 MB 将存储在某个数据节点上作为200 MB 文件。
    • 这是有道理的,感谢您的精彩更新!但是(我很抱歉没有正确解释我的问题),我已经为我的问题添加了更新,因为我不完全确定 HDFS 文件放置策略的一部分。我可以说服你看一下吗?
    【解决方案2】:

    我将尝试通过示例来强调块拆分与文件大小相关的差异。在 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.
    

    最好主动避免这种情况,因为这意味着 tasktracker 将必须获取 16 个数据块,其中大部分不是 tasktracker 本地的。

    最后,block、split和file的关系可以总结如下:

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

    分割可以扩展到块之外,因为分割取决于如何分割文件的 InputFormat 类定义,这可能与块大小不一致,因此分割扩展到包括查找点在源中。

    【讨论】:

    • 这很有帮助,谢谢。我能问你和我问克里斯怀特一样的问题吗?如果我将 3 200 MB 文件存储在 300 MB 块中会怎样?每隔一个文件会被分成两个块,还是每个块中都有 100 MB 未使用?
    • 看起来 Chris 很好地解决了你在评论中问我的问题,但是这里的重点是,与传统文件系统不同,HDFS 有效地使用它的空间,因此块遵循文件大小的逻辑边界不浪费空间。
    猜你喜欢
    • 1970-01-01
    • 2016-11-01
    • 2012-06-16
    • 2015-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多