1

我有一个 mapreduce 映射器。这个 Mapper 应该使用一些只读参数。假设我想计算输入行中某些子字符串(某物的标题)的出现次数。我确实有一个配对列表:“某个标题”=>“从输入行中提取此标题的正则表达式”。这些对存储在通常的文本文件中。

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

  1. 将文件成对上传到 hdfs。
  2. 使用 -Dpath.to.file.with.properties 将路径传递给文件
  3. 在映射器读取文件的静态{}部分并填充映射对“某些标题”=>“标题的常规表达式”。

是好还是坏?请建议

4

2 回答 2

4

你走上了正轨,但我建议使用分布式缓存。它的目的正是为了这个——将只读文件传递给任务节点。

  1. 将文件放入 HDFS
  2. 在应用程序的 main 方法中将该文件添加到分布式缓存中。
  3. 在 Mapper 类中,根据您使用的 API 版本覆盖configure或方法。setup在该方法中,它可以从分布式缓存中读取并将所有内容存储在内存中。
于 2012-10-01T17:12:48.883 回答
1

这是我的代码的一部分。查看将文件复制到 HDFS 并启动 mr-job 的脚本。我确实在 maven 集成测试阶段使用 ant: scp, ssh 目标将此脚本上传到 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. 我确实将我的元数据文件上传到节点 2. 我确实把它放到了 HDFS 3. 我确实使用 -Files 参数提供了文件路径 4. 我确实指定这个文件在 HDFS 内 (hdfs://0.0 .0.0:8020/HttpSample/metadata.csv)

于 2012-10-07T12:13:10.690 回答