我正在寻找一个磁盘密集型的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);
}
2条答案
按热度按时间zaqlnxep1#
好 啊。我以前没检查过,一定是太蠢了。实际问题是,我的所有数据节点都没有真正运行。我重新格式化了namenode,所有的东西都恢复到原来的位置,我得到了15-20%的利用率,这对wc来说还不错。我将为testdfsio运行它,看看是否可以进一步利用磁盘。
0pizxfdo2#
我认为,任何在每一行的每个单元格中创建java对象,并在将其保存到磁盘之前运行java对象的任何序列化的机制都几乎没有机会利用io。
根据我的经验,序列化的速度是每秒几mb或更高一点,但不是每秒100 mb。
因此,您在输出路径上避免使用hadoop层的做法是非常正确的。现在让我们考虑如何写hdfs。数据通过本地datanode写入本地磁盘,然后同步写入网络中的其他节点,具体取决于您的复制因素。在这种情况下,您不能将更多的数据写入hdfs,而不是您的网络带宽。如果你的集群相对较小,那么事情就变得有价值了。对于3节点群集和三重复制,您将把所有数据路由到所有节点,这样整个群集hdfs写入带宽将大约为1 gbit—如果您有这样的网络的话。
因此,我建议:
a) 将复制因子减少到1,从而停止被网络绑定。
b) 在对mapper的一次调用中编写更大的数据块