1

以下用例:

我对 .gz 压缩中大小约为 500GB 的数据运行配置单元查询:

select count(distinct c1), c2 from t1 group by c2;

此查询产生约 2800 个 map 作业和约 400 个 reduce 作业。

当设置一个 Hadoop 集群时,每个 160GB 实例存储有 20 个实例,作业将停止在 97% map 和 21% reduce 进度,然后回落到 94% map 和 19% reduce 进度,然后根本没有进度。我认为这是因为 HDFS 的磁盘空间已达到使用限制。也许我可以在当天晚些时候提供一条异常消息。

但是:有没有办法根据正在处理的数据的输入大小粗略地预先计算所需的 HDFS 磁盘空间?请记住,输入数据以 .gz 格式存储。

更新

有谁知道,为什么我的 MapReduce 作业只使用节点的本地存储,而不是 DFS?

DFS 使用概述 http://img27.imageshack.us/img27/5805/dfsusageoverview.png

DFS 使用详情 http://img542.imageshack.us/img542/5026/dfsusagedetail.png

来自映射器之一的例外:

at org.apache.hadoop.hive.ql.exec.MapOperator.process(MapOperator.java:550)
        at org.apache.hadoop.hive.ql.exec.ExecMapper.map(ExecMapper.java:143)
        ... 8 more
Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: java.io.IOException: Spill failed
        at org.apache.hadoop.hive.ql.exec.ReduceSinkOperator.processOp(ReduceSinkOperator.java:304)
        at org.apache.hadoop.hive.ql.exec.Operator.process(Operator.java:471)
        at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:762)
        at org.apache.hadoop.hive.ql.exec.GroupByOperator.forward(GroupByOperator.java:959)
        at org.apache.hadoop.hive.ql.exec.GroupByOperator.flush(GroupByOperator.java:926)
        at org.apache.hadoop.hive.ql.exec.GroupByOperator.processHashAggr(GroupByOperator.java:779)
        at org.apache.hadoop.hive.ql.exec.GroupByOperator.processOp(GroupByOperator.java:722)
        at org.apache.hadoop.hive.ql.exec.Operator.process(Operator.java:471)
        at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:762)
        at org.apache.hadoop.hive.ql.exec.SelectOperator.processOp(SelectOperator.java:84)
        at org.apache.hadoop.hive.ql.exec.Operator.process(Operator.java:471)
        at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:762)
        at org.apache.hadoop.hive.ql.exec.TableScanOperator.processOp(TableScanOperator.java:83)
        at org.apache.hadoop.hive.ql.exec.Operator.process(Operator.java:471)
        at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:762)
        at org.apache.hadoop.hive.ql.exec.MapOperator.process(MapOperator.java:533)
        ... 9 more
Caused by: java.io.IOException: Spill failed
        at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.collect(MapTask.java:1045)
        at org.apache.hadoop.mapred.MapTask$OldOutputCollector.collect(MapTask.java:599)
        at org.apache.hadoop.hive.ql.exec.ReduceSinkOperator.processOp(ReduceSinkOperator.java:289)
        ... 24 more

Caused by: org.apache.hadoop.util.DiskChecker$DiskErrorException: Could not find any valid local directory for output/s
pill15.out
        at org.apache.hadoop.fs.LocalDirAllocator$AllocatorPerContext.getLocalPathForWrite(LocalDirAllocator.java:381)
        at org.apache.hadoop.fs.LocalDirAllocator.getLocalPathForWrite(LocalDirAllocator.java:146)
        at org.apache.hadoop.fs.LocalDirAllocator.getLocalPathForWrite(LocalDirAllocator.java:127)
        at org.apache.hadoop.mapred.MapOutputFile.getSpillFileForWrite(MapOutputFile.java:121)
        at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.sortAndSpill(MapTask.java:1408)
        at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.access$1800(MapTask.java:869)
        at org.apache.hadoop.mapred.MapTask$MapOutputBuffer$SpillThread.run(MapTask.java:1360)
4

1 回答 1

3

以下是来自Cloudera 博客的一些注释:

每个文件的默认复制因子为 3,您需要为中间 shuffle 文件留出大约 25% 的磁盘空间。因此,您需要存储在 HDFS 中的原始数据大小的 4 倍。但是,这些文件很少以未压缩的方式存储,并且根据文件内容和压缩算法,我们看到存储在 HDFS 中的文本文件的平均压缩率高达 10-20。因此,实际所需的原始磁盘空间仅为原始未压缩大小的 30-50% 左右。

如果我可以添加一些东西,如果空间真的是一个限制,你应该考虑压缩中间输出(在映射器和减速器之间)以减少中间 shuffle 文件。您可以通过以下方式执行此操作,例如使用 Gzip 压缩:

conf.set(“mapred.compress.map.output”, “true”)
conf.set(“mapred.output.compression.type”, “BLOCK”);
conf.set(“mapred.map.output.compression.codec”, “org.apache.hadoop.io.compress.GzipCodec”);
于 2013-01-16T15:06:03.190 回答