四、MapReduce和Yarn基本架構

@Author : By Runsen
@Date : 2020/6/20

作者介紹:Runsen目前大三下學期,專業化學工程與工藝,大學沉迷日語,Python, Java和一系列數據分析軟件。導致翹課嚴重,專業排名中下。.在大學60%的時間,都在CSDN。

在一月到四月都沒怎麼寫博客,因爲決定寫書,結果出書方說大學生就是一個菜鳥,看我確實還是一個菜鳥,就更新到博客算了。

我把第九章更新到博客上。

9、大數據Hadoop框架

9.3 MapReduce和Yarn

9.3.1 MapReduce基本架構

Hadoop要實現分佈式需要包括兩部分,一部分是分佈式文件系統hdfs一部分是分佈式計算框架MapReduce,缺一不可,由Google提出,主要用於搜索領域,解決海量數據的計算問題。也就是說,Hadoop平臺上可以通過MapReduce進行分佈式的計算編程。

那麼MapReduce怎樣解決海量數據的計算?

比如,我們如何求和: 1 + 5 +7 + 3 +4 +9 +3 + 5 +6,如下圖9-6所示,

MapReduce 模型主要分爲 2 個部分:Map 和 Reduce。MapReduce採用“分而治之”策略,將一個分佈式文件系統中的大規模數據集,分成許多獨立的分片。這些分片可以被多個Map任務並行處理。MapReduce將[1,5,7],[3,4,9]和[3,5,6]進行Map函數操作。在 Map 過程中,Map 函數會獲取輸入的數據,產生一個臨時中間值,它是一個 K/V 對,然後MapReduce Library 會按 Key 值給鍵值對(K/V)分組然後傳遞給 Reduce 函數。Reduce 接收到了這些 K/V 對,會將它們合併。

在MapReduce運行中,運行流程如下圖9-7所示。

在MapReduce,有如下組件:

  • JobTracker:初始化作業,分配作業,TaskTracker與其進行通信,協調監控整個作業
  • TaskTracker:定期與JobTracker通信,執行Map和Reduce任務
  • HDFS:保存作業的數據、配置、jar包、結果

MapReduce運行流程分析如下:

  1. 在客戶端啓動一個作業,向JobTracker請求一個Job ID。
  2. 將運行作業所需要的資源文件複製到HDFS上,包括MapReduce程序打包的JAR文件、配置文件和客戶端計算所得的輸入劃分信息,這些文件都存放在JobTracker專門爲該作業創建的文件夾中。
  3. JobTracker接收到作業後,將其放在一個作業隊列裏,等待作業調度器對其進行調度
  4. 當作業調度器根據自己的調度算法調度到該作業時,會根據輸入劃分信息爲每個劃分創建一個Map任務,並將Map任務分配給TaskTracker執行。對於Map和Reduce任務,TaskTracker根據主機核的數量和內存的大小有固定數量的Map槽和Reduce槽。
  5. TaskTracker每隔一段時間會給JobTracker發送一個心跳,告訴JobTracker它依然在運行,同時心跳中還攜帶着很多的信息,比如當前Map任務完成的進度等信息。
  6. JobTracker收到作業的最後一個任務完成信息時,便把該作業設置成“成功”。
  7. JobClient查詢狀態時,它將得知任務已完成,便顯示一條消息告訴給用戶。

9.3.2 Yarn基本架構

在 Hadoop1.x版本 ,Hadoop 由兩部分組成:HDFS + MapReduce。但是在Hadoop2.x 版本,增加了 Yarn。Yarn 只負責進行資源的調度,MapReduce 只負責進行分佈式計算,降低了資源和計算的耦合性,大大提高了 MapReduce 程序的擴展性。

Yarn 是“Yet Another Resource Negotiator”的縮寫,字面意思是“另一種資源調度器”,在hadoop稱作分佈式集羣資源調度框架,Yarn 架構如下9-8所示。

從圖上看,Yarn 包括兩個部分:一個是資源管理器(Resource Manager),一個是節點管理器(Node Manager)。這也是 Yarn 的兩種主要進程:ResourceManager 進程負責整個集羣的資源調度管理,通常部署在獨立的服務器上;NodeManager 進程負責具體服務器上的資源和任務管理,在集羣的每一臺計算服務器上都會啓動,基本上跟 HDFS 的 DataNode 進程一起出現。

Yarn 主要由 ResourceManagerNodeManagerApplicationMasterContainer等組件組成。在Yarn工作機制,如下圖9-9所示。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-N8b75LR5-1592647130888)(./images/9-9.png)]

Yarn運行流程分析如下:

  • 啓動 Mr 程序提交到客戶端所在的節點。

  • Yarnrunner 向 ResourceManager 申請創建一個 application。

  • ResourceManager 將資源的提交路徑以及 application_id 返回給 yarnrunner。

  • yarnrunner 將程序運行所需的資源(程序jar包,輸入文件切片,程序的配置信息)提交到 HDFS 上。

  • 資源提交完畢後,yarnrunner 向 ResourceManager 申請運行 mrAppMaster。

  • ResourceManager 將用戶的請求初始化成一個 task 任務。

  • 空閒的 nodemanager 領取到 task 任務。

  • NodeManager 創建容器 Container,併產生 MrAppMaster。

  • Container 從 HDFS 上拷貝資源到本地。

  • MRAppmaster 向 RM 申請創建 maptask 任務。

  • RM 將 maptaks 任務分配給另外兩個 NodeManager,另外兩個 NodeManager 分別領取任務並創建 Container。

  • MrAppMaster 向兩個接收到任務的 NodeManager 發送程序啓動腳本,這兩個 NodeManager 分別啓動 maptask 任務,對數據切片進行計算分區排序。

  • MrAppMaster 等待所有的 maptask 運行完畢後,向 RM 申請容器,運行 reduce task。

  • reduce task 從 maptask 中獲取相應分區的數據複製到本地,進行計算。

  • 程序運行完畢,MR 會向 RM 申請註銷自己。

9.3.3 詞頻統計

MapReduce界的helloworld程序是WordCount程序。所謂WordCount,就是單詞計數,用來統計一篇或者一堆文本文件中的各單詞的出現次數。

首先將HDFS中的文件讀取,然後在Mapper類中使用遍歷讀取被分隔的字符,在通過Context對象將數據發送給Reducer,在Redue類中對相同的Key,分組,對values進行求和。

創建Maven工程。在pom文件添加依賴

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-client</artifactId>
    <version>3.2.1</version>
</dependency>

編寫Mapper類

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
    Text k = new Text();
    IntWritable v = new IntWritable(1);
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        // 1.讀取1行
        String line = value.toString();
        // 2.按空格將這一行切分成多個單詞
        String[] words = line.split(" ");
        // 3.將數據按照<單詞, 出現的次數>的格式發送給reducer
        for (String word : words) {
            // 設置單詞
            k.set(word);
            // 通過Context對象將數據發送給Reducer
            context.write(k, v);
        }
    }
}

編寫Reducer類

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
    IntWritable v = new IntWritable();
    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
        // 1.對發送過來的每個單詞出現的次數累加求和
        int sum = 0;
        for (IntWritable count: values) {
            sum += count.get();
        }
        v.set(sum);
        // 2.發送數據的格式<單詞, 總次數>
        context.write(key, v);
    }
}

編寫Driver啓動類

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.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class WordCountDriver {
    public static void main(String[] args) throws Exception {
        try{
            if(args.length !=2 ){
                System.exit(100);
            }
            // 配置Hadoop參數
            Configuration conf = new Configuration();
            Job job = Job.getInstance(conf);
            // 設置jar的加載路徑(設置爲main方法所在的類名即可)
            job.setJarByClass(WordCountDriver.class);
            // 指定輸入路徑
            FileInputFormat.setInputPaths(job,new Path(args[0]));
            // 指定輸出路徑
            FileOutputFormat.setOutputPath(job,new Path(args[1]));
            // 設置map輸出的key和value的數據類型
            job.setMapperClass(WordCountMapper.class);
            job.setMapOutputKeyClass(Text.class);
            job.setMapOutputValueClass(IntWritable.class);
            // 設置Reducer輸出的key和value的數據類型
            job.setReducerClass(WordCountReducer.class);
            job.setOutputKeyClass(Text.class);
            job.setOutputValueClass(IntWritable.class);
            // 運行job
            job.waitForCompletion(true);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

通過maven打成可移植的jar包,我們通過xshell中的xftp進行文件上傳centos7虛擬機中,創建input.txt測試詞頻統計是否成功。

[root@node01]# vim input.txt
##########
I love hadoop
I love Java
Hadoop is written in Java
[root@node01 ~]# ll
-rw-r--r--. 1 root   root     52 2月  25 16:44 input.txt
-rw-r--r--. 1 root   root   4620 2月  25 16:41 wordcount-1.0-SNAPSHOT.jar
[root@node01 ~]# hdfs dfs -put input.txt /
[root@node01 ~]# hdfs dfs -ls /
-rw-r--r--   3 root supergroup         52 2020-02-25 16:45 /input.txt
[root@node01 ~]# hadoop jar wordcount-1.0-SNAPSHOT.jar WordCountDriver hdfs://node01:9000/input.txt hdfs://node01:9000/output
2020-02-25 16:48:05,924 INFO mapreduce.Job:  map 0% reduce 0%
2020-02-25 16:48:18,611 INFO mapreduce.Job:  map 100% reduce 0%
2020-02-25 16:48:24,656 INFO mapreduce.Job:  map 100% reduce 100%
[root@node01 ~]# hdfs dfs -ls /output
-rw-r--r--   3 root supergroup          0 2020-02-25 16:49 /output/_SUCCESS
-rw-r--r--   3 root supergroup         56 2020-02-25 16:49 /output/part-r-00000
[root@node01 ~]# hdfs dfs -cat /output/part-r-00000
Hadoop	1
I	2
Java	2
hadoop	1
in	1
is	1
love	2
written	1

參考:https://hadoop.apache.org/docs/r3.2.1/hadoop-mapreduce-client/hadoop-mapreduce-client-core/MapReduceTutorial.html#Example:_WordCount_v1.0

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章