Java 需要帮助使用map Hadoop MapReduce实现此算法吗

Java 需要帮助使用map Hadoop MapReduce实现此算法吗,java,hadoop,mapreduce,Java,Hadoop,Mapreduce,我有一个算法,它将通过一个大的数据集读取一些文本文件,并在这些行中搜索特定的术语。我已经用Java实现了它,但我不想发布代码,这样看起来就不一样了。我正在寻找一个人来为我实现它,但这是真的,我真的需要很多帮助!!!这不是为我的项目计划的,但数据集是巨大的,所以老师告诉我必须这样做 编辑(我没有说明我的previos版本)我拥有的数据集在Hadoop集群上,我应该实现它的MapReduce 我读过关于MapReduce的文章,认为我首先要做的是标准实现,然后用MapReduce做起来会比较容易。但

我有一个算法,它将通过一个大的数据集读取一些文本文件,并在这些行中搜索特定的术语。我已经用Java实现了它,但我不想发布代码,这样看起来就不一样了。我正在寻找一个人来为我实现它,但这是真的,我真的需要很多帮助!!!这不是为我的项目计划的,但数据集是巨大的,所以老师告诉我必须这样做

编辑(我没有说明我的previos版本)我拥有的数据集在Hadoop集群上,我应该实现它的MapReduce

我读过关于MapReduce的文章,认为我首先要做的是标准实现,然后用MapReduce做起来会比较容易。但这并没有发生,因为算法很愚蠢,也没什么特别的,而且地图缩小了……我不能把我的思想完全放在它上面

下面是我的算法的伪代码

LIST termList   (there is method that creates this list from lucene index)
FOLDER topFolder

INPUT topFolder
IF it is folder and not empty
    list files (there are 30 sub folders inside)
    FOR EACH sub folder
        GET file "CheckedFile.txt"
        analyze(CheckedFile)
    ENDFOR
END IF


Method ANALYZE(CheckedFile)

read CheckedFile
WHILE CheckedFile has next line
    GET line
    FOR(loops through termList)
            GET third word from line
          IF third word = term from list
        append whole line to string buffer
    ENDIF
ENDFOR
END WHILE
OUTPUT string buffer to file
另外,正如您所看到的,每次调用“analyze”时,都必须创建新文件,我知道map reduce很难写入许多输出

我理解mapreduce的直觉,我的例子似乎非常适合mapreduce,但当谈到这一点时,显然我知道的不够,我被卡住了


请帮忙

您可以只使用一个空的reducer,并对作业进行分区以运行单个映射程序文件。每个映射程序都将在输出文件夹中创建自己的输出文件。

Map Reduce可以使用一些优秀的Java 6并发功能轻松实现,特别是Future、Callable和ExecutorService

我创建了一个Callable,它将以您指定的方式分析文件

public class FileAnalyser implements Callable<String> {

  private Scanner scanner;
  private List<String> termList;

  public FileAnalyser(String filename, List<String> termList) throws FileNotFoundException {
    this.termList = termList;
    scanner = new Scanner(new File(filename));
  }

  @Override
  public String call() throws Exception {
    StringBuilder buffer = new StringBuilder();
    while (scanner.hasNextLine()) {
      String line = scanner.nextLine();
      String[] tokens = line.split(" ");
      if ((tokens.length >= 3) && (inTermList(tokens[2])))
        buffer.append(line);
    }
    return buffer.toString();
  }

  private boolean inTermList(String term) {
    return termList.contains(term);
  }
}
公共类FileAnalyzer实现可调用{
私人扫描仪;
私人名单;
公共文件分析器(字符串文件名,列表术语列表)抛出FileNotFoundException{
this.termList=termList;
扫描仪=新扫描仪(新文件(文件名));
}
@凌驾
公共字符串调用()引发异常{
StringBuilder缓冲区=新的StringBuilder();
while(scanner.hasNextLine()){
字符串行=scanner.nextLine();
String[]tokens=line.split(“”);
if((tokens.length>=3)和&(inTermList(tokens[2]))
buffer.append(行);
}
返回buffer.toString();
}
私有布尔值列表(字符串术语){
返回术语列表。包含(术语);
}
}
我们需要为找到的每个文件创建一个新的可调用文件,并将其提交给executor服务。提交的结果是一个未来的结果,我们可以稍后使用它来获得文件解析的结果

public class Analayser {

  private static final int THREAD_COUNT = 10;

  public static void main(String[] args) {

    //All callables will be submitted to this executor service
    //Play around with THREAD_COUNT for optimum performance
    ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT);

    //Store all futures in this list so we can refer to them easily
    List<Future<String>> futureList = new ArrayList<Future<String>>();

    //Some random term list, I don't know what you're using.
    List<String> termList = new ArrayList<String>();
    termList.add("terma");
    termList.add("termb");

    //For each file you find, create a new FileAnalyser callable and submit
    //this to the executor service. Add the future to the list
    //so we can check back on the result later
    for each filename in all files {
      try {
        Callable<String> worker = new FileAnalyser(filename, termList);
        Future<String> future = executor.submit(worker);
        futureList.add(future);
      }
      catch (FileNotFoundException fnfe) {
        //If the file doesn't exist at this point we can probably ignore,
        //but I'll leave that for you to decide.
        System.err.println("Unable to create future for " + filename);
        fnfe.printStackTrace(System.err);
      }
    }

    //You may want to wait at this point, until all threads have finished
    //You could maybe loop through each future until allDone() holds true
    //for each of them.

    //Loop over all finished futures and do something with the result
    //from each
    for (Future<String> current : futureList) {
      String result = current.get();
      //Do something with the result from this future
    }
  }
}
公共类分析器{
私有静态最终整数线程计数=10;
公共静态void main(字符串[]args){
//所有可调用项都将提交到此executor服务
//使用线程计数进行游戏,以获得最佳性能
ExecutorService executor=Executors.newFixedThreadPool(线程计数);
//将所有期货存储在此列表中,以便我们可以方便地参考它们
List futureList=新建ArrayList();
//一些随机的术语列表,我不知道你在用什么。
List termList=newarraylist();
术语表。添加(“术语表”);
条款清单。添加(“条款B”);
//对于找到的每个文件,创建一个可调用的新FileAnalyzer并提交
//这将添加到executor服务。将未来添加到列表中
//所以我们可以稍后再查看结果
对于所有文件中的每个文件名{
试一试{
Callable worker=新文件分析器(文件名,术语列表);
未来=执行人提交(工人);
添加(未来);
}
捕获(FileNotFoundException fnfe){
//如果该文件此时不存在,我们可能会忽略它,
//但我会让你决定的。
System.err.println(“无法为“+文件名”创建未来);
fnfe.printStackTrace(System.err);
}
}
//此时您可能需要等待,直到所有线程都完成
//您可能会在每个未来循环,直到allDone()为真
//对他们每个人来说。
//循环所有已完成的未来,并对结果做一些事情
//各自
用于(未来-当前:未来列表){
字符串结果=current.get();
//用这个未来的结果做点什么
}
}
}
我这里的例子远远不够完整,也远远不够有效。我还没有考虑过样本量,如果样本量真的很大,你可以继续在futureList上循环,删除已经完成的元素,类似于:

while (futureList.size() > 0) {
      for (Future<String> current : futureList) {
        if (current.isDone()) {
          String result = current.get();
          //Do something with result
          futureList.remove(current);
          break; //We have modified the list during iteration, best break out of for-loop
        }
      }
}
while(futureList.size()>0){
用于(未来-当前:未来列表){
if(current.isDone()){
字符串结果=current.get();
//做一些有结果的事情
未来列表。删除(当前);
break;//我们在迭代过程中修改了列表,这是for循环的最佳中断
}
}
}
或者,您可以实现生产者-消费者类型设置,生产者向executor服务提交可调用项并生成未来,消费者获取未来的结果,然后丢弃未来

这可能需要product和consumer线程本身,以及一个用于添加/删除未来的同步列表


有任何问题请提问。

嗨!非常感谢您提出的解决方案!!很抱歉,我可能没有明确说明问题,尽管我已经试过了。我的错误,我刚才在标题中提到了Hadoop,但我的数据集位于运行Hadoop的集群上,所以我应该根据Hadoop MaPreduce框架实现它。。。我现在将编辑我的帖子。我正在分析的数据集是6GB:/太多了,并发性无法处理它????哎呀,我在这里是个傻瓜:D为了稍微补偿我自己,我在100个文件上运行了我的代码,每个文件约61MB,总共约6GB。我不完全确定你的文件解析器做了什么,所以省略了血淋淋的细节,只是扫描了每一行并返回了一个空字符串。我知道有点做作。性能并不太糟糕,线程池大小为100