@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運行流程分析如下:
- 在客戶端啓動一個作業,向
JobTracker
請求一個Job ID。 - 將運行作業所需要的資源文件複製到HDFS上,包括MapReduce程序打包的JAR文件、配置文件和客戶端計算所得的輸入劃分信息,這些文件都存放在
JobTracker
專門爲該作業創建的文件夾中。 JobTracker
接收到作業後,將其放在一個作業隊列裏,等待作業調度器對其進行調度- 當作業調度器根據自己的調度算法調度到該作業時,會根據輸入劃分信息爲每個劃分創建一個Map任務,並將Map任務分配給
TaskTracker
執行。對於Map和Reduce任務,TaskTracker
根據主機核的數量和內存的大小有固定數量的Map槽和Reduce槽。 TaskTracker
每隔一段時間會給JobTracker
發送一個心跳,告訴JobTracker
它依然在運行,同時心跳中還攜帶着很多的信息,比如當前Map任務完成的進度等信息。- 當
JobTracker
收到作業的最後一個任務完成信息時,便把該作業設置成“成功”。 - 當
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 主要由 ResourceManager
、NodeManager
、ApplicationMaster
和 Container
等組件組成。在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