MapReduce:分佈式離線計算框架
分佈式:程序多節點(resourceManager 和 nodeManager)多角色(map 和 reduce)組成
離線:計算過程中產生中間數據,會保存在硬盤上
計算框架:提供了一個編程模型,可以很輕鬆的實現分佈式數據分析程序
使用 MapReduce 需要先啓動 hdfs 和 yarn:
1. 啓動 3 個節點的 zookeeper
2. 啓動 hdfs
3. 啓動 yarn
ResourceManager
NodeManager
http://master:8088
wordcount(詞頻統計):
計算單詞在文章內出現的次數
計算單詞在文章內出現的次數
1. 在 /root 中創建一個 word.txt 文件
2. 輸入一些單詞
3. 上傳 word.txt 到 hdfs
4. 進入 /usr/local/hadoop/share/hadoop/mapreduce 文件夾
5. 執行詞頻統計程序:
hadoop jar hadoop-mapreduce-examples-2.6.0-cdh5.15.1.jar wordcount /word.txt /word-count-1
hadoop jar:執行 maperduce 程序
/word.txt:待分析的數據保存位置
/word-count-1:分析結果保存位置
如果想重複執行,先刪除 /word-count-1 文件夾
6. 查看分析結果:
hadoop fs -cat /word-count-1/part-r-00000
mapreduce 執行流程:
採用分治法的思想進行大數據分析
分治法:把大任務拆分爲許多小任務,交給不同的節點去執行,彙總各自計算結果
分爲兩個階段:map 和 reduce
map:各個節點執行小任務
reduce:彙總各個節點的計算結果
mapreduce 程序中的輸入和輸出都是 key-value
map:
輸入 key:行首字母的索引
輸入 value:每一行數據
輸出 key:每個單詞
輸出 value:1
聚合 key 相同的 value 到一起,形成新的 key-value,輸入給 reduce
hello 1
hello 1 ---> hello [1, 1, 1]
hello 1
reduce:
輸入 key:每個單詞
輸入 value:value 集合
輸出 key:每個單詞
輸出 value:詞頻
map 的輸出就是 reduce 的輸入,reduce 用來彙總 map 輸出的內容
reduce 的輸出就是數據分析的結果
wordcount 的代碼:
每個 mapreduce 程序都分爲 3 部分:
map:小任務的數據分析邏輯
reduce:彙總數據的邏輯
job:拼裝 map 和 reduce 組成可執行程序
每個 mapper 的計算結果保存在硬盤上,reducer 從硬盤上獲取數據進行彙總
在這個過程中就有序列化和反序列化操作
序列化:對象轉換爲二進制
反序列化:二進制轉換爲對象
Java 自帶的序列化機制(Serializeable)會在序列化的時候生成一些冗餘信息
比如:版本號,class 結構,...
嚴重拖累了程序的執行效率,爲了解決這個問題 MapReduce 框架自己實現了一套序列化機制
int IntWritable
long LongWritable
String Text
Null NullWritable
mapper:
1. 創建靜態內部類 WordCountMapper 繼承自 Mapper
2. 填寫輸入輸出 kv 的四個類型
3. 聲明輸出的 kv 對象
4. 使用 ctrl + o 重寫父類 map 方法,完成數據計算工作
reducer:
1. 創建靜態內部類 WordCountReducer 繼承自 Reducer
2. 填寫輸入輸出 kv 的四個類型
3. 聲明輸出的 kv 對象
4. 使用 ctrl + o 重寫父類 reduce 方法,完成數據計算工作
job:
1. psvm 生成 main 方法
2. 配置 hdfs 訪問地址
3. 獲取 job 對象,並捕獲異常
4. 設置 job 名字和主類(main 方法所在類)
5. 設置 mapper 和 reducer 類
6. 設置 mapper 的 kv 輸出類型
7. 設置 reducer 的 kv 輸出類型
8. 設置待計算的數據位置
9. 設置計算結果的保存位置
10. 提交 job,等待執行結果,需要捕獲異常
如果 mapper 和 reducer 的輸出 kv 類型一致,可以省略第 6 步
MapReduce 程序設計:
map 的輸入 kv 是框架給的固定格式:LongWritable, Text
reduce 的輸出 kv 是用戶事先定義好的固定格式:
我們需要設計的是 map 的輸出和 reduce 的輸入 kv,而兩者又保持一致
只需要設計一組 kv 即可
(LongWritable, Text) --> kv --> (?, ?)