Hadoop

1. Hadoop簡介

Apache Hadoop 標志

1.1 背景介紹

Hadoop是Apache旗下的開源的分布式計算平臺,它可以運行在計算機集群之上,提供可靠的、可擴展的分布式計算功能。
Hadoop與三遍論文密不可分:
① 2003年,谷歌發布的分布式文件系統GFS的論文,可以用于解決海量數據存儲的問題。
② 2004年,谷歌發布了MapReduce的論文,可以用于解決海量數據計算的問題。
③ 2006年,谷歌發布了BigTable的論文,它是以GFS為底層數據存儲的分布式存儲系統。

Hadoop中的HDFS是GFS的開源實現;
Hadoop中的MapReduce是谷歌MapReduce的開源實現;
Hadoop中的HBase是谷歌BigTable的開源實現。

1.2 Hadoop核心組件

Hadoop由四個主要模塊組成:
Hadoop Common: 一組工具和庫,可補充其他模塊并確保與用戶計算機系統的兼容性;
Hadoop Distributed File System (HDFS):提供可對應用數據進行高吞吐量訪問的分布式文件系統。;
Hadoop YARN(Yet Another Resource Negotiator):作業調度和集群資源管理框架;
Hadoop MapReduce:基于YARN的大數據集并行處理系統,從數據庫讀取,轉換和分析數據。

Hadoop生態系統

Hadoop生態系統

基于Hadoop技術架構數據倉庫搭建

在大數據處理當中,最核心要解決的其實就是兩個問題,大數據存儲和大數據計算。在Hadoop生態當中,解決大數據存儲,主要依靠就是HDFS,再配合數據庫去完成。而MapReduce為海量的數據提供了計算。

1.2.1 HDFS

HDFS是什么
HDFS即Hadoop distributed file system(hadoop分布式文件系統),在Hadoop當中負責分布式存儲階段的任務,它是一個分布式的文件系統,也可以用來存放單個機器的數據,只是大部分用來存儲分布式數據。HDFS跟window下的NTFS一樣可以通過目錄樹來查找數據。
HDFS有什么用
整個Hadoop框架,本質上來說都是基于分布式實現的,隨著數據規模的越來越大,一臺機器無法存儲所有的數據,所以需要多臺機器來存儲。而多臺機器存儲又不方便管理,所以需要一個分布式的系統來管理分布在不同機器中的數據。
事實上,HDFS的出現,就是為了解決分布式框架下,數據存儲管理的問題。而HDFS只是分布式文件系統中的一種,依托于Hadoop生態,去承擔大數據分布式存儲的管理任務。
HDFS的概念與架構
HDFS是典型的主/從架構。HDFS集群由一個NameNode組成,NameNode是一個主服務器,它管理文件系統名稱空間并控制客戶機對文件的訪問。此外,還有許多datanode,通常是集群中的每個節點一個datanode,它們管理附加到它們所運行的節點上的存儲。

HDFS架構

Namenode:

即master,有以下功能

*管理文件系統命名空間;

*控制client對數據的讀取和寫入請求;

*管理數據塊到datanode的映射關系;

*管理副本策略。

Datanode:

即slave,主要是存儲文件塊數據,接受來自namenode的指令,并執行指令對數據塊的創建,刪除,復制等操作。

Client:

即客戶端,有以下功能:

*對文件的切分,HDFS上傳數據時,client將文件切分成多個block再進行上傳;

*與namenode交互,獲取文件的索引信息;

*與datanode交互,對數據的讀取和寫入;

*在客戶端中提供相關HDFS的命令,比如對HDFS的管理,格式化namenode,對HDFS對數據操作,比如上傳文件到HDFS等。

Secondary namenode:

并非namenode的熱備,當namenode掛掉的時候,并不能立馬替換namenode并提供服務,只是在定時的對namenode進行備份,存在一定的時間誤差,secondary會備份namenode的Fsimage和Edits,在緊急情況下,可以適用secondarynamenode來恢復部分的namenode。

關于大數據學習,Hadoop HDFS存儲入門,以上就為大家做了簡單的介紹了。在Hadoop大數據框架當中,HDFS作為分布式文件系統,始終是重要的核心組件,學習當中也自然需要深入理解掌握。

參考:
http://www.lxweimin.com/p/fe77da35b653

1.2.2 YARN

Yarn 的全稱是 Yet Another Resource Negotiator,意思是“另一種資源調度器”


YARN架構

YARN應用示例

Container

容器(Container)這個東西是 Yarn 對資源做的一層抽象。就像我們平時開發過程中,經常需要對底層一些東西進行封裝,只提供給上層一個調用接口一樣,Yarn 對資源的管理也是用到了這種思想。

Container

如上所示,Yarn 將CPU核數,內存這些計算資源都封裝成為一個個的容器(Container)。需要注意兩點:

  • 容器由 NodeManager 啟動和管理,并被它所監控。
  • 容器被 ResourceManager 進行調度。

ResourceManager(RM)

從名字上我們就能知道這個組件是負責資源管理的,整個系統有且只有一個 RM ,來負責資源的調度。它也包含了兩個主要的組件:定時調用器(Scheduler)以及應用管理器(ApplicationManager)。

  1. 定時調度器(Scheduler):從本質上來說,定時調度器就是一種策略,或者說一種算法。當 Client 提交一個任務的時候,它會根據所需要的資源以及當前集群的資源狀況進行分配。注意,它只負責向應用程序分配資源,并不做監控以及應用程序的狀態跟蹤。
  2. 應用管理器(ApplicationManager):應用管理器就是負責管理 Client 用戶提交的應用。定時調度器(Scheduler)不對用戶提交的程序監控,監控應用的工作正是由應用管理器(ApplicationManager)完成的。

ApplicationMaster

每當 Client 提交一個 Application 時候,就會新建一個 ApplicationMaster 。由這個 ApplicationMaster 去與 ResourceManager 申請容器資源,獲得資源后會將要運行的程序發送到容器上啟動,然后進行分布式計算。

為什么是把運行程序發送到容器上去運行?如果以傳統的思路來看,是程序運行著不動,然后數據進進出出不停流轉。但當數據量大的時候就沒法這么玩了,因為海量數據移動成本太大,時間太長。大數據分布式計算就是這種思想,既然大數據難以移動,那我就把容易移動的應用程序發布到各個節點進行計算唄,這就是大數據分布式計算的思路。

NodeManager

NodeManager 是 ResourceManager 在每臺機器的上代理,負責容器的管理,并監控他們的資源使用情況(cpu,內存,磁盤及網絡等),以及向 ResourceManager/Scheduler 提供這些資源使用報告。

提交一個 Application 到 Yarn 的流程

YARN如何運行一個應用程序

這張圖簡單地標明了提交一個程序所經歷的流程,接下來我們來具體說說每一步的過程。

  1. Client 向 Yarn 提交 Application,這里我們假設是一個 MapReduce 作業。
  2. ResourceManager 向 NodeManager 通信,為該 Application 分配第一個容器。并在這個容器中運行這個應用程序對應的 ApplicationMaster。
  3. ApplicationMaster 啟動以后,對 作業(也就是 Application) 進行拆分,拆分 task 出來,這些 task 可以運行在一個或多個容器中。然后向 ResourceManager 申請要運行程序的容器,并定時向 ResourceManager 發送心跳。
  4. 申請到容器后,ApplicationMaster 會去和容器對應的 NodeManager 通信,而后將作業分發到對應的 NodeManager 中的容器去運行,這里會將拆分后的 MapReduce 進行分發,對應容器中運行的可能是 Map 任務,也可能是 Reduce 任務。
  5. 容器中運行的任務會向 ApplicationMaster 發送心跳,匯報自身情況。當程序運行完成后, ApplicationMaster 再向 ResourceManager 注銷并釋放容器資源。

參考:https://zhuanlan.zhihu.com/p/54192454

1.2.3 MapReduce

MapReduce是Hadoop的核心框架之一,主要負責分布式并行計算。MapReduce 既是計算框架,也是編程模型,主要基于Java語言來編程,這也是為什么Hadoop學習要求要有一定的Java基礎。當然,在這幾年的發展當中,MapReduce的計算性能受到詬病,取而代之受到重用的是Spark。
MapReduce運行過程,通常涉及到input、split、map、shuffle、reduce、output幾個階段,其中shuffle過程包括sort、copy、combine操作,reduce之前有時涉及二次排序。

MapReduce編程,主要有三種方式:

1、Hadoop streaming執行mapreduce

2、Hive執行mapreduce

3、Java MR編程

①Hadoop streaming執行MapReduce

優點:

可以用大多數語言開發;

代碼量少,開發速度快;

方便本地調試。

不足:

只能通過參數控制MR框架,控制性較弱,比如定制partitioner、combiner;

支持的數據類型和數據結構有限,不適合做復雜處理,處理字符型較多;

②Hive執行MapReduce

將類SQL轉換成MapReduce,定位于數據倉庫。

優點:

開發速度快,易調試,易理解;

易于構建數據倉庫模型;

內置函數功能齊全,比如rownumber等窗口函數;

可擴展性好,比如自定義存儲格式、自定義函數UDF;

多接口,比如JDBC、Thrift、Rest等。

缺點:

不能用于復雜計算,比如涉及時序處理的數據;

可控制性較弱,比如partition、關聯等操作。

③Java MR編程

用Java編寫MR,可以說是最“原始”的一種方式,Java面向對象編程,設計模式成熟,通用性好,并且Java方面第三方類庫非常豐富。

優點:

定制性強,比如定制partitioner、定制combiner等;

數據類型和數據結構豐富,隊列、堆棧、自定義類等使用方便;

控制性非常高,包括MR運行過程的一些控制,Map端join等;

可以方便使用Hadoop組件類庫中的類或工具,比如HDFS文件操作類等。

缺點:

相比Hive、Hadoop streaming或Pyspark,開發代碼量較大,對開發環境要求高且不易調試;

通常每個操作都要寫一個MR類;

不如Spark執行效率高。

參考:http://www.lxweimin.com/p/3c9aa4214dd3

1.3 Hadoop的特點

① 跨平臺性:
hadoop是基于java語言開發的,有很好的跨平臺性,可以運行在Linux平臺上;
② 高可靠性:
hadoop中的HDFS是分布式文件系統,可以將海量數據分布冗余存儲在不同的機器節點上,即使是某個機器副本上發生故障,其他的機器副本也能正常運行;
③ 高容錯性:
HDFS把把文件分布存儲在很多不同的機器節點上,能實現自動保存多個副本,因此某個節點上的任務失敗后也能實現自動重新分配;
④ 高效性:
hadoop的核心組件HDFS和MapReduce,一個負責分布式存儲一個負責分布式處理,能夠處理PB級別的數據;

⑤ 低成本與高擴展:
hadoop在廉價的計算機集群上就可以運行,因此成本比較低,并且可以擴展到幾千個計算機節點上,完成海量數據的存儲和計算。

參考:
https://zhuanlan.zhihu.com/p/369486877

1.4 應用實例

  • Adobe

    • We use Apache Hadoop and Apache HBase in several areas from social services to structured data storage and processing for internal use.
    • We currently have about 30 nodes running HDFS, Hadoop and HBase in clusters ranging from 5 to 14 nodes on both production and development. We plan a deployment on an 80 nodes cluster.
    • We constantly write data to Apache HBase and run MapReduce jobs to process then store it back to Apache HBase or external systems.
    • Our production cluster has been running since Oct 2008.
  • Alibaba

    • A 15-node cluster dedicated to processing sorts of business data dumped out of database and joining them together. These data will then be fed into iSearch, our vertical search engine.
    • Each node has 8 cores, 16G RAM and 1.4T storage.
  • Facebook
    • We use Apache Hadoop to store copies of internal log and dimension data sources and use it as a source for reporting/analytics and machine learning.
    • Currently we have 2 major clusters:
      • A 1100-machine cluster with 8800 cores and about 12 PB raw storage.
      • A 300-machine cluster with 2400 cores and about 3 PB raw storage.
      • Each (commodity) node has 8 cores and 12 TB of storage.
      • We are heavy users of both streaming as well as the Java APIs. We have built a higher level data warehousing framework using these features called Hive (see the http://hadoop.apache.org/hive/). We have also developed a FUSE implementation over HDFS.

參考:https://cwiki.apache.org/confluence/display/hadoop2/PoweredBy

2. Hadoop安裝

2.1 安裝前的準備

2.1.1 支持的平臺

2.1.2 需要提前安裝的軟件

Java

官方現在推薦OpenJDK,其他版本(比如Oracle)也可以
Hadoop 3.3.x支持Java 8 和 Java 11,推薦Java 8
Hadoop 3.0.x 到 3.2.x n只支持 Java 8
Hadoop from 2.7.x 到 2.10.x 同時支持 Java 7 and 8
本文安裝Hadoop 3.2.2, OpenJDK版本為系統自帶的1.8.0

ssh

必須安裝并且保證 sshd一直運行,以便用Hadoop 腳本管理遠端Hadoop守護進程
安裝ssh

 sudo apt-get install ssh

2.1.3 下載Hadoop

考慮到網速以及以后適配Spark的版本問題,我們選擇比較新的Hadoop 3.2.2穩定發行版。香港可以直接從官網下載https://hadoop.apache.org/releases.html
內地可以使用鏡像網站,比如清華鏡像
https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-3.2.2/

清華大學開源鏡像

2.2 安裝過程(單機版)

參考
http://www.lxweimin.com/p/cdae5bab030f
https://blog.csdn.net/weixin_42001089/article/details/81865101
https://blog.csdn.net/qq_44830040/article/details/104873759
https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/SingleCluster.html
集群配置
https://blog.csdn.net/qq_39785575/article/details/106300628

2.3 環境變量設置

1d0aee74363e019589680eff8e31891.jpg

2.4 Hadoop 啟動

格式化namenode

hadoop namenode -format
image.png

啟動hdfs

start-all.sh
image.png

查看相應進程

jps

瀏覽器訪問

localhost:9870
image.png

3. Hadoop 應用

3.1 上傳文件到HDFS

3.1.1 Linux 命令行

(1)格式畫NameNode

hdfs namenode -format

(2) 啟動hdfs

start-all.sh

(3)查看hdfs狀態

hdfs dfsadmin -report

(4)上傳文件到hdfs

hdfs dfs -put 要上傳的文件路徑  目標路徑
#舉例
hdfs dfs -put test.txt /

(5)查看hdfs路徑下的文件

hdfs dfs -ls /

(6)讀取hdfs文件內容

hdfs dfs -cat /test.txt

(7)刪除hdfs文件

hdfs dfs -rm /test.txt

3.1.2 Java

3.2 MapReduce

3.2.1 MapReduce是什么

(1) MapReduce是一種分布式計算框架 ,以一種可靠的,具有容錯能力的方式并行地處理上TB級別的海量數據集。主要用于搜索領域,解決海量數據的計算問題。
(2) MapReduce有兩個階段組成:Map和Reduce,用戶只需實現map()和reduce()兩個函數,即可實現分布式計算。

3.2.2 MapReduce做什么

(1) MapReduce框架由Map和Reduce組成。
(2) Map()負責把一個大的block塊進行切片并計算。
(3) Reduce() 負責把Map()切片的數據進行匯總、計算。

3.2.3 MapReduce怎么做

image

(1) 第一步對輸入的數據進行切片,每個切片分配一個map()任務,map()對其中的數據進行計算,對每個數據用鍵值對的形式記錄,然后輸出到環形緩沖區(圖中sort的位置)。
(2) map()中輸出的數據在環形緩沖區內進行快排,每個環形緩沖區默認大小100M,當數據達到80M時(默認),把數據輸出到磁盤上。形成很多個內部有序整體無序的小文件。
(3) 框架把磁盤中的小文件傳到Reduce()中來,然后進行歸并排序,最終輸出。

3.2.4 要點是什么

MapReduce是六大過程,簡單來說:Input, Split, Map, Shuffle, Reduce, Finalize
(1) MapReduce將輸入的數據進行邏輯切片,一片對應一個Map任務
(2) Map以并行的方式處理切片
(3) 框架對Map輸出進行排序,然后發給Reduce
(4) MapReduce的輸入輸出數據處于同一個文件系統(HDFS)
(5) 框架負責任務調度、任務監控、失敗任務的重新執行
(6) 框架會對鍵和值進行序列化,因此鍵和值需要實現writable接口,框架會對鍵排序,因此必須實現writableComparable接口。

3.1.5 舉個例子

如何統計1TB或1PB文件里的單詞數呢

image.png

(1) Input: 我們輸入很多文檔,文檔的每一行有很多不同的單詞
(2) Split: 找不同的worker分配不同的任務,就是Split過程,那怎么切分呢?每一行文檔分給一個worker
(3) Map: 就切分成單詞和它出現的次數,寫成鍵值對,每次出現的次數是1,就寫1。
(4) Shuffle就是把不同的單詞繼續放到同樣的盒子里面,Bear放一起,Car放一起,這可以由Shuffle寫的時候算法來決定。當然現在很多智能都不用做了,有時候還需要隨機采樣的方式來實現。
(5) Reduce,就是把相同的數據放一起,比如Car有3個就寫3,River是2個就寫2,最后再放到一起,這樣便于提供服務,得到最終結果。
大家可以看到最后箭頭指過來是亂序的,也就是說這個執行過程實際上是高度并行的,也不用等待每個都完成,所以說這是一個很好的優化過程。

Hadoop Streaming是一種運行作業的實用工具,它允許用戶創建和運行任何可執行程序 (例如:Java, Python, Shell工具)來做為mapper和reducer。

代碼形式:


image.png

Map輸入每一行的ID是key,value是這一行的單詞。有這個結果以后就可以統計每個單詞出現的次數。Reduce輸入的還是各個單詞,但后面跟的是一個串,是在里面出現的次數,1,1,1,我們把1加到一起就是sum的過程,這就是MapReduce的整個過程。輸出我們的關鍵詞和它的出現次數

3.1.6 再舉個例子

參考:
https://zhuanlan.zhihu.com/p/55884610
https://www.cnblogs.com/duanzi6/p/11348960.html

將天氣數據每年整合成一個文件,存入hdfs

hdfs dfs -mkdir /ncdc
hdfs dfs -put ~/ncdc/raw/ /ncdc

hdfs 查看命令

hdfs dfs -ls -R 

以NCDC原始數據求每個年份最高氣溫為例:
首先原始數據如下(去除了一些列用省略號表示),這些數據就是map函數的輸入

0067011990999991950051507004...9999999N9+00001+99999999999999...
0043011990999991950051512004...9999999N9+00221+99999999999999...
0043011990999991950051518004...9999999N9-00111+99999999999999...
0043012650999991949032412004...0500001N9+01111+99999999999999...
0043012650999991949032418004...0500001N9+00781+99999999999999...

這些行以鍵值對的方式作為map函數的輸入:

(0,0067011990999991950051507004...9999999N9+00001+99999999999999...)
(106,0043011990999991950051512004...9999999N9+00221+99999999999999...)
(212,0043011990999991950051518004...9999999N9-00111+99999999999999...)
(318,0043012650999991949032412004...0500001N9+01111+99999999999999...)
(424,0043012650999991949032418004...0500001N9+00781+99999999999999...)

其中key是文件中的行偏移量,map函數會提取輸入中的年份和氣溫信息(粗體),并作為輸出:

(1950,0)
(1950,22)
(1950,-11)
(1949,111)
(1949,78)

map函數的輸出會經過MapReduce計算框架基于鍵的排序和分組后發送到reduce函數作為輸入:

(1949,[111,78])
(1950,[0,22,-11])

reduce遍歷值列表找到最大溫度后返回:

(1949,111)
(1950,22)


整個MapReduce計算流程如下:

image

從本地模式到分布式集群計算

處理少量輸入數據并不能體現MapReduce計算框架的優勢,當有大量輸入的數據流時,我們需要分布式文件系統HDFS)和Hadoop資源管理系統YARN)實現集群分布式計算。

一、術語

先了解一下關于數據流的一些術語

Job:MapReduce作業,是客戶端需要執行的一個工作單元:包括輸入數據、MapReduce程序和配置信息
Task:Hadoop會將作業job分成若干個任務(task)執行,其中包括兩類任務:map任務和Reduce任務
Input split:輸入分片,Hadoop會將MapReduce的輸入數據劃分成等長的小數據塊,稱為“分片”,Hadoop為每個分片構建一個map任務,并由該任務運行用戶自定義的map函數從而處理分片中的每條記錄。

二、分片

1、分片的意義

處理單個分片的時間小于處理整個輸入數據花費的時間,因此并行處理每個分片且每個分片數據比較小的話,則整個處理過程會獲得更好的負載平衡(因為一臺較快的計算機能夠處理的數據分片比一臺較慢的計算機更多,且成一定比例)。

2、分片的大小

盡管隨著分片切分得更細,負載平衡的質量也會更高但是分片切分得太小的時候,管理分片的總時間和構建map任務的總時間將決定整個作業的執行時間
對于大多數作業來說,一個合理的分片大小趨于HDFS一個塊的大小,默認是128MB。

三、數據本地化優化(map任務)

Hadoop在存儲有輸入數據(HDFS中的數據)的節點上運行map任務,可以獲得最佳性能(因為無需使用寶貴的集群帶寬資源),這就是“數據本地化優化”(data locality optimization)。

1、本地數據、本地機架與跨機架map任務

有時候存儲該分片的HDFS數據塊復本的所有節點可能正在運行其他map任務,此時作業調度需要從某一數據塊所在的機架中一個節點尋找一個空閑的map槽(slot)來運行該map任務分片。特別偶然的情況下(幾乎不會發生)會使用其他機架中的節點運行該map任務,這將導致機架與機架之間的網絡傳輸。下圖顯示了這三種可能性。

image

2、數據本地化原則決定了最佳分片大小

數據本地化的原則解釋了為什么最佳分片大小應該與HDFS塊大小相同:因為這是確保可以存儲在單個節點上最大輸入塊的大小。

3、reduce任務不具備數據本地化的優勢

單個reduce任務的輸入通常來自于所有mapper的輸出。排過序的map輸出需通過網絡傳輸發送到運行reduce任務的節點,數據在reduce端合并并由用戶定義的reduce函數處理。

四、MapReduce任務數據流

reduce任務的數量并非由輸入數據的大小決定,而是獨立指定的。

真實的應用中,幾乎所有作業都會把reducer的個數設置成較大的數字,否則由于所有中間數據都會放到一個reduce任務中,作業的處理效率就會及其低下。
增加reducer的數量能縮短reduce進程;但是reducer數量過多又會導致小文件過多而不夠優化。一條經驗法則是:目標reducer保持每個運行在5分鐘左右,且產生至少一個HDFS塊的輸出比較合適。

1、單個reduce任務的MapReduce數據流

image

虛線框表示節點,虛線箭頭表示節點內部的數據傳輸,實線箭頭表示不同節點之間的數據傳輸。

2、多個reduce任務的MapReduce數據流

image

map任務到reduce任務的數據流稱為shuffle(混洗,類似洗牌的意思),每個reduce任務的輸入都來自許多map任務。shuffle比圖示的更加復雜而且調整shuffle參數對作業總執行時間的影響非常大

3、無reduce任務

當數據完全可以并行處理時可能會出現無reduce任務的情況,唯一的非本地節點數據傳輸是map任務將結果寫入HDFS。

image

五、combiner函數(減少map和reduce之間的數據傳輸)

由前面的描述我們知道數據傳輸會占用集群上的可用帶寬資源,從而限制了MapReduce作業的數量,因此我們應該盡量避免map和reduce任務之間的數據傳輸。combiner作為一個中間函數簡化map任務的輸出從而減少了map任務和reduce任務之間的數據傳輸。


舉個例子
假設我們有一個計算每年最高氣溫的任務,1950年的讀數由兩個map任務處理(因為它們在不同的分片中)。假設第一個map的輸出如下:

(1950,0)
(1950,20)
(1950,10)

第二個map的輸出如下:

(1950,25)
(1950,15)

reduce函數調用時,輸入如下:

(1950,[0,20,10,25,15)

reduce的輸出如下:

(1950,25)

為了優化reduce函數的輸入,我們可以使用combiner找到每個map任務輸出結果中的最高氣溫。那么可以將reduce函數調用的輸入更改為:

(1950,[20,25])
其中20和25為每個map函數輸出結果中的最大值

我們可以用下面表達式來說明尋找最高氣溫的MapReduce過程中combiner的作用

max(0,20,10,25,15) = max(max(0,20,10),max(25,15)) = max(20,25)=25


很遺憾,并非所有函數都具有該屬性,比如計算平均值時就不能用mean作為combiner函數,因為:

mean(0,20,10,25,15) = 14
mean(mean(0,20,10),mean(25,15)) = mean(10,20) = 15

另外,combiner函數并不能取代reduce函數的位置,因為我們仍然需要reduce函數來處理不同map輸出中具有相同鍵的記錄。

寫MapReduce程序(Hadoop streaming)

Hadoop Streaming使用Unix標準流作為Hadoop和應用程序之間的接口,允許程序員用多種語言寫MapReduce程序。
Streaming天生適合于文本處理。map的輸入數據通過標準輸入傳遞給map函數,并且是一行一行地傳輸,并且將結果行寫到標準輸出。map輸出的鍵-值對是以一個制表符分隔的行,reduce輸入格式與之相同。reduce函數從標準輸入流中讀取輸入行,該輸入已經由Hadoop框架根據鍵排過序,最后將結果寫入標準輸出。
接下里我們用Streaming重寫按年份查找最高氣溫的MapReduce程序。
Map函數

import re
import sys

for line in sys.stdin:
    val = line.strip()
    (year,temp,q) = (val[15:19],val[87:92],val[92:93])
    if (temp != "+9999" and re.match("[01459]",q)
        print ("%s\t%s" % (year,temp))

Reduce函數



import sys 
(last_key,max_val) = (None,-sys.maxint) 
for line in sys.stdin: 
    (key,val) = line.strip().split("\t") 
    if last_key and last_key != key: 
        print ("%s\t%s" % (last_key,max_val))
        (last_key,max_val) = (key,int(val)) 
    else: 
        (last_key,max_val = (key,max(max_val,int(val))) 
if last_key: 
    print("%s\t%s" % (last_key,max_val))


示例3:
https://zhuanlan.zhihu.com/p/34903460

參考
https://zhuanlan.zhihu.com/p/62135686
https://zhuanlan.zhihu.com/p/32172999
https://zhuanlan.zhihu.com/p/55884610
https://hadoop.apache.org/docs/stable/hadoop-mapreduce-client/hadoop-mapreduce-client-core/MapReduceTutorial.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容