hadoop集群的简单运行流程

Hadoop集群是一种分布式数据处理系统,它可以高效地处理大规模数据,通过将任务分发给多台服务器并整合它们的结果来完成工作,让处理大数据变得更快速和可扩展。

当你使用Hadoop集群来处理大量数据时,它就像一台巨大的数据处理工厂,有许多工人(服务器)一起工作。

一.数据分割:将要处理的大数据文件分成小块,就像把一大块巧克力切成小块一样。这些小块叫做数据块。

数据分割在Hadoop集群中是自动进行的,不需要手动编写代码来执行数据分割。Hadoop将大文件分成小块,并在底层管理数据的分布和复制。这是Hadoop的核心功能之一,通常不需要用户编写特定的代码来实现数据分割。
下面是一个简单的示例,说明如何使用Hadoop MapReduce编写一个程序,将输入数据分割成数据块并进行处理。

import java.io.IOException;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
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;

public class DataSplitExample {

    public static class DataSplitMapper
            extends Mapper<LongWritable, Text, Text, IntWritable> {

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

        public void map(LongWritable key, Text value, Context context)
                throws IOException, InterruptedException {
            // 在这里你可以编写自己的数据分割和处理逻辑
            // 这个示例将文本数据拆分成单词并计数
            String[] words = value.toString().split(" ");
            for (String w : words) {
                word.set(w);
                context.write(word, one);
            }
        }
    }

    public static class DataSplitReducer
            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();
            }
            result.set(sum);
            context.write(key, result);
        }
    }

    public static void main(String[] args) throws Exception {
        Job job = Job.getInstance();
        job.setJarByClass(DataSplitExample.class);
        job.setMapperClass(DataSplitMapper.class);
        job.setCombinerClass(DataSplitReducer.class);
        job.setReducerClass(DataSplitReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);
        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }
}

这个示例展示了一个简单的MapReduce程序,用于将文本数据分割成单词并计数。但请注意,Hadoop会自动处理数据分割和数据块的管理,程序员通常只需专注于业务逻辑。

让我们一行一行地分析上面提供的代码。
 

import java.io.IOException;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
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;

首先,导入了所需的Java类库和Hadoop MapReduce相关的类。

public class DataSplitExample {

    public static class DataSplitMapper
            extends Mapper<LongWritable, Text, Text, IntWritable> {

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

定义了一个名为 DataSplitExample 的类,并在类内部定义了一个 DataSplitMapper 类。DataSplitMapper 类继承了 Mapper 类,其泛型参数 LongWritable, Text, Text, IntWritable; 分别表示输入键类型、输入值类型、输出键类型和输出值类型。

oneword是和TextIntWritable 类型的成员变量,它们用于在map函数中进行计数和存储键值对。

        public void map(LongWritable key, Text value, Context context)
                throws IOException, InterruptedException {
            // 在这里你可以编写自己的数据分割和处理逻辑
            // 这个示例将文本数据拆分成单词并计数
            String[] words = value.toString().split(" ");
            for (String w : words) {
                word.set(w);
                context.write(word, one);
            }
        }
    }

DataSplitMapper类中,定义了map方法,该方法是重写父类Mappermap方法。方法接受三个参数:keyvalue context,分别表示输入键、输入值和上下文对象,允许将输出写入Hadoop输出文件。
在这个示例中, map方法将输入的文本数据拆分成单词,并使用context.write方法将每个单词作为输出键,然后将 (计数器)作为输出值发送到Reducer阶段。

    public static class DataSplitReducer
            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();
            }
            result.set(sum);
            context.write(key, result);
        }
    }

接下来,定义了一个名为DataSplitReducer的类,并继承了Reducer类。它也是使用泛型参数 。
DataSplitReducer 类中,定义了 reduce 方法,该方法也是重写父类 Reducer reduce 方法。它接受三个参数:keyvalues context,分别表示输入键、输入值的迭代器和上下文对象。
reduce 方法遍历输入值的迭代器,并对其进行求和操作,然后将计算结果分别与对应的键一起写入输出。

    public static void main(String[] args) throws Exception {
        Job job = Job.getInstance();
        job.setJarByClass(DataSplitExample.class);
        job.setMapperClass(DataSplitMapper.class);
        job.setCombinerClass(DataSplitReducer.class);
        job.setReducerClass(DataSplitReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);
        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }
}

最后,定义了 main 方法,该方法是程序的入口点。在 main 方法中,首先创建一个 Job 对象,然后设置该作业的各种属性,包括指定要运行的类、MapperCombinerReducer类,以及设置键和值的类型。
接下来,通过 FileInputFormat.addInputPath FileOutputFormat.setOutputPath 方法,指定输入和输出路径。
最后,通过调用 job.waitForCompletion 方法提交作业并等待作业完成。作业完成后,根据返回值判断是否成功执行,并使用 System.exit 退出程序。
上面展示了一个简单的Hadoop MapReduce程序,用于对输入文本数据进行分割和计数。

二.分发数据:将这些数据块分发给集群中的不同服务器。每个服务器都有一部分数据块。

在Hadoop集群中,数据的分发是通过Hadoop Distributed File System (HDFS) 来实现的。HDFS是Hadoop的文件系统,它能够将大量的数据划分成更小的块,并将这些块分发到集群中的各个节点上进行并行处理。
下面是一个示例代码,演示了如何将输入数据分发到Hadoop集群上进行处理:

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

public class DataDistributionExample {
    public static void main(String[] args) {
        try {
            // 创建Hadoop配置对象
            Configuration conf = new Configuration();
            // 指定Hadoop集群的Master节点地址
            conf.set("fs.defaultFS", "hdfs://master:9000");
            
            // 创建Hadoop文件系统对象
            FileSystem fs = FileSystem.get(conf);
            
            // 将本地数据文件上传到HDFS
            fs.copyFromLocalFile(new Path("/path/to/local/data/file.txt"), new Path("/hdfs/path/file.txt"));
            
            // 关闭文件系统连接
            fs.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

上面的示例代码通过以下步骤实现了数据分发:

1.创建了一个 Configuration 对象,用于存储Hadoop的配置信息。
2.使用 conf.set 方法设置Hadoop集群的Master节点地址(即NameNode的地址)。
3.创建了一个Hadoop文件系统对象 FileSystem,通过调用 FileSystem.get(conf) 方法来获取与Hadoop集群的连接。
4.使用 fs.copyFromLocalFile 方法将本地数据文件 /path/to/local/data/file.txt 上传到HDFS中的 /hdfs/path/file.txt 路径。
5.最后,调用 fs.close() 方法关闭与HDFS的连接。

这段代码的关键点在于使用 FileSystem 对象的 copyFromLocalFile 方法将本地文件复制到HDFS中。这将触发Hadoop分布式文件系统自动将文件划分为块,并将这些块分布到Hadoop集群中的不同节点上。
通过这种方式,数据在Hadoop集群中被分发到各个节点上进行并行处理。每个节点只处理其分配到的数据块,从而实现大规模数据处理的高效性和运行速度。
这只是数据分发的一个简单示例代码,实际的应用中可能需要更多的配置和处理步骤,例如处理大量的数据文件、处理数据的复杂逻辑等。此外,还需要确保Hadoop集群正常运行,并且在代码中正确配置Hadoop集群的相关参数。

三.并行处理:集群中的服务器同时处理它们手头的数据块。这就像一群人一起工作,每个人处理自己的任务。

在Hadoop集群中,并行处理是通过MapReduce编程模型来实现的。MapReduce将任务分为两个阶段:Map阶段和Reduce阶段。Map阶段用于将输入数据划分为小块,并在不同节点上并行处理。Reduce阶段用于对Map阶段的输出结果进行合并和汇总。
下面是一个示例代码,演示了如何在Hadoop集群上进行并行处理:

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapreduce.*;

public class ParallelProcessingExample {
    public static class MapClass extends Mapper<LongWritable, Text, Text, IntWritable> {
        public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            // 在这里编写Map阶段的处理逻辑
            // 将输入的文本行拆分为单词,并输出键值对(单词,1)
        }
    }

    public static class ReduceClass extends Reducer<Text, IntWritable, Text, IntWritable> {
        public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
            // 在这里编写Reduce阶段的处理逻辑
            // 对相同单词的计数进行汇总,并输出最终结果
        }
    }

    public static void main(String[] args) throws Exception {
        try {
            // 创建Hadoop配置对象
            Configuration conf = new Configuration();
            // 指定Hadoop集群的Master节点地址
            conf.set("fs.defaultFS", "hdfs://master:9000");

            // 创建Job对象
            Job job = Job.getInstance(conf, "ParallelProcessingExample");
            // 设置作业的类路径
            job.setJarByClass(ParallelProcessingExample.class);

            // 设置Map阶段的类和输出键值类型
            job.setMapperClass(MapClass.class);
            job.setMapOutputKeyClass(Text.class);
            job.setMapOutputValueClass(IntWritable.class);

            // 设置Reduce阶段的类和输出键值类型
            job.setReducerClass(ReduceClass.class);
            job.setOutputKeyClass(Text.class);
            job.setOutputValueClass(IntWritable.class);

            // 设置输入和输出路径
            FileInputFormat.addInputPath(job, new Path("/hdfs/input"));
            FileOutputFormat.setOutputPath(job, new Path("/hdfs/output"));

            // 提交作业并等待完成
            int exitCode = job.waitForCompletion(true) ? 0 : 1;
            System.exit(exitCode);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

1.创建了一个 Configuration 对象,用于存储Hadoop的配置信息,并设置Hadoop集群的Master节点地址(即NameNode的地址)。
2.创建了一个 Job 对象,用于表示一个作业。并设置作业的类路径。
3.设置Map阶段的类(MapClass)和输出键值类型(Text作为键,IntWritable作为值)。
4.设置Reduce阶段的类(ReduceClass)和输出键值类型(同样是Text和IntWritable)。
5.设置输入路径和输出路径,这里使用 /hdfs/input 作为输入路径,/hdfs/output 作为输出路径。
6.使用 job.waitForCompletion(true) 提交作业并等待完成。该方法会将作业提交给Hadoop集群,并开始执行MapReduce任务。

在上述代码中,需要自定义 MapClass 和 ReduceClass 分别继承自 Mapper 和 Reducer 类,重写它们的 map 和 reduce 方法来编写Map和Reduce阶段的处理逻辑。在map方法中,可以将输入数据拆分为单词,并输出键值对(单词,1)。在reduce方法中,将相同单词的计数进行汇总,并输出最终结果。
需要注意的是,这只是一个简单的示例代码,实际的应用中可能需要更多的MapReduce任务,以及处理更复杂的业务逻辑。此外,还需要确保Hadoop集群正常运行,并在代码中正确配置Hadoop集群的相关参数。

四.中间结果:每个服务器在处理数据时会生成一些中间结果,就像工人处理巧克力块后获得巧克力碎片。

在Hadoop集群中,中间结果通常指的是Map阶段的输出结果,也称为中间键值对(Intermediate Key-Value Pairs)。这些中间结果在Map阶段完成后,会被按照键进行分组(Shuffle阶段),然后传递给Reduce任务进行进一步处理。以下是一个详细解释,包括示例代码和代码分析。
中间结果的生命周期:

1.Map阶段:输入数据会被分为多个数据块,每个数据块会被一个或多个Mapper任务处理。每个Mapper任务会产生一系列中间键值对作为其输出。这些中间键值对通常表示处理过程中的临时结果,例如,对输入数据进行拆分、计数、筛选等操作。
2.Shuffle和Sort阶段:一旦所有的Mapper任务完成,Hadoop框架会对中间键值对进行分组(按照键进行分组),并将每个分组发送给对应的Reducer任务。这个过程称为Shuffle和Sort阶段。在Shuffle阶段,数据会在集群内的节点之间传输,并根据键进行排序,以便在Reduce阶段更高效地进行处理。
3.Reduce阶段:Reducer任务会接收到分组后的中间结果,然后对每个分组的数据进行处理,通常是对键值对进行合并、汇总或其他操作,以生成最终的输出结果。

下面是一个示例代码,演示了如何在Hadoop中使用MapReduce处理中间结果:

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

public class IntermediateResultExample {
    public static class MapClass extends Mapper<LongWritable, Text, Text, IntWritable> {
        private final static IntWritable one = new IntWritable(1);
        private Text word = new Text();

        public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            String line = value.toString();
            String[] words = line.split("\\s+"); // 按空格切分单词

            for (String w : words) {
                word.set(w);
                context.write(word, one); // 发射中间键值对(单词, 1)
            }
        }
    }

    public static class ReduceClass extends Reducer<Text, IntWritable, Text, IntWritable> {
        public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
            int sum = 0;
            for (IntWritable value : values) {
                sum += value.get();
            }
            context.write(key, new IntWritable(sum)); // 发射最终结果(单词, 总计数)
        }
    }

    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf, "IntermediateResultExample");
        job.setJarByClass(IntermediateResultExample.class);

        job.setMapperClass(MapClass.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        job.setReducerClass(ReduceClass.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        FileInputFormat.addInputPath(job, new Path("/input/data.txt"));
        FileOutputFormat.setOutputPath(job, new Path("/output"));

        job.waitForCompletion(true);
    }
}

上述代码中,Map阶段将输入文本数据按单词切分,并为每个单词生成一个中间键值对(单词, 1)。这些中间键值对会在Shuffle阶段被分组,然后传递给Reducer任务。Reducer任务接收到相同单词的所有计数,将它们相加,然后生成最终的输出键值对(单词, 总计数)。
中间结果的重要性在于它们允许分布式处理大规模数据集,并将数据有效地传递给Reducer任务,以进行进一步的汇总和分析。这样的设计使得Hadoop能够处理大规模数据集,而不需要将所有数据加载到内存中。中间结果的产生和处理是Hadoop的核心机制之一,使其在大数据处理中非常有用。

五.数据整合:集群会把这些中间结果收集起来,就像把所有人的巧克力碎片集中在一起。

在Hadoop集群中,数据整合通常指的是将多个数据源的数据合并到一起进行处理。这些数据源可以是不同的文件、目录或数据库。

1.数据源定义:首先,需要明确定义要整合的数据源。这可以是Hadoop分布式文件系统(HDFS)中的多个文件,也可以是外部数据库中的记录,甚至可以是其他集群节点上的数据。
2.数据读取:使用适当的输入格式读取每个数据源中的数据。在Hadoop中,通常使用输入格式(InputFormat)来指定如何读取数据。例如,对于文本文件,可以使用TextInputFormat,对于数据库,可以使用DBInputFormat。
3.数据整合:在Map阶段,对每个数据源的数据进行适当的处理,并输出中间键值对。中间键值对的键可以用来标识数据源来源,值可以是整个记录或经过处理的部分数据。
4.中间结果分组:在Shuffle阶段,根据键对中间键值对进行分组,将相同键的数据发送给相同的Reducer任务。这样可以确保来自同一数据源的数据被发送到同一个Reducer任务进行最终的整合处理。
5.数据整合处理:在Reduce阶段,接收到相同键的中间键值对,并根据需要进行进一步的整合操作。这可以包括数据合并、聚合、计算等操作。最终的结果将作为最终输出写入到目标位置。

下面是一个示例代码,演示了如何在Hadoop中进行数据整合:

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

public class DataIntegrationExample {
    public static class MapClass extends Mapper<LongWritable, Text, Text, Text> {
        private Text outKey = new Text();
        private Text outValue = new Text();

        public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            // 解析输入记录
            String line = value.toString();
            String[] fields = line.split(",");

            // 提取关键字段
            String id = fields[0];
            String name = fields[1];

            // 设置中间键值对
            outKey.set(id);
            outValue.set(name);

            // 发射中间键值对
            context.write(outKey, outValue);
        }
    }

    public static class ReduceClass extends Reducer<Text, Text, Text, Text> {
        private Text outValue = new 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(",");
            }

            // 设置最终键值对
            outValue.set(sb.toString());

            // 发射最终键值对
            context.write(key, outValue);
        }
    }

    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf, "DataIntegrationExample");
        job.setJarByClass(DataIntegrationExample.class);

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

        job.setReducerClass(ReduceClass.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);

        FileInputFormat.addInputPath(job, new Path("/input/source1.csv"));
        FileInputFormat.addInputPath(job, new Path("/input/source2.csv"));
        FileOutputFormat.setOutputPath(job, new Path("/output"));

        job.waitForCompletion(true);
    }
}

上述代码中,Map阶段将两个数据源(source1.csv和source2.csv)的记录按照指定的逻辑进行处理,并输出中间键值对(id, name)。然后,在Reduce阶段,Reducer任务接收到相同id的中间键值对,并将它们按照需要的方式进行整合。最终的结果将以(id, 整合数据)的形式写入到输出文件中。
通过数据整合,我们可以将多个数据源的数据合并到一起进行处理,从而有效地利用Hadoop集群的分布式处理能力。

六.最终结果:最后,集群会把收集的中间结果整合在一起,形成最终的处理结果。就像把所有巧克力碎片合成一块大巧克力一样。

在Hadoop集群中,最终结果是指经过MapReduce处理后的数据结果。这些结果可以是聚合、计算、排序等操作的输出。

1.数据预处理:首先,需要进行数据的预处理步骤,例如数据清洗、过滤、转换等。这可以在Map阶段中完成,将原始数据转换为中间键值对的形式。
2.数据计算/聚合:在Map阶段输出的中间键值对会根据键进行分组,在Shuffle阶段将相同键的数据发送到同一个Reducer任务。在Reduce阶段,可以对相同键对应的数据进行进一步的计算、聚合等操作,产生最终结果。
3.结果存储:最终结果将被写入Hadoop文件系统(HDFS)或其他存储系统中,以便后续的查询、分析或展示。通常,可以使用Hadoop提供的输出格式(OutputFormat)将结果以符合特定需求的格式进行存储。

下面是一个示例代码,演示了如何在Hadoop中生成最终结果:

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

public class FinalResultExample {
    public static class MapClass extends Mapper<LongWritable, Text, Text, IntWritable> {
        private Text outKey = new Text();
        private IntWritable outValue = new IntWritable();

        public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            // 解析输入记录
            String line = value.toString();
            String[] fields = line.split(",");

            // 提取关键字段
            String city = fields[0];
            int population = Integer.parseInt(fields[1]);

            // 设置中间键值对
            outKey.set(city);
            outValue.set(population);

            // 发射中间键值对
            context.write(outKey, outValue);
        }
    }

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

        public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
            int sum = 0;

            // 计算相同键的数据之和
            for (IntWritable value : values) {
                sum += value.get();
            }

            // 设置最终键值对
            outValue.set(sum);

            // 发射最终键值对
            context.write(key, outValue);
        }
    }

    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf, "FinalResultExample");
        job.setJarByClass(FinalResultExample.class);

        job.setMapperClass(MapClass.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        job.setReducerClass(ReduceClass.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        FileInputFormat.addInputPath(job, new Path("/input/data.csv"));
        FileOutputFormat.setOutputPath(job, new Path("/output/result"));

        job.waitForCompletion(true);
    }
}

上述代码中,Map阶段解析了输入记录,并将城市(city)作为键,人口(population)作为值,发射中间键值对。在Reduce阶段,Reducer任务接收到相同城市的中间键值对,计算这些城市的人口之和,然后将最终结果写入输出文件中。
 

七.存储结果:最终的处理结果可以保存在集群中,也可以传输给用户,就像把巧克力交给客户一样。

在Hadoop集群中,结果存储是指将经过MapReduce处理后的最终结果写入到Hadoop文件系统(HDFS)或其他存储系统中。

1.配置输出路径:首先,需要指定结果输出的路径,即将结果写入的目标位置。通常,可以使用Hadoop的FileOutputFormat.setOutputPath()方法来设置输出路径。
2.设置输出格式:根据不同的需求,可以选择不同的输出格式(OutputFormat)来存储结果。Hadoop提供了多种输出格式,如文本格式、SequenceFile格式、Parquet格式等。可以使用job.setOutputFormatClass()方法来设置输出格式。
3.写入结果:在Reduce阶段,通过使用context.write()方法将最终结果写入输出流中。输出流会将结果按照指定的格式写入到指定的输出路径中。

下面是一个示例代码,演示了如何在Hadoop中将最终结果存储到HDFS中:
 

import org.apache.hadoop.conf.Configuration;
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.Reducer;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;

import java.io.IOException;

public class ResultStorageExample {
    public static class MapClass extends Mapper<LongWritable, Text, Text, IntWritable> {
        // Mapper代码省略,与之前的示例相同
    }

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

        public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
            // Reduce代码省略,与之前的示例相同
        }
    }

    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf, "ResultStorageExample");
        job.setJarByClass(ResultStorageExample.class);

        job.setMapperClass(MapClass.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        job.setReducerClass(ReduceClass.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        FileInputFormat.addInputPath(job, new Path("/input/data.csv"));
        FileOutputFormat.setOutputPath(job, new Path("/output/result"));

        job.setOutputFormatClass(TextOutputFormat.class);  // 设置输出格式为文本格式

        job.waitForCompletion(true);
    }
}

上述代码中,我们通过FileOutputFormat.setOutputPath()方法设置了结果输出的路径为/output/result。然后,使用job.setOutputFormatClass()方法将输出格式设置为文本格式(TextOutputFormat.class)。最后,在Reduce阶段,使用context.write()方法将最终结果写入到输出流中。
通过以上代码,我们可以将Hadoop集群中处理后的最终结果存储到指定的路径(例如HDFS)中。这样的存储方式可以确保结果的持久性和可靠性,并方便后续的数据查询和分析。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值