Hadoop数据节点:为什么数据块的阈值有一个神奇的"数字"?



专家,

我们可能会看到我们的 hadoop 集群中的区块数量增长。"太多"块会产生诸如数据节点的堆需求增加、执行速度下降、GC 增加等后果。当区块数量超过某个"阈值"时,我们应该注意。

  1. 我见过不同的阈值静态数字,例如 200,000 或 500,000 - "魔术"数字。它不应该是节点内存的函数(DataNode 的 Java 堆大小,以字节为单位)?

其他有趣的相关问题:

  1. 高块数表示什么? A. 小文件太多? B. 产能不足? 是(a)还是(b)?如何区分两者?

  2. 什么是小文件?文件大小小于块大小 (dfs.blocksize) 的文件?

  3. 每个文件是否在磁盘上占用一个新的数据块?还是与新文件关联的元数据是问题所在?

  4. 效果是更多的GC,降低执行速度等。如何"量化"高区块数的影响?

提前致谢

感谢大家的投入。我对这个话题做了一些研究,并分享了我的发现。

  1. 任何静态数字都是幻数。我建议块阈值的数量为:堆内存(以 GB 为单位)x 100 万 * comfort_%age(例如 50%)

为什么? 经验法则:1M 块为 1GB,Cloudera [1]

事实证明,namenode 所需的实际堆内存量要低得多。 所需的堆 =(块数 + 索引节点(文件 + 文件夹))x 对象大小(150-300 字节 [1])

对于 100 万个文件:所需堆 = (1M + 1M) x 300b = 572mb <== 远小于经验法则。

  1. 高块计数可能表示两者兼而有之。 名称节点 UI 声明使用的堆容量。

例如 http://namenode:50070/dfshealth.html#tab-overview 9,847,555 个文件和目录,6,827,152 个块 = 16,674,707 个文件系统对象总数。 堆内存使用了 5.82 GB 的 15.85 GB 堆内存。最大堆内存为 15.85 GB。

** 请注意,使用的堆内存仍高于 16,674,707 个对象 x 300 字节 = 4.65gb

要找出小文件,请执行 HDFS FSCK -blocks | grep "总块数(已验证):" 它将返回如下内容: 总块数(已验证):2402(平均块大小 325594 B) <== 小于 1mb

  1. 是的。 如果文件的大小<dfs.blocksize,则文件很小。>
    • 每个文件在磁盘上都有一个新的数据块,尽管块大小接近文件大小。 这么小的块。
    • 对于每个新文件,都会创建索引节点类型对象(150B),因此对名称节点的堆内存施加压力

对名称和数据节点的影响:小文件会给名称节点和数据节点带来问题: 命名节点: - 降低文件数量的上限,因为它需要将每个文件的元数据保留在内存中 - 重新启动时间长,因为它必须从本地磁盘上的缓存中读取每个文件的元数据

数据节点: - 大量的小文件意味着大量的随机磁盘IO。HDFS专为大文件而设计,并受益于顺序读取。

[1] https://www.cloudera.com/documentation/enterprise/5-8-x/topics/admin_nn_memory_config.html

您的第一个假设是错误的,因为 Data 节点不维护内存中的数据文件结构,因此 Name 节点的工作是跟踪内存中的文件系统(重复出现于 INodes)。因此,小文件实际上会导致您的 Name 节点更快地耗尽内存(因为需要更多的元数据来表示相同数量的数据),并且执行速度将受到影响,因为映射器是按块创建的。

  1. 要回答您的第一个问题,请检查:名称节点文件数量限制
  2. 执行以下命令:hadoop fs -du -s -h。如果您看到第一个值(表示所有文件的平均文件大小)远小于配置的块大小,那么您就面临着小文件的问题。要检查空间是否不足:hadoop fs -df -h
  3. 是的,可以小得多。有时,如果文件太大,则需要额外的块。一旦块被保留给某个文件,它就不能被另一个文件使用。
  4. 该块不会在磁盘上保留超出实际存储数据所需的空间,它是名称节点上的元数据施加限制。
  5. 正如我之前所说,需要为相同数量的数据执行更多的映射器任务。由于映射器是在新的JVM上运行的,因此GC不是问题,但是启动它以处理少量数据的开销是问题所在。

最新更新