使用 TotalOrderPartitioner 时,抛出异常:File _partition.lst does not exist

本文探讨了在Hadoop环境下使用TotalOrderPartitioner遇到的问题,即分区文件未被正确设置,导致采样结果写入错误路径。文中详细分析了问题的原因,并提供了两种解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

情景:

    编程环境:Hadoop-1.2.1;使用NEW API

    如下边代码,TotalOrderPartitioner.setPartitionFile(...) 后,在 TotalOrderPartitioner 的 setConf(...) 方法中抛出异常  java.io.FileNotFoundException: File _partition.lst does not exist.  

job.setPartitionerClass(TotalOrderPartitioner.class); 
	
InputSampler.RandomSampler<IntWritable, NullWritable> sampler = 
new InputSampler.RandomSampler<IntWritable, NullWritable>(0.1, 10000, 10);
	
Path partitionFile = new Path(input, "_partitions");
TotalOrderPartitioner.setPartitionFile(conf, partitionFile);
InputSampler.writePartitionFile(job, sampler);    .......

    查看结果发现,采样的结果没有写入到 partitionFile 中。而是写入到 /user/{user_name}/_partition.lst 的文件里面。

通过 Eclipse 调试,找到在 下边的函数

InputSampler.writePartitionFile(job, sampler);

代码里面:

public static <K,V> void writePartitionFile(Job job, Sampler<K,V> sampler) // InputSampler.writePatitionFile(...)
      throws IOException, ClassNotFoundException, InterruptedException {
    Configuration conf = job.getConfiguration();
    final InputFormat inf = 
        ReflectionUtils.newInstance(job.getInputFormatClass(), conf);
    int numPartitions = job.getNumReduceTasks();
    K[] samples = sampler.getSample(inf, job);
    LOG.info("Using " + samples.length + " samples");
    RawComparator<K> comparator =
      (RawComparator<K>) job.getSortComparator();
    Arrays.sort(samples, comparator);
    Path dst = new Path(TotalOrderPartitioner.getPartitionFile(conf));
    FileSystem fs = dst.getFileSystem(conf);
    if (fs.exists(dst)) {
      fs.delete(dst, false);
    }
    ...
}
第 03 行:通过 job.getConfiguration() 获取的 conf 配置对象
第 12 行:获取的 Path dst 也不是 我设置的路径


原因:

    可以跑一下下面的代码:

Configuration conf = new Configuration();
Job job = new Job(conf);
TotalOrderPartitioner.setPartitionFile(conf, partitionFile); 
String pf = TotalOrderPartitioner.getPartitionFile( conf );
System.out.println("pf: " + pf);
pf = TotalOrderPartitioner.getPartitionFile( job.getConfiguration() );
System.out.println("pf2: " + pf);

会得到不一样的结果。

具体为什么 conf  与 job.getConfiguration() 根本上有什么区别,还要进一步对源代码进行学习。


解决方法:

方法一:

    查看了 InputSampler.writePartitionFile(...); 源码发现其中使用的是:jog。getConfiguration conf = job.getConfiguration();

所以在main函数里面就要使用:

TotalOrderPartitioner.setPartitionFile( job.getConfiguration(), partitionFile); 

方法二(我没测试过,可以试试):

    使用Old API,使用的参数可能会明确一些。



                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值