隨着計算機網絡基礎設施的完善,社交網絡和電商的發展以及物連網的推動,產生了愈來愈多的大數據,使得人工智能最近幾年也有了長足的發展(可供機器學習的樣本數據量足夠大了),大數據的存儲和處理也愈來愈重要,國家對此也比較重視(可上網搜索關鍵字「大數據白皮書」關鍵字,以瞭解詳細狀況),會長決定和年輕人也一起學習一下,因而報了網易雲課堂的課程,不定時將學習到的東西整理爲博客,此乃開篇。java
學習大數據必先學習Hadoop,由於它是目前世界上最流行的分佈式數據處理框架。node
Tips:所謂大數據,是指數據量龐大、產生數度快、結構多樣的價值密度低的數據。其中,數據量龐大是指數據規模超出了1,2臺高性能主機所能處理範圍;結構多樣性是指除了關係型數據庫可以處理的結構化數據還包含半結構化數據(如各種傳感設備必如地鎊、衛星、GPS設備等產生的純文本格式的數據,還有良心網站NASA官網公佈的txt格式的空間天氣數據等成行成列的數據)和非結構化數據(視頻、圖像等)。這些數據的價值密度廣泛較低(和具體的應用範圍也有關係,好比NASA的數據,若是想知道某天的太陽射電狀況,看當天發佈的txt就行了,價值密度很高,可是這就不算大數據了,由於須要採集的數據量很小;若是想知道過去N年太陽射電的極值就須要處理不少數據,這些數據的價值密度就低了),大數據處理的目的就是從價值密度的數據裏把有價值的數據過濾分析出來。linux
Hadoop是一個用於分佈式大數據處理的編程框架。同時它也是個大數據處理完整的生態系統,圍繞着Hadoop,這個生態系統還包括但不限於:數據庫
但願本系列的寫做可以堅持下去,對上述內容都有所涉及吧。apache
假設老王在某不知名IT公司工做,因爲最近太陽活動異常,引發了領導的外甥的讀碩士的同窗的關注,領導讓老王把山西鐵島太陽射電望遠鏡觀測到的近30年的太陽射電數據下載下來,讓老王從裏面找到最高的記錄。老王畢竟搞挨踢已有多年,雖然技術不行,終日碌碌無爲,但多年的直覺告訴老王這個很簡單。老王馬上下載了其中一個文件並大體看了文件的機構:數據保存在txt文件裏,每行N列,其中包含了時間和數據信息列,大約每0.1s記錄一條數據,一個文件記錄15分鐘的數據,大約有9000條記錄,1個小時4個文件,1天96個文件,30年大約1051200個文件,一共大約100億條數據,這其中還有一些損壞的文件,還有一些用9999表示的未檢測到值的佔位數據須要特殊照顧。編程
老王以爲單機處理這些數據耗時過久,因而老王找來一些公司淘汰下來的舊服務器(通常小公司最破的機器都是服務器),準備每一個機器負責一部分,最後把結果彙總,老王在開發的過程當中仍是遇到了不少問題,好比,如何分配任務,有的機器破,有的機器新,還有的文件大,有的文件小,老是不能保證全部的任務一塊兒完成,先完成任務的機器閒置浪費掉了資源;還有最後把結果經過網絡通訊彙總起來,如何保證數據不丟失,不覆蓋;還有若是某臺機器出了問題,如何從新分配任務,這些非核心業務的開發使得老王心力憔悴,還好,老王最後找到了Hadoop這個工具,這個工具給老王提供了一個簡單的編程模型,老王在map方法中寫了分配的任務的邏輯,在reduce方法中寫了合併結果的邏輯,而後Hadoop幫老王完成了其餘全部事情,Hadoop就是幹這個的。以上故事純屬虛構,若有雷同,實屬巧合。服務器
其實上述意淫的例子裏的數據量不是很大,若是天天產生上TB級別的數據,就算是速度很快的固態硬盤也須要小時級時間才能讀取一遍,速度仍是遠遠跟不上,終歸有上限,並且高性能主機價格不菲,不如把數據分開放到一個相對廉價又可擴展的計算機集羣中,每一個節點上運行一段程序並處理一小塊數據,而後在彙總處理結果,使用Hadoop可讓開發者沒必要把精力放在集羣的建設上,採用Hadoop提供的簡單的編程模型就能夠實現分佈式處理。網絡
Hadoop集羣中運行的守護進程共有5類:框架
Hadoop集羣中的機器(節點)分爲2類:主節點和從節點,NameNode、JobTracker所在節點爲主節點(負責管理),DataNode和TaskTracker所在節點爲從節點(負責幹活兒)。ssh
NameNode節點負責將一個文件分紅若干文件塊,並記錄了HDFS文件系統中的文件塊放了在哪些DataNode中(一個數據塊被冗餘地放到1個或多個DataNode節點中),一個集羣中只有一個NameNode節點(Hadoop2.X中狀況有所不一樣了),且該節點一般再也不運行DataNode和TaskTracker守護進程。
DataNode實際管理不少NameNode分配給它的不少數據塊,當有文件塊變更時會通知NameNode,同時也從NameNode接受指令。一個集羣中有多個DataNode節點,DataNode之間也會保持聯繫,複製冗餘文件塊,這樣當一個DataNode出現故障後不會影響到文件的完整性。
SNN只與NameNode通訊,定時獲取HDFS元數據的快照,一個集羣只有一個SNN,且SNN所在節點只運行SNN守護進程,不幹其它的事情。當NameNode出現故障後,能夠人工啓用SNN做爲NameNode。
JobTracker負責分配MapReduce任務給TaskTracker,負責監控任務的執行,如任務失敗後重啓任務。JobTracker守護進程運行在主節點上,一般該節點不運行DataNode和TaskTracker守護進程。
TaskTracker負責完成JobTracker分配的任務並和JobTranker進行通訊,回報狀況。TaskTracker守護進程運行在多個子節點上
上圖中,NameNode和JobTracker是分開的,若是集羣規模不大也能夠運行在同一個節點上(若是這個節點出現故障該如何恢復?)
在安裝Hadoop以前須要先安裝以下軟件:
我用的是Ubuntu16.04,已經預裝了ssh和ssh-kengen了,只須要安裝jdk和sshd,能夠經過執行命令which
命令來檢查是否安裝了某軟件,如which sshd
下載壓縮包解壓便可:
sudo mkdir /usr/local/lib/jvm
sudo tar -zxv -f ~/setupFiles/jdk-8u101-linux-x64.tar.gz -C /usr/local/lib/jvm
配置環境變量:
修改 /etc/profile文件,追加:
export JAVA_HOME=/usr/local/lib/jvm/jdk1.8.0_101 export PATH=$JAVA_HOME/bin:$PATH
配置完畢後執行命令source /etc/profile
,此刻經過echo $JAVA_HOME
應該能看到剛纔設置的了。
sudo apt install openssh-server
安裝完了sshd後應該能夠經過ssh lcoalhost
命令遠程訪問了,可是須要輸入密碼,Hadoop集羣節點間要進行通訊須要配置爲無密碼登陸方式。
執行以下命令:
ssh-keygen -t rsa
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
chmod 0600 ~/.ssh/authorized_keys
ssh-keygen
命令時一路回車不要輸入密碼,執行完畢後會在/home/userName/.ssh路徑下生成公鑰和私鑰id_rsa和id_rsa.pub。若是一切順利的話,如今能夠經過ssh localhost
無密碼登陸了我下載的是1.0.4版本(2.X版本和1.X版本有着很大的差異,仍是先學會1.X再看2.X吧,咱們的課程也是以1.X爲例的,事實上我剛纔下的2.X,發現不少東西不懂,又退回1.X了,:-)),先把下載下來的壓縮包解壓到~/wiley/hadoop(其實最好放按照Linux的習慣放到/usr/local下,而後把hadoop目錄及裏面的文件所屬用戶和所屬組改爲當前用戶和當前用戶所屬組)
解壓後配置文件conf/hadoop-env.sh文件中的JAVA_HOME,反註釋以下行
# export JAVA_HOME=/usr/lib/j2sdk1.5-sun
,而且設置爲相應的Java所在路徑。
Hadoop能夠在三種模式下工做:
工做環境下是分佈式模式,開發環境下可使用單節點模式或僞分佈式模式,方便調試。解壓後不作配置就是單節點模式,而僞分佈式模式意思是指集羣中的各個節點實際配置爲同一臺機器。下面的步驟用來配置僞分佈式模式:
反註釋並修改JAVA_HOME:
export JAVA_HOME=/usr/local/lib/jvm/jdk1.8.0_101
<configuration> <property> <name>hadoop.tmp.dir</name> <value>/home/joey/wiley/hadoop/hadoop_temp/</value> <description>http://stackoverflow.com/questions/2354525/what-should-be-hadoop-tmp-dir</description> </property> <property> <name>fs.default.name</name> <value>hdfs://localhost:9000</value> <description>NameNode守護進程所在機器和端口</description> </property> </configuration>
<configuration> <property> <name>dfs.replication</name> <value>1</value> <description>HDFS的默認副本數,因爲是僞分佈式模式,因此設置爲1</description> </property> </configuration>
<configuration> <property> <name>mapred.job.tracker</name> <value>localhost:9001</value> <description>JobTracker守護進程所在機器及端口</description> </property> </configuration>
在啓動以前先格式和HDFS文件系統:
cd ~/wiley/hadoop/bin ./hadoop namenode -format
而後啓動Hadoop:./start-all.sh
,若是一切順利的話用jps
命令查看會有5個進程(不包括jps自己):
此時能夠打開兩個基於Web的界面
文章的最後運行一個簡單的MapReduceJob:單詞統計。Hadoop中已經附有一些實例Java代碼,放在了hadoop/src/examples/org/apache/hadoop/examples,其中一個叫作WordCount.java,是用來統計文件中單詞數量的,代碼很簡單的,你們能夠去看看。此處先運行一下這個例子感覺一下,執行以下命令
mkdir test
mkdir test/classes
mkdir test/src
cp src/examples/org/apache/hadoop/examples/WordCount.java test/src
生成jar文件:
javac -classpath hadoop-core-1.0.4.jar:lib/commons-cli-1.2.jar -d test/classes test/src/WordCount.java
jar -cvf test/WordCount.jar -C test/classes/ .
運行該程序須要兩個參數(可參考源碼文件),一個是放置文本文件的input路徑,一個是輸出結果的output路徑,先在HDFS中建立之:
bin/hadoop dfs -mkdir input
在本地文件系統中建立一個文本文件test/f1.txt,寫入一句話:2b or not 2b is ff
,把文件put到HDFS裏:
bin/hadoop fs -put test/f1.txt /user/joey/input
激動人心的時刻到了:
bin/hadoop jar test/WordCount.jar org.apache.hadoop.examples.WordCount input output
因爲input和output位於/user/joey下面,而/user/joey是默認的工做目錄,全部直接寫input和output,不用在前面加/user/joey/。如今看看運行結果:
竟然用了整整兩天時間才寫完,啊,雖然有點蛇尾,但是我太累了。到此結束,歡迎批評。
*參考資料: