HDFS分布式读取没有Map / Reduce

时间:2011-12-10 05:00:17

标签: hadoop hdfs

是否可以在一台计算机上使用HDFS客户端从HDSF群集实现分布式读取?

我已经对由3个数据节点(DN1,DN2,DN3)组成的集群进行了实验。然后我从位于DN1的客户端程序中的10个独立文件中同时读取10个,并且它似乎只是从DN1读取数据。其他数据节点(DN2,DN3)显示零活动(从调试日志判断)。

我已检查所有文件的块是否在所有3个数据节点中复制,因此如果我关闭DN1,则会从DN2(仅限DN2)读取数据。

增加读取的数据量没有帮助(尝试从2GB到30GB)。

由于我需要读取多个大文件并从中提取少量数据(少量Kb),我想避免使用map / reduce,因为它需要设置更多服务并且还需要编写输出每个拆分任务返回HDFS。相反,将结果直接从数据节点流回我的客户端程序会很好。

我正在使用SequenceFile以这种方式读取/写入数据(jdk7):

//Run in thread pool on multiple files simultaneously

List<String> result = new ArrayList<>();
LongWritable key = new LongWritable();
Text value = new Text();
try(SequenceFile.Reader reader = new SequenceFile.Reader(conf,
                                     SequenceFile.Reader.file(filePath)){
  reader.next(key);
  if(key.get() == ID_I_AM_LOOKING_FOR){
    reader.getCurrentValue(value);
    result.add(value.toString());
  }
}

return result; //results from multiple workers are merged later

任何帮助表示赞赏。谢谢!

3 个答案:

答案 0 :(得分:7)

我担心你看到的行为是按设计的。来自Hadoop document

  
    

副本选择

         

为了最大限度地减少全局带宽消耗和读取延迟,HDFS会尝试     满足来自最接近的副本的读取请求     读者。如果在与读取器节点相同的机架上存在副本,     然后该副本首选满足读取请求。如果angg /     HDFS群集跨越多个数据中心,然后是一个副本     驻留在本地数据中心优先于任何远程数据中心     复制品。

  

可以通过相应的Hadoop source code进一步确认:

  LocatedBlocks getBlockLocations(...) {
    LocatedBlocks blocks = getBlockLocations(src, offset, length, true, true);
    if (blocks != null) {
      //sort the blocks
      DatanodeDescriptor client = host2DataNodeMap.getDatanodeByHost(
          clientMachine);
      for (LocatedBlock b : blocks.getLocatedBlocks()) {
        clusterMap.pseudoSortByDistance(client, b.getLocations());

        // Move decommissioned datanodes to the bottom
        Arrays.sort(b.getLocations(), DFSUtil.DECOM_COMPARATOR);
      }
    }
    return blocks;
  }

即,所有可用的副本都是一个接一个地尝试,如果前者失败了,但最近的副本总是第一个。

另一方面,如果您通过HDFS Proxy访问HDFS文件,它会选择数据节点randomly。但我不认为这就是你想要的。

答案 1 :(得分:3)

除了Edwardw所说的,你当前的群集非常小(只有3个节点),在这种情况下你会看到所有节点上的文件。这是因为Hadoop的默认复制因子也是3.在较大的群集中,您的文件在每个节点上都不可用,因此访问多个文件可能会转到不同的节点并分散负载。

如果您使用较小的数据集,您可能需要查看HBase,它允许您使用较小的块并在节点之间分配负载(通过拆分区域)

答案 2 :(得分:0)

我会告诉你,你的情况对MR来说听起来不错。如果我们抛开特定的MR计算范例,我们就可以知道hadoop是为了将代码带入数据而不是相反的。将代码移动到数据对于获得可扩展的数据处理至关重要。
另一方面 - 设置MapReduce比HDFS更容易 - 因为它在作业之间不存储任何状态 同时 - MR框架会关心你的并行处理 - 这需要时间才能正常完成 另一点 - 如果数据处理结果如此之小 - 如果将它们组合在减速器中,则不会对性能产生重大影响。
换句话说 - 我建议重新考虑使用MapReduce。