将带参数的文件传递给mapreduce作业

时间:2012-09-30 09:55:22

标签: java configuration hadoop mapreduce

我有一个mapreduce Mapper。此Mapper应使用一些只读参数集。 让我们想象一下,我想计算输入行中某些子串(某些东西的标题)的出现。 我有一对配对列表:“some title”=> “从输入行提取此标题的正则表达式”。 这些对存储在通常的文本文件中。

将此文件传递给Mapper的最佳方法是什么? 我只有这个想法:

  1. 将成对上传文件到hdfs。
  2. 使用-Dpath.to.file.with.properties
  3. 将路径传递给文件
  4. 在mapper读取文件的static {}部分中并填充地图对“some title”=> “标题的常规expr”。
  5. 好还是坏?请adivce

2 个答案:

答案 0 :(得分:4)

你正在走上正轨,但我建议使用distributed cache.它的目的正是为此 - 将只读文件传递给任务节点。

  1. 将文件放入HDFS
  2. 将该文件添加到应用程序主方法中的分布式缓存中。
  3. 在Mapper类中,根据您使用的API版本覆盖configuresetup方法。在该方法中,它可以从分布式缓存中读取并将所有内容存储在内存中。

答案 1 :(得分:1)

这是我的代码的一部分。 请参阅将文件复制到HDFS并启动mr-job的脚本。我使用ant:scp,ssh targets在maven intergation-test阶段将此脚本上传到hadoop节点。

#dummy script for running mr-job
hadoop fs -rm -r /HttpSample/output
hadoop fs -rm -r /HttpSample/metadata.csv
hadoop fs -rm -r /var/log/hadoop-yarn/apps/cloudera/logs
#hadoop hadoop dfs -put /home/cloudera/uploaded_jars/metadata.csv /HttpSample/metadata.csv
hadoop fs -copyFromLocal  /home/cloudera/uploaded_jars/metadata.csv /HttpSample/metadata.csv
hadoop fs -copyFromLocal  /home/cloudera/uploaded_jars/opencsv.jar /HttpSample/opencsv.jar
hadoop fs -copyFromLocal  /home/cloudera/uploaded_jars/gson.jar /HttpSample/gson.jar
#Run mr job
cd /home/cloudera/uploaded_jars
#hadoop jar scoring-job.jar ru.megalabs.mapreduce.scoringcounter.Main -libjars gson.jar -files hdfs://0.0.0.0:8020/HttpSample/metadata.csv -libjars hdfs://0.0.0.0:8020/HttpSample/opencsv.jar, hdfs://0.0.0.0:8020/HttpSample/gson.jar /HttpSample/raw_traffic.json /HttpSample/output/scoring_result
hadoop jar scoring-job.jar ru.megalabs.mapreduce.scoringcounter.Main -files hdfs://0.0.0.0:8020/HttpSample/metadata.csv -libjars hdfs://0.0.0.0:8020/HttpSample/opencsv.jar,hdfs://0.0.0.0:8020/HttpSample/gson.jar /HttpSample/raw_traffic.json /HttpSample/output/scoring_result

Mapper中的代码:

public class ScoringCounterMapper extends Mapper<LongWritable, Text, GetReq, IntWritable> {

    private static final Log LOG = LogFactory.getLog(ScoringCounterMapper.class);

    private static final String METADATA_CSV = "metadata.csv";

    private List<RegexMetadata> regexMetadatas = null;

    private final static IntWritable one = new IntWritable(1);

    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
//bal-bla-lba
}

    @Override
    protected void setup(Context context) throws IOException, InterruptedException {
    MetadataCsvReader metadataCsvReader = new MetadataCsvReader(new File(METADATA_CSV));
    regexMetadatas = metadataCsvReader.getMetadata();
    for(RegexMetadata rm : regexMetadatas){
        LOG.info(rm);   
    }


    }
}

看到: 1.我确实将我的元数据文件上传到节点 我把它放到了HDFS上 3.我确实提供了使用-Files参数的文件路径 4.我确实指定此文件位于HDFS内(hdfs://0.0.0.0:8020 / HttpSample / metadata.csv)