從數據爆炸開始。。。
一、 第三次工業革命
五、 理解MapReduce
5.1 手動拓展一個簡單單詞計數程序
multisetAdd (totalWordCount, wordCount);
}
5.2 相同程序在MapReduce中拓展
六、 運行第一個Hadoop程序——用Hadoop框架來統計單詞
6.1首先安裝JAVA JDK
6.2 下載一個Hadoop穩定版本
6.3 配置 Hadoop
第一次:18世紀60年代,手工工廠向機器大生產過渡,以蒸汽機的發明和使用為標志。
第二次:19世紀70年代,各種新技術新發明不斷被應用於工業生產,以電力的發明使用為標志。
第三次:20世界四五十年代末,以高新技術為代表的新科學技術革命,以原子能、航天技術和電子計算機
為標志。
二、 信息技術發展帶來的數據爆炸
三、 海量數據存儲與分析
四、 Hadoop-一個可靠的分布式共享存儲和分析系統
4.1 簡要介紹
4.2 歷史起源:Apache的子項目的子項目
4.4 比較Hadoop和SQL數據庫
- 紐約證券所交易 每天 1TB
- FaceBook一千億照片 1PB
- 騰訊 每天 300TB
- 淘寶 每天 pv20億 數據量 50TB
- ......

問題:數據量指數增加,磁盤訪問速度未能與時俱進
- 1990 年 一個磁盤 1370MB 速度4.4MB/s 用時5分鍾
- 2010 年 一個磁盤 1TB 速度 100MB/s 用時兩個半
分析:讀一個很慢,那么可以同時讀多個
- 如果把1TB存儲到100個磁盤,每個存儲1%,並行讀取,用時不到兩分鍾。
- 如果一個我們有100個1TB數據集,100個1TB磁盤,那么我們以磁盤共享的方式把每個數據集分布到100個磁盤中,這樣邊會大大提高每個數據集的讀取速率。
如果實現此類文件系統需要解決哪些問題?
- 硬盤故障:因為文件系統有多個磁盤,那么任意一個磁盤發生故障的概率就變得很高。(采取數據備份)
- 數據分析:某些分析任務需要結合大部分數據共同完成,那么我們的文件系統就要保證對來自多個數據源的數據進行分析的准確性。
Hadoop 是Apache基金會下一個開源的分布式計算平台,它以分布式文件系統HDFS和MapReduce算法為核心,為用戶提供了系統底層細節透明的分布式基礎架構。


如上圖Hadoop集群中有很多並行的機器來存儲和分析數據,客戶端把任務提交到集群,集群計算返回結果。
雄心勃勃的Doug Cutting:他先領導創立了Apache的項目Lucene,然后Lucene又衍生出子項目Nutch,Nutch又衍生了子項目Hadoop。Lucene是一個功能全面的文本搜索和查詢庫,Nutch目標就是要視圖以Lucene為核心建立一個完整的搜索引擎,並且能達到提到Google商業搜索引擎的目標。網絡搜索引擎和基本文檔搜索區別就在規模上,Lucene目標是索引數百萬文檔,而Nutch應該能處理數十億的網頁。因此Nutch就面臨了一個極大的挑戰,即在Nutch中建立一個層,來負責分布式處理、冗余、故障恢復及負載均衡等等一系列問題。。。
曙光的到來:2004年,Google發表了兩篇論文來論述Google文件系統(GFS)和MapReduce框架,並且使用了這兩項技術來拓展自己的搜索系統,於是Doug Cutting看到了這兩篇論文的價值並帶領他的團隊便實現了這個框架,並將Nutch移植上去,於是Nutch的可擴展性得到極大的提高。
Hadoop的誕生:Doug Cutting逐漸認識到急需要成立一個專門的項目來充實這兩種技術,於是就誕生了Hadoop。
2006年1月,雅虎雇佣Doug Cutting,並讓他和一個專門的團隊來一起改進Hadoop,並將其作為一個開源項目。
2008年2月19日,雅虎正式宣布,其索引網頁的生產系統采用的就是在10000多個核的Linux系統上運行的Hadoop。
於是,Hadoop真正達到了互聯網級。。。
ps:關於Doug Cutting它三個項目的名字由來,這個人很有意思,三個項目的名字都來源於他家庭,Lucene是他妻子的中間名也是她外祖母的名字,他兒子在很小的時候總是把吃飯的詞叫做Nutch,后來,他又把一個黃色大象毛絨玩具叫做Hadoop,這樣大家就明白了為何好多關於Hadoop的資料中都能看到個黃色的大象。
優點:Hadoop是一個開源框架,可編寫和運行分布式應用來處理大規模數據,分布式計算是一個不斷變化且寬泛的領域,優點如下:
1.易用性。Hadoop運行在由一般商用機器構成的大型集群上。
2.可靠性。Hadoop致力於一般商用機器上,其架構假設硬件會頻繁出現失效,它可以從容處理大多數此類故障。
3.可擴展。Hadoop通過增加集群節點,可以線性地拓展以處理更大數據集。
4.簡單。Hadoop允許用戶快速的編寫出高效地並行代碼。
4.3 了解分布式系統和Hadoop
分布式系統(向外拓展scale-out)與大型服務器(向上拓展scale-up),從IO性價比層面分析:
一個四IO通道的高端機,每個通道的吞吐量各為100MB/sec,讀取4TB數據也要接近3小時,而用Hadoop,同樣的數據被划分為較小的塊(通常為64MB),通過HDFS分不到群內的多台計算機上,集群可以並行存取數據,這樣,一組通用的計算機比一台高端機要便宜。
Hadoop與其它分布式系統比較,如SETI@home,它的一台中央服務器存儲了來自太空的無線電信號,並把這些信號數據發給分布在世界各地的客戶端計算,再將計算返回的結果存儲起來。
Hadoop對待數據的理念與其不同。SETI@home需要服務器和客戶端重復地傳輸數據,這種方式在處理密集數據時,會使得數據遷移變得十分困難。而Hadoop則強調把代碼向數據遷移,即Hadoop集群中既包含數據又包含運算環境,並且盡可能讓一段數據的計算發生在同一台機器上,代碼比數據更加容易移動,Hadoop的設計理念即是把要執行的計算代碼移動到數據所在的機器上去。
從總體上看,現在大多數數據應用處理的主力是關系型數據庫,即SQL面向的是結構化的數據,而Hadoop則針對的是非結構化的數據,從這一角度看,Hadoop提供了對數據處理的一種更為通用的方式。
下面,我們從特定的視角將Hadoop與SQL數據庫做詳細比較:
1. 用scale-out代替scale-up
拓展商用服務器的代價是非常昂貴的。要運行一個更大的數據庫,就要一個更大的服務器,事實上,各服務器廠商往往會把其昂貴的高端機標稱為“數據庫級服務器”,不過有時候有可能需要處理更大的數據集,但卻找不到更大的機器,而更為重要的是,高端機對於許多應用並不經濟。
2.用鍵值對代替關系表
關系型數據庫需要將數據按照某種模式存放到具有關系型數據結構表中,但是許多當前的數據模型並不能很好的適應這些模型,如文本、圖片、xml等,此外,大型數據集往往是非結構化或半結構化的。而Hadoop以鍵值對作為最基本的數據單元,能夠靈活的處理較少結構化的數據類型。
3.用函數式編程(MapReduce)代替聲明式查詢(SQL)
SQL從根本上說是一個高級聲明式語言,它的手段是聲明你想要的結果,並讓數據庫引擎判斷如何獲取數據。而在MapReduce程序中,實際的數據處理步驟是由你指定的。SQL使用查詢語句,而MapReduce使用程序和腳本。MapReduce還可以建立復雜的數據統計模型,或者改變圖像數據的處理格式。
4.用離線批量處理代替在線處理
Hadoop並不適合處理那種對幾條記錄讀寫的在線事務處理模式,而適合一次寫入多次讀取的數據需求。
也許你知道管道和消息隊列數據處理模型,管道有助於進程原語的重用,用已有模塊的簡單連接就可組成一個新的模塊,消息隊列則有助於進程原語的同步。
同樣,MapReduce也是一種數據處理模型 。它的最大的特點就是容易拓展到多個計算機節點上處理數據。在MapReduce中,原語通常被稱作Mapper和Reducer。也許講一個數據處理應用分解為一個Mapper和Reducer是非常繁瑣的,但是一旦你寫好了一個Mapreduce應用程序,僅需通過配置,就可將其拓展到集群的成百上千個節點上運行,這種簡單的可拓展性使得Mapreduce吸引了大量程序員。
統計一個單詞的出現次數,單詞只有一句話:"do as i say , not as i do"。如果文檔很小,一段簡單的代碼即可實現,下面是一段偽代碼:
define wordCount as Multiset;
for each document in documentSet {
T = tokenize(document);
for each token in T {
wordCount[token]++;
}
}
display(wordCount);
但是這個程序只適合處理少了文檔,我們試着重寫程序,使它可以分布在多個計算機上,每台機器處理文檔的不同部分,在把這些機器處理的結果放到第二階段,由第二階段來合並第一階段的結果。
第一階段要分布到多台機器上的代碼為:
defi ne wordCount as Multiset;
for each document in documentSet {
T = tokenize(document);
for each token in T {
wordCount[token]++;
}
}
sendToSecondPhase(wordCount);
第二階段偽代碼:
defi ne totalWordCount as Multiset;
for each wordCount received from firstPhase {
multisetAdd (totalWordCount, wordCount);
}
如果這么設計的話還有什么其他困難嗎?一些細節可能會妨礙它按預期工作,
- 如果數據集很大,中心存儲服務器性能可能會跟不上,因此我們需要把文檔分不到多台機器上存儲。
- 還有一個缺陷是wordcount被存放在內存當中,同樣,如果數據集很大一個wordcount就有可能超過內存容量,因此我們不能將其放在內存中,我們需實現一個基於磁盤的散列表,其中當然涉及大量編碼。
- 第二階段如果只有一台計算機,顯然不太合理,若按照第一階段的設計把第二階段的任務也分布到多台計算機上呢?答案當然是可以的,但是我們必須將第一階段的結果按某種方式分區,使其每個分區可以獨立運行在第二階段的各個計算機上。比如第二階段的A計算機只統計以a開頭的wordcount,計算機B統計wordcount-b分區,依次類推。
現在這個單詞統計程序正在變得復雜,為了使它能夠運行在一個分布式計算機集群中,我們發現需要添加以下功能:
- 存儲文件到多台計算機上
- 編寫一個基於磁盤的散列表,使其不受計算機內存限制
- 划分來自第一階段的中間數據
- 洗牌第一階段分區到第二階段合適的計算機上
僅僅這一個簡單的小問題就需要考慮這么多細節處理,這就是我們為什么需要一個Hadoop框架,當我們用MapReduce模型編寫程序時,Hadoop框架可以管理所有與可拓展性相關的底層問題。
Map和Reduce程序必須遵循以下鍵和值類型的約束
1.應用的輸入必須組織為一個鍵值對列表List<key1,value1>,輸入格式不受約束,例如處理多個文件的輸入格式可以使List<String filename,String fileContent>。
2.含鍵值對的列表被拆分,進而通過調用Mapper的Map函數對每個鍵值對<K1,V1>進行處理,Mapper 轉換每個<K1,V1>,並將其結果並入<K2,V2>。在上面例子中,Mapper轉換成的是一個<String word,Integer count>的列表。
3.所有Mapper的輸出被聚合在一個巨大的<K2,V2>列表中,所有共享K2的對被組織在一起成為一個新的鍵值對列表<K2,List(V2)>,讓reducer來處理每一個聚合起來的<K2,List(V2)>,並將處理轉換成<K3,V3>,MapReduce框架自動搜索所有<K3,V3>並將其寫入文件中。
在linux環境下配置Hadoop運行環境
- Hadoop需要1.6或更高版本
- 到oracle官網下載Linux版java安裝包(rpm包)
- 查看是否已安裝:java or java -version
- 卸載老版本 rpm -e jdk
- 安裝jdk rpm -ivh jdk
- 配置環境變量
# mkdir /usr/hadoop # cd /usr/hadoop/ # wget http://apache.mesi.com.ar/hadoop/common/hadoop-1.2.1/hadoop-1.2.1.tar.gz # tar -xzf hadoop-1.2.1.tar.gz # mv hadoop-1.2.1 hadoop # cd /usr/hadoop/hadoop/
# bin/hadoop
編輯 core-site.xml
# vim conf/core-site.xml
#Add the following inside the configuration tag <property> <name>fs.default.name</name> <value>hdfs://localhost:9000/</value> </property> <property> <name>dfs.permissions</name> <value>false</value> </property>
編輯 hdfs-site.xml
# vim conf/hdfs-site.xml
# Add the following inside the configuration tag <property> <name>dfs.data.dir</name> <value>/opt/hadoop/hadoop/dfs/name/data</value> <final>true</final> </property> <property> <name>dfs.name.dir</name> <value>/opt/hadoop/hadoop/dfs/name</value> <final>true</final> </property> <property> <name>dfs.replication</name> <value>2</value> </property>
編輯 mapred-site.xml
# vim conf/mapred-site.xml
# Add the following inside the configuration tag <property> <name>mapred.job.tracker</name> <value>localhost:9001</value> </property>
編輯 hadoop-env.sh
# vim conf/hadoop-env.sh
export JAVA_HOME=/opt/jdk1.7.0_17 export HADOOP_OPTS=-Djava.net.preferIPv4Stack=true
設置 JAVA_HOME path
格式化 Name Node
$ cd /usr/hadoop/hadoop $ bin/hadoop namenode -format
6.4 啟動 Hadoop Services
Use the following command to start all hadoop services.
$ bin/start-all.sh
輸入網址查看一下效果:
http://localhost:50030(MapReduce 的web頁面)
http://localhost:50070(HDFS 的web頁面)