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

jkg*_*yti 10 hadoop hdfs

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

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

我的理解是:

  1. 块大小几乎没有上限,因为对于我的簇的大小,适当数量的映射器有"大量文件".
  2. 为了确保数据的位置,我希望每个gzip文件都在1个块中.

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

我想我真的在询问文件是如何实际存储的,并且跨越hdfs块进行分割 - 以及尝试了解不可拆分文件的最佳实践.

更新:一个具体的例子

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

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

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

HDFS策略

Chr*_*ite 4

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

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

至于块大小的上限,我知道对于某些旧版本的 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 块慢。

更新 - 一个有效的例子

鉴于这引起了一些混乱,这里有一些有效的例子:

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

如果要存储 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
Run Code Online (Sandbox Code Playgroud)

请注意,该文件不能完全被 300 MB 整除,因此文件的最终块的大小为文件除以块大小的模。

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

/local/path/to/datanode/storage/0/blk_000000000000005  1 MB
Run Code Online (Sandbox Code Playgroud)

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

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

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
Run Code Online (Sandbox Code Playgroud)

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