Die zweite Kernkomponente von Hadoop: MapReduce-Framework Abschnitt 1

1. Grundkonzepte

Hadoop löst zwei Kernprobleme von Big Data: das Speicherproblem großer Datenmengen und das Berechnungsproblem großer Datenmengen.

Unter diesen ist MapReduce speziell für die Lösung massiver Datenberechnungsprobleme konzipiert. Gleichzeitig besteht der Unterschied zwischen MapReduce und HDFS darin, dass es sich bei HDFS zwar um verteilte Komponenten handelt, es sich jedoch um eine vollständige Software handelt, die wir nur verwenden müssen, um logische Änderungen vorzunehmen . Wenn MapReduce Datenberechnungen durchführt, weiß das MR-Programm nicht, welche Art von Daten berechnet werden und welche Art von Logik verwendet wird. Daher ist MR nur ein [Framework] für verteiltes Rechnen. Das sogenannte Framework besteht darin, dass das MR-Programm die Daten kombiniert Ideen und Logik des verteilten Rechnens. Alles ist gekapselt, wir müssen nur den Berechnungscode (dh unseren eigenen Logikcode für die Datenverarbeitung) gemäß dem Denken des Frameworks schreiben. Nach Abschluss des Schreibens muss unser Programm ein verteiltes Programm sein .

Der Vorteil der Verwendung eines Distributed-Computing-Frameworks besteht darin, dass sich unsere Entwickler nur auf die Entwicklung der Geschäftslogik konzentrieren müssen und nicht auf die Logik der Programmlogik für verteiltes Computing.

2. Die Kernidee des verteilten Rechnens von MapReduce

Die vom MR-Framework implementierte Logik des verteilten Rechnens besteht darin, das MR-Programm in zwei Teile zu unterteilen: die Map-Phase und die Reduce-Phase.

Beim Ausführen eines Berechnungsprogramms wird zunächst die Kartenphase ausgeführt, und in der Kartenphase können mehrere Berechnungsprogramme (MapTask) gleichzeitig ausgeführt werden, um die Logik der Kartenphase zu berechnen. Die Kartenphase ist hauptsächlich für die Aufteilung von Daten und mehrere MapTasks verantwortlich Die Kartenphasen laufen parallel, ohne sich gegenseitig zu stören .

In der zweiten Stufe, der Reduce-Stufe, kann die Reduce-Stufe auch mehrere Rechenprogramme (ReduceTask) gleichzeitig ausführen. Die Aufgaben der Reduce-Stufe sind hauptsächlich für die Kombination von Daten verantwortlich. Gleichzeitig können mehrere ReduceTasks gleichzeitig ausgeführt werden gleichzeitig, ohne sich gegenseitig zu stören.

Jedes MR-Programm kann nur eine Map-Stufe und eine Reduce-Stufe haben.

3. Drei Kernprozesse während des Betriebs des MapReduce-Programms

MRAppMaster (eins): Verantwortlich für die Überwachung des gesamten verteilten Programms

MapTask (mehrere): Der Kernprozess der Map-Phase. Jede MapTask verarbeitet einen Teil der Daten aus der Datenquelle.

ReduceTask (mehrere): Der Kernprozess der Reduce-Phase. Jede ReduceTask ist für die Verarbeitung eines Teils der von der Map-Phase ausgegebenen Daten verantwortlich.

4. So schreiben Sie ein MapReduce-Berechnungsprogramm: (Programmierschritte)

1. Schreiben Sie die Berechnungslogik von MapTask

1. Schreiben Sie eine Java-Klasse , die die Mapper-Klasse erbt . Nach dem Erben der Mapper-Klasse müssen Sie vier Generika angeben. Die vier Generika repräsentieren die Eingabedaten- und Ausgabedatentypen der MapTask-Stufe.
Das MR-Programm erfordert, dass sowohl die Eingabedaten als auch der Ausgabedatentyp Daten vom Typ Schlüssel-Wert-Paar sein müssen.

2. Schreiben Sie die Kartenmethode in der geerbten Mapper-Klasse neu. Wenn die Kartenmethode Daten verarbeitet, ruft sie die Kartenmethode einmal für jede Datenzeile in der Datei auf . Die Berechnungslogik der Kartenmethode ist die Kernberechnungslogik von MapTask.

3. Gleichzeitig ist die Datenberechnung in der Kartenmethode abgeschlossen und die Daten müssen im angegebenen Schlüsselwertformattyp ausgegeben werden.

2. Schreiben Sie die Berechnungslogik von ReduceTask

1. Schreiben Sie eine Java-Klasse , die die Reducer-Klasse erbt . Nach dem Erben der Reducer-Klasse müssen Sie vier Generics angeben. Die vier Generics repräsentieren jeweils die Eingabe- und Ausgabe-KV-Datentypen der Reduce-Stufe.
Der KV-Typ des Reduziereingangs ist der KV-Typ des Ausgangs der Map-Stufe.
Der Ausgabetyp „Reduzieren“ wird angepasst.

2. Schreiben Sie die in der Reducer-Klasse bereitgestellte Reduzierungsmethode neu. Wenn die Reduzierungsmethode Daten verarbeitet, ruft ein Satz derselben Schlüssel die Reduzierungsmethode einmal auf . Die Berechnungslogik der Reduzierungsmethode ist die Kernberechnungslogik von ReduceTask.

3. Rufen Sie die Reduzierungsmethode auf, die Verarbeitung der Reduzierungslogik ist abgeschlossen und die Daten müssen im angegebenen Schlüsselwertformattyp ausgegeben werden.

3. Treiberprogramm schreiben

Der Treibertreiber wird zum Zusammenstellen des MR-Programms, zum Zusammenstellen des vom MR-Programm verarbeiteten Dateipfads, der Berechnungslogik der Kartenphase des MR-Programms, der Berechnungslogik der Reduzierphase des MR-Programms und des Ausgabepfads verwendet die Ergebnisse nach Abschluss des MR-Programms.

Der Treibertreiber ist im Wesentlichen eine Hauptfunktion

Die unterste Ebene von MapReduce wurde in Java entwickelt. Wenn wir also MR-Programme schreiben möchten, können wir sie mit Java-Code schreiben.

5. Implementierung des MapReduce-Falls – der klassische Fall des verteilten Big-Data-Computings WordCount (Wortzählung)

1. Fallanforderungen

Jetzt gibt es eine Datei. Die Datei ist sehr groß. Jede in der Datei gespeicherte Datenzeile besteht aus mehreren durch Leerzeichen getrennten Wörtern. Jetzt ist es notwendig, die verteilte Big-Data-Computing-Technologie zu verwenden, um die Gesamtzahl der Vorkommen jedes Wortes zu zählen in der Datei.

2. Fallanalyse (basierend auf MapReduce)

3. Code-Entwicklung

1. Erstellen Sie ein von Maven verwaltetes Java-Projekt

2. Stellen Sie die Programmierabhängigkeiten von MR vor

  • Hadoop-Client
  • hadoop-hdfs
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.kang</groupId>
  <artifactId>mr-study</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>mr-study</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <hadoop.version>3.1.4</hadoop.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-client</artifactId>
      <version>${hadoop.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-hdfs</artifactId>
      <version>${hadoop.version}</version>
    </dependency>
  </dependencies>
</project>

3. Schreiben Sie die Berechnungslogik der Mapper-Stufe

package com.kang.wc;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

import java.io.IOException;

/**
 * 单词计数的MapTask的计算逻辑
 * 1、继承Mapper类。同时需要指定四个泛型 两两一组 分别 代表输入的key value 和输出的key value的数据类型
 *      默认情况下,map阶段读取文件数据是以每一行的偏移量为key 整数类型 每一行的数据为value读取的 字符串类型
 *      map阶段输出以单词为key 字符串 以1为value输出 整数
 *      数据类型不能使用Java中的数据类型,数据类型必须是Hadoop的一种序列化类型
 *      Int —— hadoop.io.IntWritable
 *      Long —— hadoop.io.LongWritable
 *      String —— hadoop.io.Text
 * 2、重写map方法
 */
public class WCMapper extends Mapper<LongWritable, Text, Text, LongWritable> {
    
    
    /**
     * map方法就是MapTask的核心计算逻辑方法
     * map方法是切片中的一行数据调用一次
     * @param key   这一行数据的偏移量
     * @param value 这一行数据
     * @param context 上下文对象 用于输出map阶段处理完成的key value数据
     * @throws IOException
     * @throws InterruptedException
     */
    @Override
    protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, LongWritable>.Context context) throws IOException, InterruptedException {
    
    
        //拿到一行数据,并且将一行数据转成字符串类型
        String line = value.toString();
        //字符串以空格切割得到一个数组,数组中存放的就是一行的多个单词
        String[] words = line.split(" ");
        //遍历数组 得到每一个单词 以单词为key 以1为value输出数据即可
        for (String word : words) {
    
    
            context.write(new Text(word),new LongWritable(1L));
        }
    }
}

4. Schreiben Sie die Berechnungslogik der Reduzierstufe

package com.kang.wc;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

import java.io.IOException;

/**
 * Reduce的编程逻辑:
 * 1、继承Reducer类,指定输入和输出的kv类型
 *      输入KV就是Map阶段的输出KV Text LongWritable
 *      输出kv  Text LongWritable
 * 2、重写reduce方法
 */
public class WCReducer extends Reducer<Text, LongWritable,Text,LongWritable> {
    
    
    /**
     * Reduce方法是Reduce阶段的核心计算逻辑
     * reduce方法是一组相同的key执行一次
     * @param key      一组相同的key  某一个单词
     * @param values   是一个集合,集合存放的就是这一个单词的所有的value值
     * @param context  上下文对象 用于reduce阶段输出数据
     * @throws IOException
     * @throws InterruptedException
     */
    @Override
    protected void reduce(Text key, Iterable<LongWritable> values, Reducer<Text, LongWritable, Text, LongWritable>.Context context) throws IOException, InterruptedException {
    
    
        //只需要将某个单词聚合起来的value数据累加起来 得到总次数
        long sum = 0L;
        for (LongWritable value : values) {
    
    
            sum += value.get();
        }
        //只需要以单词为key 以sum为value输出即可
        context.write(key,new LongWritable(sum));
    }
}

5. Treiberprogramm schreiben

package com.kang.wc;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
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;

import java.io.IOException;

/**
 * Driver驱动程序说白了就是封装MR程序的
 * Driver驱动程序其实就是一个main函数
 */
public class WCDriver {
    
    
    public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
    
    
        //1、准备一个配置文件对象Configuration
        Configuration conf = new Configuration();
        //指定HDFS的地址
        conf.set("fs.defaultFS","hdfs://192.168.31.104:9000");
        //2、创建封装MR程序使用一个Job对象
        Job job = Job.getInstance(conf);
        //3、封装处理的文件路径hdfs://single:9000/wc.txt
        FileInputFormat.setInputPaths(job,new Path("/wc.txt"));
        //4、封装MR程序的Mapper阶段,还要封装Mapper阶段输出的key-value类型
        job.setMapperClass(WCMapper.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(LongWritable.class);
        //5、封装MR程序的Reducer阶段,还要封装reduce的输出kv类型
        job.setReducerClass(WCReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setMapOutputValueClass(LongWritable.class);
        job.setNumReduceTasks(1);//指定reduce阶段只有一个ReduceTask
        //6、封装MR程序的输出路径 —— 输出路径一定不能存在  如果存在会报错
        FileOutputFormat.setOutputPath(job,new Path("/wcoutput"));
        //7、提交运行MR程序
        boolean flag = job.waitForCompletion(true);
        System.exit(flag?0:1);
    }
}

Bild-20230721191141473

Bild-20230721191153152

Bild-20230721191135459

おすすめ

転載: blog.csdn.net/weixin_57367513/article/details/132717847