如何使用Hadoop分布式缓存将文件放入内存?

如何使用Hadoop分布式缓存将文件放入内存?,hadoop,distributed-cache,Hadoop,Distributed Cache,据我所知,分布式缓存将文件复制到每个节点,然后映射或减少从本地文件系统读取文件 我的问题是:有没有一种方法可以使用Hadoop分布式缓存将文件放入内存,这样每个map或reduce都可以直接从内存读取文件 我的MapReduce程序向每个节点分发一张大约1M的png图片,然后每个地图任务从分布式缓存中读取图片,并对来自地图输入的另一张图片进行一些图像处理。import java.io.BufferedReader; import java.io.BufferedReader; import ja

据我所知,分布式缓存将文件复制到每个节点,然后映射或减少从本地文件系统读取文件

我的问题是:有没有一种方法可以使用Hadoop分布式缓存将文件放入内存,这样每个map或reduce都可以直接从内存读取文件

我的MapReduce程序向每个节点分发一张大约1M的png图片,然后每个地图任务从分布式缓存中读取图片,并对来自地图输入的另一张图片进行一些图像处理。

import java.io.BufferedReader;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.URI;
import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.filecache.DistributedCache;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;

public class WordCount {

  public static class TokenizerMapper 
       extends Mapper<Object, Text, Text, IntWritable>{

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

    public void map(Object key, Text value, Context context
                    ) throws IOException, InterruptedException {

          Path[] uris = DistributedCache.getLocalCacheFiles(context
                    .getConfiguration());





                    try{
                        BufferedReader readBuffer1 = new BufferedReader(new FileReader(uris[0].toString()));
                        String line;
                        while ((line=readBuffer1.readLine())!=null){
                            System.out.println(line);

                        }
                        readBuffer1.close(); 
                    }       
                    catch (Exception e){
                        System.out.println(e.toString());
                    }

                  StringTokenizer itr = new StringTokenizer(value.toString());

      while (itr.hasMoreTokens()) {
        word.set(itr.nextToken());
        context.write(word, one);
      }
    }
  }

  public static class IntSumReducer 
       extends Reducer<Text,IntWritable,Text,IntWritable> {
    private IntWritable result = new IntWritable();

    public void reduce(Text key, Iterable<IntWritable> values, 
                       Context context
                       ) throws IOException, InterruptedException {
      int sum = 0;
      for (IntWritable val : values) {
        sum += val.get();
      }
      int length=key.getLength();
      System.out.println("length"+length);
      result.set(sum);
/*      key.set("lenght"+lenght);*/
      context.write(key, result);


    }
  }

  public static void main(String[] args) throws Exception {

      final String NAME_NODE = "hdfs://localhost:9000";
    Configuration conf = new Configuration();

    String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
    if (otherArgs.length != 2) {
      System.err.println("Usage: wordcount <in> <out>");
      System.exit(2);
    }
    Job job = new Job(conf, "word count");
    job.setJarByClass(WordCount.class);
    job.setMapperClass(TokenizerMapper.class);
    job.setCombinerClass(IntSumReducer.class);
    job.setReducerClass(IntSumReducer.class);
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(IntWritable.class);


    DistributedCache.addCacheFile(new URI(NAME_NODE
      + "/dataset1.txt"),
      job.getConfiguration());



    FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
    FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
    System.exit(job.waitForCompletion(true) ? 0 : 1);
  }

}
导入java.io.FileReader; 导入java.io.IOException; 导入java.net.URI; 导入java.util.StringTokenizer; 导入org.apache.hadoop.conf.Configuration; 导入org.apache.hadoop.filecache.DistributedCache; 导入org.apache.hadoop.fs.Path; 导入org.apache.hadoop.io.IntWritable; 导入org.apache.hadoop.io.Text; 导入org.apache.hadoop.mapreduce.Job; 导入org.apache.hadoop.mapreduce.Mapper; 导入org.apache.hadoop.mapreduce.Reducer; 导入org.apache.hadoop.mapreduce.lib.input.FileInputFormat; 导入org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; 导入org.apache.hadoop.util.GenericOptionsParser; 公共类字数{ 公共静态类令牌映射器 扩展映射器{ 私有最终静态IntWritable one=新的IntWritable(1); 私有文本字=新文本(); 公共无效映射(对象键、文本值、上下文 )抛出IOException、InterruptedException{ 路径[]URI=DistributedCache.getLocalCacheFiles(上下文 .getConfiguration()); 试一试{ BufferedReader readBuffer1=新的BufferedReader(新的文件读取器(URI[0].toString()); 弦线; 而((line=readBuffer1.readLine())!=null){ 系统输出打印项次(行); } readBuffer1.close(); } 捕获(例外e){ System.out.println(例如toString()); } StringTokenizer itr=新的StringTokenizer(value.toString()); 而(itr.hasMoreTokens()){ set(itr.nextToken()); 上下文。写(单词,一); } } } 公共静态类IntSumReducer 伸缩减速机{ 私有IntWritable结果=新的IntWritable(); public void reduce(文本键、Iterable值、, 语境 )抛出IOException、InterruptedException{ 整数和=0; for(可写入值:值){ sum+=val.get(); } int length=key.getLength(); 系统输出打印项次(“长度”+长度); 结果集(总和); /*键设置(“长度”+长度)*/ 编写(键、结果); } } 公共静态void main(字符串[]args)引发异常{ 最终字符串名称\u节点=”hdfs://localhost:9000"; Configuration conf=新配置(); String[]otherArgs=新的GenericOptionsParser(conf,args); if(otherArgs.length!=2){ System.err.println(“用法:wordcount”); 系统出口(2); } Job Job=新作业(conf,“字数”); job.setJarByClass(WordCount.class); setMapperClass(TokenizerMapper.class); job.setCombinerClass(IntSumReducer.class); job.setReducerClass(IntSumReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); DistributedCache.addCacheFile(新URI(名称\u节点 +“/dataset1.txt”), job.getConfiguration()); addInputPath(作业,新路径(其他参数[0]); setOutputPath(作业,新路径(其他参数[1]); 系统退出(作业等待完成(真)?0:1; } }
好问题。我还试图解决类似的问题。我认为Hadoop不支持现成的内存缓存。但是,在网格上的某个地方使用另一个内存缓存来实现这一目的应该不是很困难。作为作业配置的一部分,我们可以传递缓存的位置和参数的名称


就上面的代码示例而言,它并没有回答最初的问题。此外,它还展示了非最佳代码示例。理想情况下,您应该作为setup()方法的一部分访问缓存文件,并缓存您可能希望作为map()方法的一部分使用的任何信息。在上面的示例中,每个键值对将读取一次缓存文件,这会影响mapreduce作业的性能。

谢谢。我知道如何使用分布式缓存。我的问题是如何将文件放入内存而不是本地文件系统。在您的程序中,每个地图都将从本地文件系统读取dataset1.txt。Spark似乎可以满足我的需求。请在setup()中加载图片。