我一直在寻找一个磁盘密集型 Hadoop 应用程序来测试 Hadoop 中的 I/O 活动,但我找不到任何此类应用程序可以使磁盘利用率保持在上述水平(例如 50%),或者某些此类应用程序实际上使磁盘保持繁忙。我尝试了 randomwriter,但令人惊讶的是这并不是磁盘 I/O 密集型。
因此,我编写了一个小程序来在 Mapper 中创建一个文件并向其中写入一些文本。该应用程序运行良好,但仅在主节点(同时也是名称节点、作业跟踪器和从节点之一)中利用率较高。在其他任务跟踪器中,磁盘利用率为零或可以忽略不计。我无法理解为什么任务跟踪器中的磁盘 I/O 如此之低。如果我做错了什么,有人可以将我推向正确的方向吗?提前致谢。
这是我在 WordCount.java 文件中编写的示例代码段,用于创建 UTF 字符串并将其写入文件 -
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);
Path outFile;
while (itr.hasMoreTokens()) {
word.set(itr.nextToken());
context.write(word, one);
outFile = new Path("./dummy"+ context.getTaskAttemptID());
FSDataOutputStream out = fs.create(outFile);
out.writeUTF("helloworld");
out.close();
fs.delete(outFile);
}
我认为任何为每行中的每个单元创建 java 对象并在将 java 对象保存到磁盘之前运行任何 java 对象序列化的机制都几乎没有机会利用 IO。
根据我的经验,序列化的工作速度为每秒几 MB 或更高,但不是每秒 100 MB。
因此,您所做的避免输出路径上的 hadoop 层的做法是非常正确的。
现在让我们考虑写入 HDFS 的工作原理。数据通过本地datanode写入本地磁盘,然后同步到网络中的其他节点,具体取决于你的复制因子。在这种情况下,您无法将比您的网络带宽更多的数据写入 HDFS。如果您的集群相对较小,那么事情就值得了。对于 3 节点集群和三重复制,您将把所有数据传输到所有节点,因此整个集群 HDFS 写入带宽将约为 1 GBit - 如果您有这样的网络。
所以,我建议:
a) 将复制因子降低到1,从而不再受网络束缚。
b) 在一次调用映射器中写入更大的数据块
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)