是否可以在一台计算机上使用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
任何帮助表示赞赏。谢谢!
答案 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。