我一直在寻找一个磁盘密集型Hadoop应用程序来测试Hadoop中的I/O事件,但是找不到任何使磁盘利用率保持在50%以上的应用程序,或者某个实际上使磁盘繁忙的应用程序。我尝试过randomwriter,但是令人惊讶的是,它不是磁盘I/O密集型的。

因此,我写了一个小程序在Mapper中创建一个文件,并向其中写入一些文本。该应用程序运行良好,但利用率仅在主节点(即名称节点,作业跟踪器和从节点之一)中较高。磁盘利用率为NIL或在其他任务跟踪器中可以忽略不计。我无法理解为什么任务跟踪器中的磁盘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对象保存到磁盘之前对其进行序列化的任何机制都很少有机会利用IO。
以我的经验,序列化的速度为每秒几MB或更高,但不是每秒100 MB。
因此,避免输出路径上的hadoop层的做法是正确的。
现在让我们考虑写入HDFS的工作方式。数据通过本地datanode写入本地磁盘,然后同步到网络中的其他节点,具体取决于您的复制因素。在这种情况下,您将无法向HDFS中写入比您的网络带宽更多的数据。如果您的集群相对较小,那么物有所值。对于3节点群集和三重复制,您会将所有数据路径传递到所有节点,因此整个群集HDFS的写入带宽将约为1 GBit-如果您有这样的网络。
因此,我建议:
a)将复制因子减小为1,从而不再受网络的束缚。
b)在一次对映射器的调用中写入更大的数据块

关于hadoop - 在Hadoop的HDFS中写入文件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13457934/

10-16 01:31