Mapreduce倒排索引代码详解

InvertedIndexMapper-类

package org.joe.project;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;

import java.io.IOException;

public class InvertedIndexMapper extends Mapper<LongWritable, Text,Text, Text> {
    private static final Text keyInfo = new Text();
    private static final Text valueInfo = new Text("1");
    @Override
    protected  void map(LongWritable key, Text value, Context context)throws IOException,InterruptedException{
        String line = value.toString();
        String[] fields = line.split(" ");// 得到字段数组
        FileSplit fileSplit = (FileSplit) context.getInputSplit();// 得到这行数据所在的文件切片
        String fileName = fileSplit.getPath().getName();// 根据文件切片得到文件名
        for (String field : fields) {
            // key值由单词和URL组成,如“MapReduce->file1”
            keyInfo.set(field + "->" + fileName);
            context.write(keyInfo, valueInfo);
        }
    }
}

package org.joe.project;
  • package 关键字用于声明一个 Java 类所在的包。
  • org.joe.project 是一个包名,它表示这个 Java 类属于 org.joe.project 这个包。
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
  • org.apache.hadoop.io 包:

作用:这个包提供了用于在Hadoop分布式文件系统(HDFS)中读写数据的基本数据类型和工具类。以下是一些常用的类和它们的作用:

  1. Text:用于存储文本数据的类。
  2. LongWritable:用于存储长整数数据的类。
  3. IntWritable:用于存储整数数据的类。
  4. NullWritable:用于表示空值的类。

这些类用于在MapReduce任务中表示输入数据和输出数据的键值对。它们有助于将数据序列化和反序列化,并在不同任务之间传递数据。

  • org.apache.hadoop.mapreduce 包:

作用:这个包包含了Hadoop MapReduce框架的核心类,用于编写和执行MapReduce作业。以下是一些常用的类和它们的作用:

  1. Mapper:用于编写Mapper任务的抽象类,定义了 map 方法,用于处理输入数据并生成中间键值对。
  2. Reducer:用于编写Reducer任务的抽象类,定义了 reduce 方法,用于对Mapper输出进行聚合。
  3. Job:用于配置和提交MapReduce作业的类。
  4. Configuration:用于管理Hadoop配置信息的类,包括输入和输出路径、文件系统等。

这些类是编写和执行MapReduce作业的关键组成部分,开发人员可以继承它们来编写自定义的Mapper和Reducer。

  • org.apache.hadoop.mapreduce.lib.input.FileSplit 类:

作用:这个类用于获取输入文件的切片信息。在MapReduce任务中,输入数据通常被划分成多个文件切片,每个切片由一个Mapper处理。FileSplit 可以用来获取当前Mapper正在处理的切片的相关信息,例如文件名、偏移量等。这对于了解输入数据的来源和上下文非常有用。

import java.io.IOException;

这是一个异常类。它通常用于处理与输入和输出操作相关的异常情况,例如文件读写时可能发生的错误。

public class InvertedIndexMapper extends Mapper<LongWritable, Text,Text, Text>
  • public class InvertedIndexMapper:这行代码定义了一个名为 InvertedIndexMapper 的Java类,它是一个公共类,可被其他类访问和使用。
  • extends Mapper<LongWritable, Text, Text, Text>:这部分表示 InvertedIndexMapper 类继承自Hadoop MapReduce框架中的 Mapper 类。Mapper 类是一个抽象类,它定义了用于执行映射操作的模板方法,您需要在子类中实现它。<LongWritable, Text, Text, Text> 是泛型参数,指定了输入键类型、输入值类型、输出键类型和输出值类型。

private static final Text keyInfo = new Text();
  • private static final:这是Java中的关键字组合,用于声明一个私有静态常量成员变量。私有 (private) 表示该成员变量只能在当前类内部访问,静态 (static) 表示它属于类而不是实例,常量 (final) 表示它的值在初始化后不能被修改。

  • Text:这是Hadoop中的数据类型,用于表示文本数据。它是一个可变的字符串,类似于Java标准库中的 String 类。Text 类允许在Hadoop MapReduce任务中有效地表示和处理文本数据。

  • keyInfo:这是一个成员变量的名称,它表示用于存储键信息的 Text 对象。

  • = new Text();:这是对 keyInfo 变量的初始化。通过使用 new Text(),我们创建了一个新的空的 Text 对象并将其分配给 keyInfo 变量。这意味着 keyInfo 在初始化时是一个空字符串。

private static final Text valueInfo = new Text("1");
  • private static final:这是Java中的关键字组合,用于声明一个私有静态常量成员变量。私有 (private) 表示该成员变量只能在当前类内部访问,静态 (static) 表示它属于类而不是实例,常量 (final) 表示它的值在初始化后不能被修改。

  • Text:这是Hadoop中的数据类型,用于表示文本数据。它是一个可变的字符串,类似于Java标准库中的 String 类。Text 类允许在Hadoop MapReduce任务中有效地表示和处理文本数据。

  • valueInfo:这是一个成员变量的名称,它表示用于存储值信息的 Text 对象。

  • = new Text("1");:这是对 valueInfo 变量的初始化。通过使用 new Text("1"),我们创建了一个包含字符串 "1" 的 Text 对象并将其分配给 valueInfo 变量。这意味着 valueInfo 在初始化时包含值 "1"。

   @Override

@Override 是Java中的一个注解(Annotation),用于表示一个方法是在子类中覆盖(重写)了父类中的方法。这个注解的作用是在编译时检查,以确保子类中的方法确实是在父类中存在的方法的有效覆盖。

protected  void map(LongWritable key, Text value, Context context)throws IOException,InterruptedException
  • protected:这是方法的访问修饰符。在Java中,protected 表示该方法可以在当前类和同一包内的子类中访问,以及在其他包中的子类中访问。在这里,map 方法是被子类继承和覆盖的方法,所以通常会使用 protected 修饰符。

  • void:这是方法的返回类型。void 表示该方法不返回任何值。

  • map:这是方法的名称,表示这个方法是Mapper类中的映射方法。

  • (LongWritable key, Text value, Context context):这是方法的参数列表,它定义了方法接受的参数。具体解释如下:

    • LongWritable key:这是输入的键,通常表示行号。在MapReduce中,输入数据按行划分,每行都有一个键,这个键通常用 LongWritable 类型表示。
    • Text value:这是输入的值,表示当前行的文本数据。在MapReduce任务中,数据通常以文本形式传递,并使用 Text 类型表示。
    • Context context:这是一个上下文对象,它提供了与Hadoop框架的交互功能,包括输入、输出、配置等。通过 context 对象,您可以读取输入数据、写入输出数据以及与MapReduce作业的其他部分进行通信。
  • throws IOException, InterruptedException:这是方法的异常声明。它表示 map 方法可能会抛出 IOExceptionInterruptedException 异常。这些异常通常与文件操作和多线程操作相关,因此在处理输入数据时可能需要捕获或抛出这些异常。

String line = value.toString();
  • value 是一个 Text 对象,它包含了当前Mapper正在处理的一行文本数据。
  • toString() 方法是 Text 类的方法,用于将 Text 对象转换为字符串表示。
  • String line 是一个新的字符串变量,它用于存储从 Text 对象中提取的文本数据。
String[] fields = line.split(" ");// 得到字段数组
  • line 是先前从 value 中提取的文本数据,它是一行字符串,可能包含了多个字段,这些字段通常由空格字符分隔。
  • split(" ") 方法是字符串的一个常用方法,它接受一个分隔符作为参数,并将字符串分割成一个字符串数组。在这里,空格字符 " " 被用作分隔符,表示将 line 字符串按照空格字符进行分割。
  • 分割后的子字符串会被存储在字符串数组 fields 中。每个子字符串都代表了原始字符串中的一个字段。
FileSplit fileSplit = (FileSplit) context.getInputSplit();
  • FileSplit 是Hadoop中的一个类,用于表示输入数据的文件切片。在MapReduce任务中,输入数据通常被切分成多个文件切片,每个切片由一个Mapper任务处理。FileSplit 对象包含了关于当前切片的信息,例如文件名、起始偏移量和切片长度等。
  • context 是Mapper任务的上下文对象,它是一个参数传递给 map 方法的对象,用于与Hadoop框架进行交互。
  • getInputSplit()context 对象的一个方法,用于获取当前Mapper任务正在处理的输入切片(InputSplit)。因为 InputSplitFileSplit 的父类,所以可以通过类型转换将其转换为 FileSplit
  • (FileSplit) context.getInputSplit() 执行了类型转换,将获取的输入切片转换为 FileSplit 对象,并将其赋值给 fileSplit 变量。
String fileName = fileSplit.getPath().getName();
  • fileSplit 是之前从 context 中获取的 FileSplit 对象,它包含了关于当前Mapper任务正在处理的文件切片的信息,包括文件名、起始偏移量、切片长度等。
  • getPath()FileSplit 类的方法,用于获取文件切片的路径信息,通常返回一个 Path 对象,它表示文件的路径。
  • getName()Path 类的方法,用于获取文件路径中的文件名部分。这个方法返回一个字符串,表示文件的名称。
  • String fileName 是一个字符串变量,它用于存储从文件切片路径中提取的文件名。
for (String field : fields) {
    // key值由单词和URL组成,如“MapReduce->file1”
    keyInfo.set(field + "->" + fileName);
    context.write(keyInfo, valueInfo);
}
  • for (String field : fields):这是一个增强型的 for 循环,用于遍历 fields 数组中的每个字符串字段。fields 数组是之前从输入文本数据中分割得到的,每个元素代表一个字段。
  1. keyInfo.set(field + "->" + fileName):在循环中,对于每个字段 field,这行代码构建了一个新的键(keyInfo)。
  2. 键的格式是 field + "->" + fileName,它由两部分组成:
  3. field:当前字段的内容,通常是一个单词或短语。
  4. fileName:之前从文件切片中获取的文件名,表示数据的来源文件。

这个格式将字段和文件名组合在一起,以创建一个唯一的键,用于标识单词和它所在的文件。

  • context.write(keyInfo, valueInfo):这行代码将构建的键值对写入MapReduce框架的输出中。
  1. keyInfo 是键,它包含了字段和文件名的组合,用于唯一标识一个单词在特定文件中的出现。
  2. valueInfo 是值,它始终为 "1",通常用于在后续的Reducer任务中执行计数操作。

InvertedIndexPatitioner-类

package org.joe.project;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Partitioner;

public class InvertedIndexPatitioner extends Partitioner<Text,Text> {
    private static int PatitionNumber=0;
    @Override
    public int getPartition(Text text, Text text2, int i) {
        // 写分区规则,返回分区号;分区数为i;分区尽量使数据均匀分散到各个区,避免有的分区数据过多,有的分区没有数
        String word=text.toString().trim();
        if (word.length()==0) return 0;
        char firstchar=Character.toUpperCase(word.charAt(0));
        if (firstchar>='A'&&firstchar<='M')
            PatitionNumber=1;
        else  if (firstchar>='N'&&firstchar<='Z')
            PatitionNumber=2;
        else PatitionNumber=0;
        return PatitionNumber;
    }
}

import org.apache.hadoop.io.Text;

org.apache.hadoop.io.Text: 这是一个完全限定的类名,指的是 Apache Hadoop 库中的 Text 类。Text 类是 Hadoop 中用于表示文本数据的数据类型。它类似于 Java 中的字符串(String),但被优化用于大规模数据处理,特别是在分布式计算中。

import org.apache.hadoop.mapreduce.Partitioner;

org.apache.hadoop.mapreduce.Partitioner: 这是一个完全限定的类名,指的是 Apache Hadoop 库中的 Partitioner 类。Partitioner是 Hadoop 中的一个抽象类,它用于定义如何将 Map 阶段的输出数据分区成不同的 Reduce 任务。在 MapReduce 作业中,数据分区决定了哪些键值对将被发送到同一个 Reduce 任务进行处理。

public class InvertedIndexPatitioner extends Partitioner<Text,Text> 

public class InvertedIndexPatitioner extends Partitioner<Text, Text>: 这是一个类的声明语句。它声明了一个名为 InvertedIndexPatitioner 的类,这个类继承自 Partitioner 类,并使用泛型 <Text, Text> 指定了键和值的类型。在这种情况下,键和值都被指定为 Text 类型,这意味着这个分区器将处理包含文本数据的键值对。

String word=text.toString().trim();

text.toString(): 这是将一个文本对象 text 转换为字符串的操作。在 Hadoop MapReduce 中,通常使用 Text 类来表示文本数据,但有时需要将其转换为标准的 Java 字符串来进行处理。

.trim(): 这是字符串的一个方法,用于移除字符串两端的空白字符(例如空格、制表符、换行符等)。调用 .trim() 方法可以确保去除字符串两端的不可见字符,使字符串更干净。

char firstchar=Character.toUpperCase(word.charAt(0));

word.charAt(0): 这部分代码从字符串 word 中获取索引位置为 0 的字符。在 Java 中,字符串的索引从 0 开始,所以 word.charAt(0) 获取的是字符串 word 的第一个字符。

Character.toUpperCase(...): 这是一个静态方法调用,用于将一个字符转换为大写形式。在这里,它将前面获取的第一个字符转换为大写形式。

char firstchar = ...: 最后,将大写形式的字符赋给变量 firstchar,这个变量将包含字符串 word 的第一个字符的大写版本。

        if (firstchar>='A'&&firstchar<='M')
            PatitionNumber=1;
        else  if (firstchar>='N'&&firstchar<='Z')
            PatitionNumber=2;
        else PatitionNumber=0;
        return PatitionNumber;

根据首字母来进行分区。

InvertedIndexCombiner-类

package org.joe.project;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;

public class InvertedIndexCombiner extends Reducer<Text,Text,Text,Text> {
    private static Text info =new Text();
    @Override
    protected void reduce(Text key,Iterable<Text> values, Context context)throws IOException,InterruptedException{
        int sum = 0;// 统计词频
        for (Text value : values) {
            sum += Integer.parseInt(value.toString());
        }
        int splitIndex = key.toString().indexOf("->");// 重新设置 value 值由 URL 和词频组成
        info.set(key.toString().substring(splitIndex + 1) + "->" + sum);// 重新设置 key 值为单词
        key.set(key.toString().substring(0, splitIndex));
        context.write(key, info);
    }
}

public class InvertedIndexCombiner extends Reducer<Text,Text,Text,Text> 

public class InvertedIndexCombiner extends Reducer<Text, Text, Text, Text>: 这是一个类的声明语句。它声明了一个名为 InvertedIndexCombiner 的类,这个类继承自 Hadoop 中的 Reducer 类,并使用泛型 <Text, Text, Text, Text> 来指定输入和输出的键值对类型。

自定义的组合器类通常用于在 Map 阶段之后、Reduce 阶段之前执行局部汇总操作,以减少数据传输和提高性能。它通常用于将具有相同键的键值对合并在一起,以减小后续处理的数据量。

        for (Text value : values) {
            sum += Integer.parseInt(value.toString());
        }

for (Text value : values): 这是一个增强型的 for 循环,用于迭代处理一个名为 values 的集合(通常是一个 Iterable,例如在 Hadoop MapReduce 中,它是一个 Reducer 的输入值迭代器)。在每次循环迭代中,它将集合中的一个元素赋给变量 value。

sum += Integer.parseInt(value.toString());: 这是在循环内部的代码。它执行以下操作:

        value.toString(): 将 value 对象(通常是一个 Text 类型)转换为标准的 Java 字符串。

        Integer.parseInt(...): 将这个字符串解析为整数。这个方法将字符串表示的整数转换为相应的整数值。

sum += ...: 将解析后的整数值累加到变量 sum 中。

因此,循环会遍历 values 中的每个元素,将它们解析为整数,并将它们累加到 sum 变量中。这通常用于计算一组整数值的总和或累加。

int splitIndex = key.toString().indexOf("->");

key.toString(): 这部分代码将 key 对象(通常是一个 Text 类型)转换为标准的 Java 字符串。在 Hadoop MapReduce 中,键通常用于唯一标识数据,而在处理过程中,可能需要对键执行字符串操作。

indexOf("->"): 这是字符串的一个方法,用于查找指定子字符串(在这里是 "->")在源字符串中的位置。如果找到了该子字符串,它将返回子字符串的起始索引。如果找不到,则返回 -1。

int splitIndex = ...;: 这一行将查找到的子字符串的起始索引赋给整数变量 splitIndex。

info.set(key.toString().substring(splitIndex + 1) + "->" + sum);

key.toString().substring(splitIndex + 1): 这部分代码首先将 key 对象(通常是一个 Text 类型)转换为标准的 Java 字符串,并然后使用 substring(splitIndex + 1) 方法从字符串中提取子字符串。splitIndex 是之前找到的 "->" 的起始索引。所以这部分代码将返回 "->" 后面的子字符串。

sum: 这是一个变量,通常包含一些计算的结果或累加值。

+ "->" +: 这是字符串拼接操作,它将上面两个部分连接起来。结果字符串将包含提取的子字符串,然后是 "->",最后是 sum 的值。

info.set(...): 这是用于设置一个变量或对象的值的语句。在这里,它将连接后的字符串设置为名为 info 的对象的值。

key.set(key.toString().substring(0, splitIndex));

key.toString().substring(0, splitIndex): 这部分代码首先将 key 对象(通常是一个 Text 类型)转换为标准的 Java 字符串,然后使用 substring(0, splitIndex) 方法从字符串中提取子字符串。splitIndex 是之前找到的 "->" 的起始索引。所以这部分代码将返回 "->" 之前的子字符串。

key.set(...): 这是用于设置键(key)的值的语句。在这里,它将从原始键中提取的子字符串设置为新的键的值。

context.write(key, info);

context: 在MapReduce作业中,context 是一个上下文对象,它提供了与Map或Reduce任务的交互能力。这包括将键值对写入输出以及访问配置信息等功能。

context.write(key, info): 这是一个用于写入键值对到输出的语句。具体解释如下:

  • key: 这是要写入的键,通常是一个 Text 对象或与你的MapReduce作业配置相匹配的数据类型。
  • info: 这是要写入的值,也通常是一个 Text 对象或与你的MapReduce作业配置相匹配的数据类型。
  • InvertedIndexReducer-类

  • import org.apache.hadoop.mapreduce.Reducer;

    org.apache.hadoop.mapreduce.Reducer: 这是导入的类的全限定名(fully qualified name)。org.apache.hadoop 是 Hadoop 框架的基本包名,mapreduce 是 Hadoop MapReduce 框架的一部分,而 Reducer 则是 MapReduce 框架中的一个类。

  • public class InvertedIndexReducer extends Reducer<Text, Text, Text, Text>

    public class InvertedIndexReducer extends Reducer<Text, Text, Text, Text>: 这是一个类的声明语句。它声明了一个名为 InvertedIndexReducer 的类,这个类继承自 Hadoop MapReduce 框架中的 Reducer 类,并使用泛型 <Text, Text, Text, Text> 来指定输入和输出的键值对类型。

  • protected void reduce(Text key, Iterable<Text> values, Context context)  throws IOException, InterruptedException

    protected: 这是 Java 中的访问修饰符,表示该方法具有受保护的访问级别。它可以被类的子类访问。

    void: 这是方法的返回类型,表示这个方法不返回任何值。

    reduce: 这是方法的名称,表示这是一个 Reduce 阶段的处理方法。

    (Text key, Iterable<Text> values, Context context): 这是方法的参数列表,它包含三个参数:

    Text key: 这是输入键,通常是一个文档中的单词。

    Iterable<Text> values: 这是与输入键相关联的值的迭代器。这些值通常是文档中单词的位置信息。

    Context context: 这是上下文对象,它提供了与 MapReduce 框架的交互能力,包括写入输出等操作。

    throws IOException, InterruptedException: 这是方法可能抛出的异常列表。在处理数据时,可能会发生 I/O 异常(IOException)或中断异常(InterruptedException),因此在方法签名中声明了这些异常,以便在方法内部处理它们或将它们传播出去。

  • InvertedIndexMain-类

  • import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Job;
    import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
    import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

    import org.apache.hadoop.conf.Configuration;: 这是导入 Hadoop 中的 Configuration 类,用于配置 Hadoop 作业的参数和设置。

    import org.apache.hadoop.fs.Path;: 这是导入 Hadoop 中的 Path 类,用于指定文件和目录的路径。

    import org.apache.hadoop.io.Text;: 这是导入 Hadoop 中的 Text 类,它是一种 Hadoop 数据类型,通常用于表示文本数据。

    import org.apache.hadoop.mapreduce.Job;: 这是导入 Hadoop 中的 Job 类,它用于配置和管理 MapReduce 作业。

    import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;: 这是导入 Hadoop 中的 FileInputFormat 类,用于配置作业的输入文件格式和路径。

    import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;: 这是导入 Hadoop 中的 FileOutputFormat 类,用于配置作业的输出文件格式和路径。

  • Configuration conf =new Configuration();

    Configuration: 这是 Hadoop 中的一个类,用于管理配置信息。Configuration 对象包含了许多配置项,可以用来控制作业的各个方面,例如文件系统设置、作业的输入输出路径、作业的 Mapper 和 Reducer 类等。

    new Configuration(): 这部分代码创建了一个新的 Configuration 对象的实例。这个对象将用于存储和管理作业的配置信息。

  • Job job = Job.getInstance(conf, "invertedindexwithpartitioner");

    Job: 这是 Hadoop 中的一个类,用于配置和管理 MapReduce 作业。Job 对象包含了作业的各种配置,包括输入路径、输出路径、Mapper 类、Reducer 类、作业名称等。

    Job.getInstance(conf, "invertedindexwithpartitioner"): 这部分代码创建了一个新的 Job 对象的实例,并传递了两个参数:

    conf: 这是之前创建的 Configuration 对象,它包含了作业的配置信息。

    "invertedindexwithpartitioner": 这是作业的名称,通常用于标识作业。

  •         if (args.length != 2) {
                System.err.println("Usage: invertedindexwithpartitioner<in> <out>");
                System.exit(2);
            }

    args.length != 2: 这是一个条件判断,用于检查命令行参数的数量是否等于2。在这个上下文中,期望的参数数量是两个,一个是输入路径(<in>),另一个是输出路径(<out>)。

    System.err.println("Usage: invertedindexwithpartitioner <in> <out>");: 如果命令行参数数量不正确,那么程序将使用标准错误流(System.err)打印一条错误消息,指示正确的使用方法。这条消息告诉用户应该如何正确地运行程序,包括输入和输出路径的格式。

    System.exit(2);: 如果参数数量不正确,程序将使用 System.exit() 方法终止执行,并返回一个非零的退出状态码(在这里是2),表示程序的非正常退出。这有助于在脚本或其他自动化流程中捕获错误状态。

  • job.setJarByClass(InvertedIndexMain.class);

    这行代码设置了作业的 Jar 文件,以便在分布式环境中运行 MapReduce 任务时,能够将包含作业代码的 Jar 文件分发到集群的各个节点上。让我解释一下这行代码的作用:

    job.setJarByClass(InvertedIndexMain.class);: 这是调用 Job 对象的方法,其中 setJarByClass 用于设置作业的 Jar 文件。在括号中传递的参数是指定一个类,通常是包含了作业的主类(包括 main 方法)的类。

    InvertedIndexMain.class: 在这里,传递了 InvertedIndexMain.class,它是包含 main 方法的主类。通过指定这个类,Hadoop 将查找并使用包含该类的 Jar 文件作为作业的 Jar 文件。

        job.setMapperClass(InvertedIndexMapper.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(Text.class);

job.setMapperClass(InvertedIndexMapper.class);: 这一行代码设置了作业使用的 Mapper 类,即 InvertedIndexMapper.class。Mapper 类是用于处理输入数据并产生键值对的类。在这个例子中,InvertedIndexMapper 类将被用于执行 Map 阶段的操作。

job.setMapOutputKeyClass(Text.class);: 这一行代码设置了 Map 阶段输出键的数据类型,即键的类型为 Text。在 Map 阶段,Mapper 类会产生一系列键值对,这里指定了键的类型为文本类型。

job.setMapOutputValueClass(Text.class);: 这一行代码设置了 Map 阶段输出值的数据类型,即值的类型为 Text。在 Map 阶段,Mapper 类会产生一系列键值对,这里指定了值的类型也为文本类型。

job.setCombinerClass(InvertedIndexCombiner.class);
  • job.setCombinerClass(InvertedIndexCombiner.class);: 这是调用 Job 对象的方法,用于设置作业使用的 Combiner 类。Combiner 类是可选的,它在 Map 阶段的输出数据进行局部聚合操作,以减少数据传输到 Reduce 阶段的数据量。

    通过设置 Combiner 类,你可以在每个 Map 任务的输出结果中进行一些局部聚合操作,以减少网络传输的数据量和提高性能。在这里,InvertedIndexCombiner.class 是指定的 Combiner 类,它将应用于 Map 阶段的输出数据。

    通常情况下,Combiner 类的功能应该与 Reducer 类的功能类似,但要注意它只在 Map 阶段的输出数据上执行,而不是在整个作业上。这有助于降低数据传输成本,特别是在大规模数据处理中。

  •         job.setPartitionerClass(InvertedIndexPatitioner.class);
            job.setNumReduceTasks(3);

    job.setPartitionerClass(InvertedIndexPatitioner.class);: 这一行代码设置了作业使用的分区器类,即 InvertedIndexPatitioner.class。分区器类用于将 Map 阶段的输出数据分配到不同的 Reduce 任务中。在这里,InvertedIndexPatitioner 类将被用于决定数据分区的逻辑。

    job.setNumReduceTasks(3);: 这一行代码设置了作业使用的 Reduce 任务的数量,即总共有3个 Reduce 任务。Reduce 任务用于对 Map 阶段的输出数据进行汇总和处理。

  •         job.setReducerClass(InvertedIndexReducer.class);
            job.setOutputKeyClass(Text.class);
            job.setOutputValueClass(Text.class);

    job.setReducerClass(InvertedIndexReducer.class);: 这一行代码设置了作业使用的 Reducer 类,即 InvertedIndexReducer.class。Reducer 类是用于处理 Map 阶段输出的键值对数据并生成最终输出的类。在这个例子中,InvertedIndexReducer 类将被用于执行 Reduce 阶段的操作。

    job.setOutputKeyClass(Text.class);: 这一行代码设置了 Reduce 阶段的输出键的数据类型,即键的类型为 Text。在 Reduce 阶段,Reducer 类会产生一系列键值对,这里指定了键的类型为文本类型。

    job.setOutputValueClass(Text.class);: 这一行代码设置了 Reduce 阶段的输出值的数据类型,即值的类型为 Text。在 Reduce 阶段,Reducer 类会产生一系列键值对,这里指定了值的类型也为文本类型。

  •         FileInputFormat.setInputPaths(job, new Path(args[0]));
            FileOutputFormat.setOutputPath(job, new Path(args[1]));

    FileInputFormat.setInputPaths(job, new Path(args[0]));: 这一行代码设置了作业的输入路径,即从哪里读取输入数据。args[0] 是命令行参数中的第一个参数,通常表示输入数据的路径。通过使用 new Path(...) 创建一个 Path 对象,你可以将输入路径指定为 Hadoop 文件系统中的某个目录或文件。

    FileOutputFormat.setOutputPath(job, new Path(args[1]));: 这一行代码设置了作业的输出路径,即将结果输出到哪里。args[1] 是命令行参数中的第二个参数,通常表示输出数据的路径。同样,通过使用 new Path(...) 创建一个 Path 对象,你可以将输出路径指定为 Hadoop 文件系统中的某个目录。

  • boolean flag = job.waitForCompletion(true);

    job.waitForCompletion(true);: 这是一个 Job 对象的方法,用于提交作业并等待其完成。它接受一个布尔参数,如果参数为 true,则作业完成后会打印详细的进度和计数信息,如果参数为 false,则只返回作业的执行结果而不打印详细信息。

    boolean flag: 这是一个布尔变量,它用来存储作业的执行结果。如果作业成功完成,flag 将被设置为 true,否则将被设置为 false。

  •         if (!flag) {
                System.out.println("InvertedIndex failed!");
            }

    if (!flag) {: 这是一个条件判断语句,它检查 flag 的值是否为 false,即作业是否执行失败。

    System.out.println("InvertedIndex failed!");: 如果作业执行失败,这一行代码会使用 System.out.println() 方法打印一条错误消息,指示作业的执行失败。消息内容是 "InvertedIndex failed!",这是一个简单的提示信息,告诉用户作业未能成功完成。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hadoop倒排索引代码实现需要以下几个步骤: 1. 读取输入文件,将每行文本按照单词进行切分。 2. 对于每个单词,将其作为key,将文本所在的文件名作为value,输出到中间结果。 3. 对中间结果进行shuffle和sort操作,将相同单词的value合并到一起。 4. 将合并后的结果按照单词进行分组,将单词作为key,将所有文件名组成的列表作为value,输出到最终结果。 下面是一个简单的Hadoop倒排索引代码实现: ```java public class InvertedIndex { public static class Map extends Mapper<LongWritable, Text, Text, Text> { private Text word = new Text(); private Text docId = new Text(); public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String line = value.toString(); String[] tokens = line.split("\\s+"); docId.set(tokens[0]); for (int i = 1; i < tokens.length; i++) { word.set(tokens[i]); context.write(word, docId); } } } public static class Reduce extends Reducer<Text, Text, Text, Text> { public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException { StringBuilder sb = new StringBuilder(); for (Text value : values) { sb.append(value.toString()).append(" "); } context.write(key, new Text(sb.toString())); } } public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job job = Job.getInstance(conf, "InvertedIndex"); job.setJarByClass(InvertedIndex.class); job.setMapperClass(Map.class); job.setReducerClass(Reduce.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(Text.class); FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); System.exit(job.waitForCompletion(true) ? 0 : 1); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值