Hadoop學習:深入解析MapReduce的大數據魔力(三)

Hadoop學習:深入解析MapReduce的大數據魔力(三)

  • 3.5 MapReduce 內核源碼解析
    • 3.5.1 MapTask 工作機制
    • 3.5.2 ReduceTask 工作機制
    • 3.5.3 ReduceTask 并行度決定機制
  • 3.6 數據清洗(ETL)
    • 1)需求
    • 2)需求分析
    • 3)實現代碼
  • 3.7 MapReduce 開發總結
    • 1)輸入數據接口:InputFormat
    • 2)邏輯處理接口:Mapper
    • 3)Partitioner 分區
    • 4)Comparable 排序
    • 5)Combiner 合并
    • 6)邏輯處理接口:Reducer
    • 7)輸出數據接口:OutputFormat

3.5 MapReduce 內核源碼解析

3.5.1 MapTask 工作機制

在這里插入圖片描述
(1)Read階段:MapTask通過InputFormat獲得的RecordReader,從輸入InputSplit中解析出一個個key/value。

(2)Map階段:該節點主要是將解析出的key/value交給用戶編寫map()函數處理,并產生一系列新的key/value。

(3)Collect 收集階段:在用戶編寫 map()函數中,當數據處理完成后,一般會調用OutputCollector.collect()輸出結果。在該函數內部,它會將生成的 key/value 分區(調用Partitioner),并寫入一個環形內存緩沖區中。

(4)Spill 階段:即“溢寫”,當環形緩沖區滿后,MapReduce會將數據寫到本地磁盤上,生成一個臨時文件。需要注意的是,將數據寫入本地磁盤之前,先要對數據進行一次本地排序,并在必要時對數據進行合并、壓縮等操作。

溢寫階段詳情:
步驟1:利用快速排序算法對緩存區內的數據進行排序,排序方式是,先按照分區編號Partition 進行排序,然后按照key進行排序。這樣,經過排序后,數據以分區為單位聚集在一起,且同一分區內所有數據按照key有序。

步驟2:按照分區編號由小到大依次將每個分區中的數據寫入任務工作目錄下的臨時文件output/spillN.out(N 表示當前溢寫次數)中。如果用戶設置了 Combiner,則寫入文件之前,對每個分區中的數據進行一次聚集操作。

步驟3:將分區數據的元信息寫到內存索引數據結構SpillRecord中,其中每個分區的元信息包括在臨時文件中的偏移量、壓縮前數據大小和壓縮后數據大小。如果當前內存索引大小超過1MB,則將內存索引寫到文件output/spillN.out.index中。

(5)Merge 階段:當所有數據處理完成后,MapTask 對所有臨時文件進行一次合并,以確保最終只會生成一個數據文件。 當所有數據處理完后,MapTask 會將所有臨時文件合并成一個大文件,并保存到文件output/file.out 中,同時生成相應的索引文件output/file.out.index。 在進行文件合并過程中,MapTask以分區為單位進行合并。對于某個分區,它將采用多輪遞歸合并的方式。每輪合并mapreduce.task.io.sort.factor(默認 10)個文件,并將產生的文件重新加入待合并列表中,對文件排序后,重復以上過程,直到最終得到一個大文件。
讓每個 MapTask 最終只生成一個數據文件,可避免同時打開大量文件和同時讀取大量小文件產生的隨機讀取帶來的開銷。

3.5.2 ReduceTask 工作機制

在這里插入圖片描述
(1)Copy 階段:ReduceTask 從各個 MapTask 上遠程拷貝一片數據,并針對某一片數據,如果其大小超過一定閾值,則寫到磁盤上,否則直接放到內存中。

(2)Sort 階段:在遠程拷貝數據的同時,ReduceTask啟動了兩個后臺線程對內存和磁盤上的文件進行合并,以防止內存使用過多或磁盤上文件過多。按照MapReduce語義,用戶編寫reduce()函數輸入數據是按key進行聚集的一組數據。為了將key相同的數據聚在一
起,Hadoop采用了基于排序的策略。由于各個MapTask已經實現對自己的處理結果進行了局部排序,因此,ReduceTask只需對所有數據進行一次歸并排序即可。

(3)Reduce 階段:reduce()函數將計算結果寫到HDFS上。

3.5.3 ReduceTask 并行度決定機制

回顧:MapTask并行度由切片個數決定,切片個數由輸入文件和切片規則決定。

思考:ReduceTask并行度由誰決定?

1)設置ReduceTask并行度(個數)
ReduceTask 的并行度同樣影響整個 Job 的執行并發度和執行效率,但與MapTask的并發數由切片數決定不同,ReduceTask數量的決定是可以直接手動設置:

// 默認值是1,手動設置為4
job.setNumReduceTasks(4);

2)實驗:測試ReduceTask多少合適
(1)實驗環境:1個Master節點,16個Slave節點:CPU:8GHZ,內存: 2G
(2)實驗結論:
在這里插入圖片描述
3)注意事項
(1)ReduceTask=0,表示沒有Reduce階段,輸出文件個數和Map個數一致。
(2)ReduceTask默認值就是1,所以輸出文件個數為一個。
(3)如果數據分布不均勻,就有可能在Reduce階段產生數據傾斜
(4)ReduceTask數量并不是任意設置,還要考慮業務邏輯需求,有些情況下,需要計算全局匯總結果,就只能有1個ReduceTask。
(5)具體多少個ReduceTask,需要根據集群性能而定。
(6)如果分區數不是1,但是ReduceTask為1,是否執行分區過程。答案是:不執行分區過程。因為在MapTask的源碼中,執行分區的前提是先判斷ReduceNum個數是否大于1。不大于1肯定不執行。

3.6 數據清洗(ETL)

“ETL,是英文 Extract-Transform-Load 的縮寫,用來描述將數據從來源端經過抽取
(Extract)、轉換(Transform)、加載(Load)至目的端的過程。ETL一詞較常用在數據倉庫,但其對象并不限于數據倉庫

在運行核心業務MapReduce 程序之前,往往要先對數據進行清洗,清理掉不符合用戶要求的數據。==清理的過程往往只需要運行Mapper程序,不需要運行Reduce程序。 ==

1)需求

去除日志中字段個數小于等于11的日志。
(1)輸入數據
在這里插入圖片描述
(2)期望輸出數據
每行字段長度都大于11。

2)需求分析

需要在Map階段對輸入的數據根據規則進行過濾清洗。

3)實現代碼

(1)編寫WebLogMapper類

package com.atguigu.mapreduce.weblog; 
import java.io.IOException; 
import org.apache.hadoop.io.LongWritable; 
import org.apache.hadoop.io.NullWritable; 
import org.apache.hadoop.io.Text; 
import org.apache.hadoop.mapreduce.Mapper; public class WebLogMapper extends Mapper<LongWritable, Text, Text, 
NullWritable>{ @Override protected void map(LongWritable key, Text value, Context context) 
throws IOException, InterruptedException { // 1 獲取1行數據 String line = value.toString(); // 2 解析日志 boolean result = parseLog(line,context); // 3 日志不合法退出 if (!result) { return; } // 4 日志合法就直接寫出 context.write(value, NullWritable.get()); } // 2 封裝解析日志的方法 private boolean parseLog(String line, Context context) { // 1 截取 String[] fields = line.split(" "); // 2 日志長度大于11的為合法 if (fields.length > 11) { return true; }else { return false; } } 
} 

(2)編寫WebLogDriver類

package com.atguigu.mapreduce.weblog; 
import org.apache.hadoop.conf.Configuration; 
import org.apache.hadoop.fs.Path; 
import org.apache.hadoop.io.NullWritable; 
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 WebLogDriver { 
public static void main(String[] args) throws Exception { 
// 輸入輸出路徑需要根據自己電腦上實際的輸入輸出路徑設置 
args = new String[] { "D:/input/inputlog", "D:/output1" }; 
// 1 獲取job信息 
Configuration conf = new Configuration(); 
Job job = Job.getInstance(conf); 
// 2 加載jar包 
job.setJarByClass(LogDriver.class); 
// 3 關聯map 
job.setMapperClass(WebLogMapper.class); 
// 4 設置最終輸出類型 
job.setOutputKeyClass(Text.class); 
job.setOutputValueClass(NullWritable.class); 
// 設置reducetask個數為0 
job.setNumReduceTasks(0); 
// 5 設置輸入和輸出路徑 
FileInputFormat.setInputPaths(job, new Path(args[0])); 
FileOutputFormat.setOutputPath(job, new Path(args[1])); 
// 6 提交 
boolean b = job.waitForCompletion(true); 
System.exit(b ? 0 : 1); 
} 
} 

3.7 MapReduce 開發總結

1)輸入數據接口:InputFormat

(1)默認使用的實現類是:TextInputFormat
(2)TextInputFormat 的功能邏輯是:一次讀一行文本,然后將該行的起始偏移量作為key,行內容作為value返回。
(3)CombineTextInputFormat 可以把多個小文件合并成一個切片處理,提高處理效率。

2)邏輯處理接口:Mapper

用戶根據業務需求實現其中三個方法:map() setup() cleanup ()

3)Partitioner 分區

(1)有默認實現 HashPartitioner,邏輯是根據key的哈希值和numReduces來返回一個分區號;key.hashCode()&Integer.MAXVALUE % numReduces
(2)如果業務上有特別的需求,可以自定義分區。

4)Comparable 排序

(1)當我們用自定義的對象作為key來輸出時,就必須要實現WritableComparable 接口,重寫其中的compareTo()方法。

(2)部分排序:對最終輸出的每一個文件進行內部排序。

(3)全排序:對所有數據進行排序,通常只有一個Reduce。

(4)二次排序:排序的條件有兩個。

5)Combiner 合并

Combiner 合并可以提高程序執行效率,減少IO傳輸。但是使用時必須不能影響原有的
業務處理結果。

6)邏輯處理接口:Reducer

用戶根據業務需求實現其中三個方法:reduce() setup() cleanup ()

7)輸出數據接口:OutputFormat

(1)默認實現類是TextOutputFormat,功能邏輯是:將每一個KV對,向目標文本文件
輸出一行。
(2)用戶還可以自定義OutputFormat。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/42674.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/42674.shtml
英文地址,請注明出處:http://en.pswp.cn/news/42674.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

uni-app封裝api請求

前端封裝api請求 前端封裝 API 請求可以提高代碼的可維護性和重用性&#xff0c;同時使得 API 調用更加簡潔和易用。 下面是一種常見的前端封裝 API 請求的方式&#xff1a; 創建一個 API 封裝模塊或類&#xff1a;可以使用 JavaScript 或 TypeScript 創建一個獨立的模塊或類來…

Java數據庫連接池原理及spring boot使用數據庫連接池(HikariCP、Druid)

和線程池類似&#xff0c;數據庫連接池的作用是建立一些和數據庫的連接供需要連接數據庫的業務使用&#xff0c;避免了每次和數據庫建立、銷毀連接的性能消耗&#xff0c;通過設置連接池參數可以防止建立連接過多導致服務宕機等&#xff0c;以下介紹Java中主要使用的幾種數據庫…

【學習FreeRTOS】第11章——FreeRTOS中任務相關的其他API函數

1.函數總覽 序號函數描述1uxTaskPriorityGet()獲取任務優先級2vTaskPrioritySet()設置任務優先級3uxTaskGetNumberOfTasks()獲取系統中任務的數量4uxTaskGetSystemState()獲取所有任務的狀態信息5vTaskGetInfo()獲取單個任務的狀態信息6xTaskGetCurrentTaskHandle()獲取當前任…

Excel自動化辦公——Openpyxl的基本使用

Excel自動化辦公——Openpyxl的基本使用 個人感覺&#xff0c;相比Pandas&#xff0c;openpyxl對Excel的操作更為細致&#xff0c;Pandas則更適用于統計計算&#xff1b; 01 基本環境02 Excel數據讀取操作03 案例04 向Excel寫入數據05 表數據定向修改06 單元格樣式制定07 單元…

原型對象的簡單了解

在前面學習java有一個概念叫做繼承&#xff0c;方便我們對父類方法、變量等的調用。對前端的學習我們需要讓對象可以訪問和繼承其他對象的屬性和方法&#xff0c;就需要了解原型對象&#xff0c;以及原型鏈。 一、原型 構造函數通過原型分配的函數是所有對象所共享的。每一個構…

【Lua語法】算術、條件、邏輯、位、三目運算符

1.算術運算符 加減乘除取余&#xff1a; - * / % Lua中獨有的&#xff1a;冪運算 ^ 注意&#xff1a; 1.Lua中沒有自增自減(、–)&#xff0c;也沒有復合運算符(、-) 2.Lua中字符串可以進行算術運算符操作&#xff0c;會自動轉成number 如&#xff1a;“10.3” 1 結果為11.3…

回歸預測 | MATLAB實現SOM-BP自組織映射結合BP神經網絡多輸入單輸出回歸預測(多指標,多圖)

回歸預測 | MATLAB實現SOM-BP自組織映射結合BP神經網絡多輸入單輸出回歸預測&#xff08;多指標&#xff0c;多圖&#xff09; 目錄 回歸預測 | MATLAB實現SOM-BP自組織映射結合BP神經網絡多輸入單輸出回歸預測&#xff08;多指標&#xff0c;多圖&#xff09;效果一覽基本介紹…

【css動畫】向下的動態箭頭

前言 使用css實現一組向下的動態箭頭效果&#xff0c;如下圖 思路 1.使用svg畫箭頭 2.設置keyframes&#xff0c;主要是每個箭頭加不同的延時。 代碼 <div class"down-arrow"><svg id"more-arrows"><polygonclass"arrow-top&quo…

Spark第三課

1.分區規則 1.分區規則 shuffle 1.打亂順序 2.重新組合 1.分區的規則 默認與MapReduce的規則一致,都是按照哈希值取余進行分配. 一個分區可以多個組,一個組的數據必須一個分區 2. 分組的分區導致數據傾斜怎么解決? 擴容 讓分區變多修改分區規則 3.HashMap擴容為什么必須…

[JavaWeb]【七】web后端開發-MYSQL

前言&#xff1a;MySQL是一種流行的關系型數據庫管理系統,它的作用是存儲和管理數據。在Web開發中,MySQL是必備的數據庫技能之一,因為它可以幫助Web開發人員處理大量的數據,并且提供了強大的數據查詢和管理功能。 一 數據庫介紹 1.1 什么是數據庫 1.2 數據庫產品 二 MySQL概述…

Servlet+JDBC實戰開發書店項目講解第六篇:訂單實現

ServletJDBC實戰開發書店項目講解第六篇&#xff1a;訂單實現 1. 數據庫設計 在訂單實現之前&#xff0c;我們需要對數據庫進行相應的設計。在這個書店項目中&#xff0c;我們可以創建以下兩個表來實現訂單功能&#xff1a; 1.1 訂單表(Order) 訂單ID(order_id)&#xff1a…

vue3 實現簡單瀑布流

一、整理思路 實際場景中&#xff0c;瀑布流一般由 父組件 提供 數據列表&#xff0c;子組件渲染每個圖片都是根據容器進行 絕對定位 &#xff0c;從而定好自己的位置取出 屏幕的寬度&#xff0c;設定 圖片的寬度 固定 為一個值&#xff0c;計算可以鋪 多少列按列數 先鋪上第一…

使用Julia進行核遞歸最小二乘算法(KRLS)的解析與實現

F 標題&#xff1a; 使用Julia進行核遞歸最小二乘算法&#xff08;KRLS&#xff09;的深度解析與實現 第一部分&#xff1a; 核遞歸最小二乘算法 (KRLS) 是一個在線核回歸算法&#xff0c;這種算法的主要特點是能夠一次處理一個樣本&#xff0c;并構建一個訓練點字典&#xf…

5G科技防汛,助力守護一方平安

“立秋雖已至&#xff0c;炎夏尚還在”&#xff0c;受臺風席卷以及季節性影響全國多地正面臨強降水的嚴峻挑戰。“落雨又順秋&#xff0c;綿綿雨不休”&#xff0c;正值“七下八上” 防汛關鍵時期&#xff0c;貴州省水文水資源局已全面進入備戰狀態。 為確保及時響應做好防汛搶…

Vue3 setup新特性簡單應用

去官網學習→組合式 API&#xff1a;setup() | Vue.js 運行示例&#xff1a; 代碼&#xff1a;App.vue <template><div class"home"><img alt"Vue logo" src"../assets/logo.png"><!-- msg 組件傳遞數據 --><Hell…

VBA_MF系列技術資料1-157

MF系列VBA技術資料 為了讓廣大學員在VBA編程中有切實可行的思路及有效的提高自己的編程技巧&#xff0c;我參考大量的資料&#xff0c;并結合自己的經驗總結了這份MF系列VBA技術綜合資料&#xff0c;而且開放源碼&#xff08;MF04除外&#xff09;&#xff0c;其中MF01-04屬于定…

MySQL 面試題

一、數據庫基礎 1、MySQL 有哪些數據庫類型? (1) 整數類型&#xff1a; TINYINT 1 字節 SMALLINT 2 字節 MEDIUMINT 3 字節 INT 4 字節 BIGINT 8 字節 ① 任何整數類型都可以加上 UNSIGNED …

【學會動態規劃】最長湍流子數組(23)

目錄 動態規劃怎么學&#xff1f; 1. 題目解析 2. 算法原理 1. 狀態表示 2. 狀態轉移方程 3. 初始化 4. 填表順序 5. 返回值 3. 代碼編寫 寫在最后&#xff1a; 動態規劃怎么學&#xff1f; 學習一個算法沒有捷徑&#xff0c;更何況是學習動態規劃&#xff0c; 跟我…

vue+elementui 實現文本超出長度顯示省略號,鼠標移上懸浮展示全部內容

一、場景 表單內的輸入框一般為固定寬度&#xff0c;當輸入框內容長度超出輸入框寬度時&#xff0c;需要顯示省略號&#xff0c;并設置鼠標移到輸入框上時懸浮展示全部內容。 <el-tooltipplacement"top-start"effect"light":content"basicData[Or…

在 IDEA 中使用 Git開發 圖文教程

在 IDEA 中使用 Git開發 圖文教程 一、連接遠程倉庫二、IDEA利用Git進行開發操作三、分支操作3.1 新建分支3.2 切換分支3.3 刪除分支3.4 比較分支3.5 合并分支 四、常用快捷鍵 一、連接遠程倉庫 一、打開IDEA&#xff0c;進入目錄&#xff1a;File ->New ->Project from…