我正在尝试分析哪些函数在 TeraSort Hadoop 作业中消耗的时间最多。对于我的测试系统,我使用的是基本的 1 节点伪分布式设置。这意味着 NameNode、DataNode、Tasktracker 和 Jobtracker JVM 都在同一台机器上运行。
我首先使用 TeraGen 生成约 9GB 的数据,然后在其上运行 TeraSort。在 JVM 执行时,我使用 VisualVM 对其执行进行采样。我知道这不是最准确的分析器,但它是免费且易于使用的!我使用最新版本的 Apache hadoop 发行版,我的实验在基于 Intel Atom 的系统上运行。
当我查看 VisualVM 中 Hot Spots-Methods 的 Self time (CPU) 时,我发现 java.util.zip.CRC32.update() 函数占用了将近 40% 的总时间。当我在调用树中查看这个函数时,它是由映射器的 main() 函数调用的,特别是当 IdentityMapper.map() 从 HDFS 读取输入文件时。实际调用 CRC32.update() 函数的函数是 org.apache.hadoop.fs.FSInputChecker.readChecksumChunk()
我对此有三个问题:
为什么要为从 HDFS 读取的块更新 CRC32 校验和?如果我理解正确,一旦读取一个块,从磁盘读取的数据与块的 CRC 的简单比较应该是唯一的操作,而不是生成和更新块的 CRC 值。
我查找了更新函数的源代码,它是由 java.util.zip.CRC32.java 文件实现的。调用的特定函数是具有三个参数的重载 update() 方法。既然这个功能是用Java实现的,有没有可能多层抽象(Hadoop、JVM、CPU指令)降低了CRC计算的原生效率?
最后,我的 VisualVM 检测方法或对采样结果的解释是否存在严重问题?
谢谢,