畢業(yè)論文-基于Hadoop的大數(shù)據(jù)應(yīng)用系統(tǒng)研發(fā)_第1頁(yè)
畢業(yè)論文-基于Hadoop的大數(shù)據(jù)應(yīng)用系統(tǒng)研發(fā)_第2頁(yè)
畢業(yè)論文-基于Hadoop的大數(shù)據(jù)應(yīng)用系統(tǒng)研發(fā)_第3頁(yè)
畢業(yè)論文-基于Hadoop的大數(shù)據(jù)應(yīng)用系統(tǒng)研發(fā)_第4頁(yè)
畢業(yè)論文-基于Hadoop的大數(shù)據(jù)應(yīng)用系統(tǒng)研發(fā)_第5頁(yè)
已閱讀5頁(yè),還剩55頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

HUNANUNIVERSITY畢業(yè)論文論文題目基于Hadoop的大數(shù)據(jù)應(yīng)用系統(tǒng)研發(fā)學(xué)生姓名學(xué)生學(xué)號(hào)專業(yè)班級(jí)自動(dòng)化1101學(xué)院名稱電氣與信息工程學(xué)院指導(dǎo)老師學(xué)院院長(zhǎng)2015年 5月23日第一章緒論1.1課題背景及目的在計(jì)算機(jī)和互聯(lián)網(wǎng)經(jīng)過(guò)了幾十年的快速發(fā)展,數(shù)字化已經(jīng)開始在全球快速普及。文字,聲音,圖像全都轉(zhuǎn)化為計(jì)算機(jī)可以存儲(chǔ)和利用的數(shù)據(jù),很難想像有什么不能轉(zhuǎn)化為數(shù)據(jù)。特別是在移動(dòng)互聯(lián)網(wǎng)的爆炸性增長(zhǎng)和物聯(lián)網(wǎng)開始出現(xiàn)之時(shí),數(shù)據(jù)以指數(shù)的形式增長(zhǎng),面對(duì)著如此海量的數(shù)據(jù),過(guò)去的人們是難以想像的,而在今天,處理如此海量的數(shù)據(jù)也并非易事。面對(duì)海量數(shù)據(jù),我們首先要考慮的便是數(shù)據(jù)的存儲(chǔ)問(wèn)題,分布式存儲(chǔ)已經(jīng)是一個(gè)很好的方案,其次便是數(shù)據(jù)的計(jì)算問(wèn)題,計(jì)算必須能進(jìn)行拆分,一個(gè)大的任務(wù)能由幾個(gè)小的任務(wù)組合而成,而且不應(yīng)該是串行組合而應(yīng)該是并行組合,這樣才能使得小任務(wù)能在不同計(jì)算機(jī)中并行完成。為了更加方便快捷的利用數(shù)據(jù),最好便是能讓計(jì)算實(shí)現(xiàn)本地化,最完美的情況下即讓分布式網(wǎng)絡(luò)中的計(jì)算機(jī)都能同時(shí)處理各自計(jì)算機(jī)中的數(shù)據(jù),從而減少分布式網(wǎng)絡(luò)集群中的帶寬壓力,而最終的結(jié)果由所有的計(jì)算機(jī)計(jì)算的結(jié)果組成。于是,云計(jì)算這個(gè)概念便脫穎而出,網(wǎng)絡(luò)化快速發(fā)展已經(jīng)為云計(jì)算提供了基礎(chǔ)平臺(tái)。Hadoop作為基礎(chǔ)的云計(jì)算平臺(tái),在數(shù)據(jù)處理方面有很大的優(yōu)勢(shì)。首先,Hadoop是開源的,這允許我們根據(jù)自己的需要進(jìn)行合適的擴(kuò)展,Hadoop本身也提供了擴(kuò)展的接口。其次,Hadoop的HDFS能很好地解決分布式數(shù)據(jù)存儲(chǔ)的問(wèn)題,有一系列容錯(cuò)和優(yōu)化機(jī)制。再者,Hadoop提供的MapReduce編程模型簡(jiǎn)單又實(shí)用,有良好的可擴(kuò)展性,最重要的是,MapReduce程序本質(zhì)上是并行運(yùn)行的。在數(shù)據(jù)之中,文本數(shù)據(jù)是不容忽視的重要組成部分之一,而以Hadoop為平臺(tái)來(lái)處理海量數(shù)據(jù)有著巨大的優(yōu)勢(shì)。本設(shè)計(jì)基于這么原因,利用Hadoop來(lái)完成文本處理的目的。實(shí)現(xiàn)的主要功能:?jiǎn)卧~計(jì)數(shù)及單詞以出現(xiàn)次數(shù)排序輸出,Grep的實(shí)現(xiàn),文本的倒排索引,單詞共現(xiàn)。1.2國(guó)內(nèi)外研究狀況Hadoop起源于開源的網(wǎng)絡(luò)搜索引擎ApacheNutch,以Google公司發(fā)表的GFS文件系統(tǒng)和MapReduce系統(tǒng)為藍(lán)本構(gòu)建了Hadoop的HNFS和MapReduce。2008年1月,Hadoop已經(jīng)成為Apache的頂級(jí)項(xiàng)目,且已經(jīng)在許多大公司得到了實(shí)際應(yīng)用,例如Yahoo!和Facebook等。Hadoop開源項(xiàng)目自從推出以來(lái),經(jīng)歷了數(shù)十個(gè)版本的演進(jìn),并逐步發(fā)展成熟,成為一個(gè)包含HDFS,MapReduce,HBase,Hive,Zookeeper,Avro,Pig,Sqoop等一系列相關(guān)子項(xiàng)目的大數(shù)據(jù)處理平臺(tái)和生態(tài)系統(tǒng)。在Yahoo!的Hadoop研究集群中,Hadoop已經(jīng)分別在188個(gè)節(jié)點(diǎn),300個(gè)節(jié)點(diǎn),500個(gè)節(jié)點(diǎn),900個(gè)節(jié)點(diǎn)等進(jìn)行擴(kuò)展研究,且研究集群曾有過(guò)17個(gè)共24000個(gè)節(jié)點(diǎn)。在2009年4月,Yahoo!的Hadoop有每分鐘排序中勝出,在59秒內(nèi)GB(1400個(gè)節(jié)點(diǎn))和173分鐘內(nèi)排序100TB數(shù)據(jù)(3400個(gè)節(jié)點(diǎn))。對(duì)于節(jié)點(diǎn)數(shù)超出4000的大型集群,經(jīng)典的MapReduce系統(tǒng)(Hadoop1.X版本)也開始面臨著擴(kuò)展性的瓶頸。在2012年,Yahoo!的一個(gè)團(tuán)隊(duì)開始設(shè)計(jì)下一代的MapReduce,即YARN(YetAnotherResourceNegotiator),并且演化為Hadoop2.X版本。作為新一代的Hadoop系統(tǒng),YARN構(gòu)架將主控節(jié)點(diǎn)的資源管理和作業(yè)管理功能實(shí)現(xiàn)分離設(shè)置,并且引入了全局資源管理器和針對(duì)每個(gè)作業(yè)的應(yīng)用主控管理器,以此來(lái)減輕原主控節(jié)點(diǎn)的負(fù)擔(dān),并且YARN還可以基于Zookeeper實(shí)現(xiàn)資源管理的失效恢復(fù),以此提高了Hadoop系統(tǒng)的高可用性。YARN還引入了資源容器的概念,將系統(tǒng)計(jì)算資源統(tǒng)一劃分和封裝為許多個(gè)資源單元,而不是像經(jīng)典的MapReduce中那樣區(qū)分Map和Reduce的計(jì)算資源,以此來(lái)提高計(jì)算資源的利用率。此外,YARN還能容納MapReduce之外的其他并行計(jì)算模型和構(gòu)架,以此來(lái)提高Hadoop構(gòu)架的并行化編程的靈活性。YARN的設(shè)計(jì)使得不同的YARN應(yīng)用可以在同一個(gè)集群上共存,大大提高了可管理性和集群的利用率。目前,Hadoop已經(jīng)成為企業(yè)主流的部署系統(tǒng),也是公認(rèn)的大數(shù)據(jù)通用存儲(chǔ)和分析平臺(tái),大量直接或間接使用Hadoop系統(tǒng)的產(chǎn)品也越來(lái)越多,許多公司也分布了自己Hadoop發(fā)行版本,例如EMC,IBM等。1.3設(shè)計(jì)和研究方法本文主要從平臺(tái)搭建開始,逐步開始了解Hadoop,對(duì)HDFS和MapReduce工作機(jī)制進(jìn)行深入了解。Hadoop是以Java進(jìn)行開發(fā)的,所以本文的設(shè)計(jì)也是有Java語(yǔ)言進(jìn)行開發(fā),以文本處理為目的,對(duì)MapReduce的類型和格式進(jìn)行進(jìn)一步了解,從而對(duì)Hadoop的容錯(cuò)性和可擴(kuò)展性有進(jìn)一步的認(rèn)識(shí)。本文中對(duì)Hadoop的一部分實(shí)現(xiàn)源代碼進(jìn)行分析,從而了解一些系統(tǒng)提供的接口的實(shí)現(xiàn)和自己對(duì)系統(tǒng)的擴(kuò)展的實(shí)現(xiàn)過(guò)程。Hadoop和Java都提供了豐富的接口,所以在程序的實(shí)現(xiàn)過(guò)程中會(huì)大部分調(diào)用其提供的接口。1.4設(shè)計(jì)過(guò)程和研究?jī)?nèi)容本設(shè)計(jì)針對(duì)文本數(shù)據(jù)進(jìn)行處理,Java為文本處理提供了大量的接口實(shí)現(xiàn),例如在實(shí)現(xiàn)Grep程序過(guò)程中通過(guò)Java的Pattern類和Matcher進(jìn)行正則表達(dá)示的創(chuàng)建和匹配操作。文本處理實(shí)現(xiàn)過(guò)程中,有過(guò)許多實(shí)現(xiàn)方式,例如,在倒排索引程序?qū)崿F(xiàn)中,可以以不同的形式處理中間結(jié)果。Hadoop的版本有許多,本設(shè)計(jì)采用Hadoop1.2.1版本,以偽分布式方式,通過(guò)Cygwin模擬Linux環(huán)境在Windows7上搭建開發(fā)平臺(tái)(Linux是Hadoop的產(chǎn)品開發(fā)和運(yùn)行的平臺(tái),Win32平臺(tái)是作為開發(fā)平臺(tái)支持的,安裝Cygwin是為了提供shell支持)。設(shè)計(jì)中的所有API均為新版API,MapReduce的執(zhí)行機(jī)制為Mapreduce1(經(jīng)典MapReduce)。在程序開發(fā)過(guò)程中,使用的Java版本為jdk1.8.0_25,開發(fā)環(huán)境使用Eclipse,安裝HadoopEclipse插件(插件版本必須與Hadoop版本一致)后,使Hadoop的開發(fā)環(huán)境中嵌入Eclipse,實(shí)現(xiàn)開發(fā)環(huán)境的圖形化,降低開發(fā)的復(fù)雜度。第二章Hadoop框架2.1Hadoop構(gòu)造模塊Hadoop實(shí)現(xiàn)了分布式存儲(chǔ)和分布式計(jì)算的概念,而在一個(gè)集群上,“運(yùn)行Hadoop”意味著在集群中的節(jié)點(diǎn)之上運(yùn)行著一組守護(hù)進(jìn)程來(lái)為分布式存儲(chǔ)和分布式計(jì)算提供服務(wù)。這些守護(hù)過(guò)程有各自的特色和各自的任務(wù),即NameNode,DataNode,SecondaryNameNode,JobTracker,TaskTracker。Hadoop在分布式計(jì)算和分布式存儲(chǔ)中都采用主從結(jié)構(gòu),分布式存儲(chǔ)系統(tǒng)被稱為Hadoop文件系統(tǒng)。Hadoop有一個(gè)類似Linux虛擬文件系統(tǒng)的抽象文件系統(tǒng)概念并提供了很多接口來(lái)訪問(wèn)實(shí)際的文件系統(tǒng),目前已經(jīng)很多個(gè)具體實(shí)現(xiàn),例如Hadoop的旗艦文件系統(tǒng)HDFS。HDFS有類似磁盤的塊的概念,默認(rèn)為64MB,HDFS上的文件以塊大小劃分,作為獨(dú)立的存儲(chǔ)單元。 HDFS集群有兩類節(jié)點(diǎn),即NameNode和DataNode,它們以管理者-工作者模式運(yùn)行。NameNode是管理者,管理文件系統(tǒng)的命名空間,維護(hù)文件系統(tǒng)樹及樹中的文件和目錄(這些信息以文件形式保存在本地磁盤中:命名空間鏡像文件和編輯日志文件)。NameNode同時(shí)也記錄每個(gè)文件中的各個(gè)數(shù)據(jù)塊的節(jié)點(diǎn)信息,并保存在內(nèi)存中,并會(huì)在系統(tǒng)啟動(dòng)時(shí)則數(shù)據(jù)節(jié)點(diǎn)創(chuàng)建。DataNode是文件系統(tǒng)的工作節(jié)點(diǎn),存儲(chǔ)著數(shù)據(jù)塊信息,它需要定期向NameNode發(fā)送所存儲(chǔ)的塊的列表。在NameNode失效時(shí),文件系統(tǒng)將無(wú)法使用,而SecondaryNameNode作為一個(gè)用于監(jiān)測(cè)HDFS集群狀態(tài)的輔助守護(hù)進(jìn)程,其主要的用途就是用來(lái)保存NameNode中對(duì)HDFSmetadata的信息的備份,并減少namenode重啟的時(shí)間(NameNode和SecondaryNameNode不應(yīng)該處于同一節(jié)點(diǎn)),實(shí)現(xiàn)盡量防止數(shù)據(jù)丟失。(Hadoop的2.X發(fā)行版本中在HDFS中增加了高可用性的支持)Hadoop的分布式計(jì)算作業(yè)的控制主要由一個(gè)JobTracker和多個(gè)TaskTraker實(shí)現(xiàn)。JobTracker是應(yīng)用程序和Hadoop之間的交互紐帶,也是整個(gè)MapReduce計(jì)算框架中的主服務(wù),負(fù)責(zé)整個(gè)作業(yè)的控制和資源的管理。JobTracker在啟動(dòng)之后,會(huì)一直監(jiān)聽并接收來(lái)自整個(gè)作業(yè)中的TaskTraker發(fā)送的“心跳”信息(節(jié)點(diǎn)資源使用情況和任務(wù)運(yùn)行情況),根據(jù)這些信息,JobTraker實(shí)現(xiàn)作業(yè)控制和資源管理。TaskTraker運(yùn)行在集群中各節(jié)點(diǎn)之上,接收并執(zhí)行JobTracker的各種命令,如運(yùn)行,提交,終止任務(wù)等,同時(shí)也需要將所處的節(jié)點(diǎn)上的各個(gè)任務(wù)狀態(tài)信息周期性通過(guò)“心跳”信息的方式提交給JobTracker。2.2Hadoop平臺(tái)搭建Hadoop有三種安裝模式:?jiǎn)螜C(jī)模式,偽分布式模式,完全分布式模式。Hadoop的默認(rèn)安裝模式為單機(jī)模式(最小配置模式),可以通過(guò)配置文件(XML格式)來(lái)改變Hadoop的安裝模式,并且可以通過(guò)配置文件實(shí)現(xiàn)Hadoop的性能調(diào)優(yōu)。在本設(shè)計(jì)中,并沒(méi)有采用完全分布式模式安裝,而是將Hadoop配置為偽分布式工作模式來(lái)模擬分布式集群。在這種情況下,每一個(gè)Hadoop守護(hù)進(jìn)程都作為一個(gè)獨(dú)立的Java進(jìn)程運(yùn)行區(qū)別于單機(jī)模式下的無(wú)需運(yùn)行任何守護(hù)進(jìn)程,所有程序都在同一個(gè)JVM上運(yùn)行。安裝條件JDK(1.8.0_25),Cygwin,Hadoop1.2.1,Eclipse,Win32。安裝JDK和Cygwin先安裝JDK,配置JAVA_HOME環(huán)境變量,再在安裝Cygwin時(shí)在SelectPackages界面里,Category展開net,選擇如下openssh和openssl兩項(xiàng),如果要在Eclipe上編譯Hadoop,需要安裝Category為Base下的sed,安裝完成后,將Cygwin安裝文件夾中的bin目錄加入到系統(tǒng)環(huán)境變量PATH中。安裝sshd服務(wù)啟動(dòng)Cygwin,執(zhí)行ssh-host-config-y命令,執(zhí)行后,會(huì)提示輸入密碼,否則會(huì)退出該配置,此時(shí)輸入密碼和確認(rèn)密碼,回車。最后出現(xiàn)Hostconfigurationfinished.Havefun!表示安裝成功。配置SSH免密碼登錄輸入ssh-keygen-tdsa-P''-f~/.ssh/id_dsa(執(zhí)行ssh-keygen命令生成密鑰文件,-t表示指定生成的密鑰類型(dsa,rsa),-P表示提供的密語(yǔ),-f指定生成的密鑰文件)。執(zhí)行此命令后,在你的Cygwin\home\用戶名路徑下面會(huì)生成.ssh文件夾,可以通過(guò)命令ls-a/home/用戶名查看,執(zhí)行ssh-version命令ssh查看版本。執(zhí)行完ssh-keygen命令后,再執(zhí)行下面命令,就可以生成authorized_keys文件了。cd~/.ssh/cpid_dsa.pubauthorized_keys然后執(zhí)行exit命令,退出Cygwin窗口。再次在桌面上雙擊Cygwin圖標(biāo),打開Cygwin窗口,執(zhí)行sshlocalhost命令,第一次執(zhí)行該命令會(huì)有提示,輸入yes后,回車即可。安裝Hadoop把hadoop壓縮包(本機(jī)選擇Hadoop1.2.1版本)解壓到/home/用戶名目錄下(在本設(shè)計(jì)中,用戶名為lenovo),文件夾名稱更改為hadoop(原解壓后文件名過(guò)長(zhǎng),在shell環(huán)境下輸入不太方便,僅僅是為方便起見,可以不更改)。配置偽分布式模式可以把偽分布模式看作是只有一個(gè)節(jié)點(diǎn)的集群,在這個(gè)集群中,這個(gè)節(jié)點(diǎn)既是Master,也是Slave,既是NameNode,也是DataNode,既是JobTracker,也是TaskTracker,這種模式下修改幾個(gè)配置文件即可。配置hadoop-env.sh,以記事本打開該文件,設(shè)置JAVA_HOME的值為你的JDK安裝路徑,以本機(jī)配置為例:exportJAVA_HOME="H:\ProgramFiles\Java\jdk1.8.0_25"配置core-site.xml<configuration><property><name></name><value>hdfs://localhost:9000</value></property></configuration>配置hdfs-site.xml<configuration><property><name>dfs.replication</name><value>1</value></property></configuration>配置mapred-site.xml<configuration><property><name>mapred.job.tracker</name><value>localhost:9001</value></property></configuration>啟動(dòng)Hadoop打開Cgywin窗口,執(zhí)行cd~/hadoop命令,進(jìn)入hadoop文件夾,啟動(dòng)Hadoop前,需要先格式化Hadoop的文件系統(tǒng)HDFS,執(zhí)行命令:bin/hadoopnamenode-format,輸入命令bin/start-all.sh,啟動(dòng)所有進(jìn)程。驗(yàn)證是否安裝成功打開瀏覽器,分別輸入下列網(wǎng)址,如果能夠正常瀏覽,說(shuō)明安裝成功。http://localhost:50030,回車打開MapReduce的web頁(yè)面。http://localhost:50070,回車打開HDFS的web頁(yè)面。至此Hadoop環(huán)境已經(jīng)配置完成,在Cygwin環(huán)境中也已經(jīng)可以進(jìn)行開發(fā),為了能更加方便快捷地使用IDE開發(fā)Hadoop,選擇利用Eclipse的Hadoop插件。在安裝插件,配置Hadoop的相關(guān)信息之后,如果創(chuàng)建Hadoop程序,插件會(huì)自動(dòng)導(dǎo)入Hadoop編程接口的JAR文件,這樣用戶就可以在Eclipse的圖形化界面中編寫、調(diào)試、運(yùn)行Hadoop程序(包括單機(jī)程序和分布式程序),也可以在其中查看自己程序的實(shí)時(shí)狀態(tài)、錯(cuò)誤信息和運(yùn)行結(jié)果,還可以查看、管理HDFS以及文件(上傳本地文件和下載HDFS文件不再需要通過(guò)shell來(lái)進(jìn)行,更加方便)。配置Eclipse開發(fā)環(huán)境首先在網(wǎng)上下載已經(jīng)修改過(guò)Hadoop源碼的hadoop-eclipse-1.2.1插件jar包(Windows文件權(quán)限問(wèn)題會(huì)導(dǎo)致報(bào)錯(cuò),Linux下不存在這個(gè)問(wèn)題,也可以自行編譯插件,但需要對(duì)hadoop\src\core\org\apache\hadoop\fs\下的FileUtil.java進(jìn)行更改,注釋掉checkReturnValue函數(shù)的中代碼),放置在eclipse/plugins目錄下,并重啟eclipse,在eclipse的右上角應(yīng)該出現(xiàn)了一只藍(lán)色的大象logo,點(diǎn)擊之后,在正下方的區(qū)域?qū)?huì)多出一項(xiàng)Map/ReduceLocations,點(diǎn)擊NewHadoopLocation,需要填寫以下內(nèi)容:Locationname(當(dāng)前創(chuàng)建的鏈接名字,可以任意指定)Map/ReduceMaster(執(zhí)行MR的主機(jī)地址,本機(jī)host:localhost,port:9001)DFSMaster(DistributionFileSystem的主機(jī)地址,本機(jī)host:localhost,port:9000)(host和port與之前的配置文件相關(guān))Username(鏈接至Hadoop的用戶名,本機(jī)為lenovo)至此,Hadoop開發(fā)環(huán)境已經(jīng)搭建完成。2.3HDFS對(duì)每一個(gè)系統(tǒng)來(lái)說(shuō),文件系統(tǒng)始終扮演著非常重要的角色。在Linux操作系統(tǒng)中,Linux可以支持許多種磁盤文件系統(tǒng),原因就是Linux在實(shí)際文件系統(tǒng)之上又抽象出一層虛擬文件系統(tǒng)的概念,虛擬文件系統(tǒng)提供統(tǒng)一的接口,而實(shí)地的文件系統(tǒng)只需要實(shí)現(xiàn)各自的接口即可。Hadoop也有類似的一個(gè)綜合性的文件系統(tǒng)抽象,而在眾多的Hadoop文件系統(tǒng)中,HDFS是Hadoop的旗艦級(jí)文件系統(tǒng),且被設(shè)計(jì)成與MapReduce結(jié)合使用時(shí)可以實(shí)現(xiàn)高性能。2.3.1HDFS的設(shè)計(jì)HDFS的設(shè)計(jì)理念是一個(gè)面向大規(guī)模數(shù)據(jù)密集型應(yīng)用的、可伸縮的分布式文件系統(tǒng)。首先,HDFS面向的文件數(shù)據(jù)體積非常大,文件分布在整個(gè)集群的多臺(tái)計(jì)算機(jī)中(也有可能擴(kuò)展分布到多個(gè)集群中)。其次,HDFS假設(shè)數(shù)據(jù)失效為常態(tài),例如應(yīng)用程序或操作系統(tǒng)的bug,操作人員的失誤,硬件的出錯(cuò)。HDFS存儲(chǔ)超大文件是以流式數(shù)據(jù)訪問(wèn)的模式,即一次寫入,多次讀取是效率最高的訪問(wèn)模式。HDFS中的文件可能只有一個(gè)寫入者,而且寫操作只能只追加數(shù)據(jù)的方式添加在文件末尾,并不支持多個(gè)寫入者或在任意位置進(jìn)行修改。HDFS的設(shè)計(jì)主要是針對(duì)高數(shù)據(jù)吞吐量應(yīng)用而進(jìn)行優(yōu)化,所以要求時(shí)間延遲低的數(shù)據(jù)訪問(wèn)方式的應(yīng)用并不適合在HDFS上運(yùn)行。Hadoop的設(shè)計(jì)之初便是面向商用硬件,因此,對(duì)于龐大的集群來(lái)說(shuō),節(jié)點(diǎn)故障的概率還是不容忽視,HDFS被設(shè)計(jì)成在遇到節(jié)點(diǎn)故障之時(shí)仍能繼續(xù)運(yùn)行肯不能讓用戶察覺(jué)到有明顯的中斷。還有一個(gè)重要的因素便是所存儲(chǔ)的文件的大小,因?yàn)镹ameNode將文件系統(tǒng)的metadata存儲(chǔ)在內(nèi)存中,即在文件文件數(shù)量太多時(shí),內(nèi)存便成為存儲(chǔ)數(shù)據(jù)的瓶頸。HDFS中的文件被劃分為塊,并以塊為獨(dú)立的存儲(chǔ)單元(HDFS中小于塊的文件不會(huì)占據(jù)整個(gè)塊的空間)。塊大小默認(rèn)為64MB,主要是為了減小尋址開銷,使用塊而不是整個(gè)文件作為數(shù)據(jù)的基本存儲(chǔ)單元在很大程度上簡(jiǎn)化了存儲(chǔ)子系統(tǒng)的設(shè)計(jì)。在HDFS中,每個(gè)塊的副本數(shù)默認(rèn)為3個(gè),這為HDFS提供了數(shù)據(jù)容錯(cuò)能力和提高了可用性。副本的存放是HDFS可靠性和提升性能的關(guān)鍵。HDFS采用機(jī)架感知策略來(lái)改進(jìn)數(shù)據(jù)的可靠性,可用性和網(wǎng)絡(luò)帶寬的利用率,即一個(gè)副本存放在本地機(jī)架的節(jié)點(diǎn)了,另一個(gè)放在同一機(jī)架的另一個(gè)節(jié)點(diǎn)上,第三個(gè)放在不同機(jī)架的節(jié)點(diǎn)上。在讀取數(shù)據(jù),HDFS會(huì)盡量讀取離客戶端最近的副本,從而降低帶寬延遲和節(jié)省網(wǎng)絡(luò)帶寬資源。另一方面,SecondaryNameNode機(jī)制也為NameNode宕機(jī)時(shí)的減少文件的損失作出替補(bǔ)作用(但這也必然會(huì)在一定程序上損失數(shù)據(jù),SecondaryNameNode的同步備份總是有個(gè)滯后時(shí)間)。2.3.2HDFS的數(shù)據(jù)流Hadoop文件系統(tǒng)支持類似Linux文件系統(tǒng)的系統(tǒng)調(diào)用,客戶端通過(guò)文件系統(tǒng)API實(shí)現(xiàn)對(duì)HDFS中的數(shù)據(jù)的讀取和寫入??蛻舳俗x取HDFS中的數(shù)據(jù):圖2.1客戶端讀取HDFS中的數(shù)據(jù)客戶端將數(shù)據(jù)寫入HDFS:圖2.2客戶端將數(shù)據(jù)寫入HDFS2.3.3序列化與反序列化序列化指的將結(jié)構(gòu)化對(duì)象轉(zhuǎn)化為字節(jié)流以便在網(wǎng)絡(luò)上傳輸或?qū)懭氲酱疟P的過(guò)程,反序列化為序列化的逆過(guò)程。序列化常用于分布式數(shù)據(jù)處理的進(jìn)程間通信和永久存儲(chǔ)中。在Hadoop中,集群中各個(gè)節(jié)點(diǎn)間進(jìn)程間的通信是通過(guò)RPC實(shí)現(xiàn)的。RPC協(xié)議將消息序列化為二進(jìn)制格式后發(fā)送至過(guò)程節(jié)點(diǎn),遠(yuǎn)程節(jié)點(diǎn)反序列化后還原為原始數(shù)據(jù)。Hadoop使用自己的序列化格式Writable,Writable是Hadoop的核心,絕大多數(shù)的MapReuce程序的鍵和值使用Hadoop自帶的Writable類型(已經(jīng)經(jīng)過(guò)很好的性能調(diào)優(yōu)),但是,有時(shí)為了根據(jù)自己的需要,再好地調(diào)整結(jié)構(gòu),可以實(shí)現(xiàn)自己的Writable類型(通過(guò)Hadoop提供的接口實(shí)現(xiàn))。在通用的幾個(gè)Writable實(shí)現(xiàn)中,LongWritable對(duì)應(yīng)long類型,Text類似于String,IntWritable對(duì)應(yīng)于int型。2.4MapReduceMapReduce是Hadoop中的編程模型。MapReduce任務(wù)分為兩個(gè)處理階段:map階段和reduce階段。每個(gè)階段都以鍵值對(duì)作為函數(shù)的輸入和輸出,類型可以自行選擇。在通常的Hadoop程序開發(fā)中,我們往往只需要編寫map函數(shù)和reduce函數(shù)即可,其他的可調(diào)用Hadoop提供的接口實(shí)現(xiàn)。2.4.1MapReduce工作機(jī)制在經(jīng)典MapReduce中,一個(gè)作業(yè)的運(yùn)行包含四個(gè)獨(dú)立的實(shí)體??蛻舳耍河糜谔峤籑apReduce作業(yè)。JobTracker:協(xié)調(diào)作業(yè)的運(yùn)行。TaskTracker:運(yùn)行作業(yè)劃分之后任務(wù)。分布式文件系統(tǒng):通常為HDFS,用于共享作業(yè)文件。整個(gè)MapRedece作業(yè)的執(zhí)行過(guò)程可由以下幾個(gè)部分組成:作業(yè)的提交過(guò)程向JobTracker請(qǐng)求新的作業(yè)ID,檢查作業(yè)的輸出說(shuō)明,計(jì)算作業(yè)的輸入分片,將運(yùn)行作業(yè)所需要的資源(作業(yè)JAR文件,配置文件,輸入分片)復(fù)制到以作業(yè)ID命名的目錄下JobTracker的分布式文件系統(tǒng)中(通常為HDFS),通知JobTracker作業(yè)準(zhǔn)備開始執(zhí)行。作業(yè)的初始化初始化的主要工作是構(gòu)造map任務(wù)和reduce任務(wù)并對(duì)它們進(jìn)行初始化。JobTracker中的作業(yè)隊(duì)列由作業(yè)調(diào)度器進(jìn)行調(diào)度(一般為基于隊(duì)列的FIFO調(diào)度器),作業(yè)調(diào)度器會(huì)從分布式文件系統(tǒng)中獲取輸入分片信息(每個(gè)分片對(duì)應(yīng)一個(gè)Map任務(wù),reduce任務(wù)的數(shù)量由配置文件中的參數(shù)決定,在偽分布式情況下,數(shù)量默認(rèn)為1,reduce任務(wù)的數(shù)量也是性能調(diào)優(yōu)的一個(gè)重要方面)。除此之外,一般還會(huì)創(chuàng)建兩個(gè)任務(wù):作業(yè)創(chuàng)建和作業(yè)清理,這兩個(gè)任務(wù)在TaskTracker中執(zhí)行。任務(wù)的分配TaskTracker通過(guò)循環(huán)方式定期向JobTracker發(fā)送“心跳”信息(節(jié)點(diǎn)資源使用情況和任務(wù)運(yùn)行情況),根據(jù)“心跳”,JobTracker判斷TaskTracker是否存活,并通過(guò)這個(gè)信息為它分配一個(gè)任務(wù)。任務(wù)的執(zhí)行首先,需要從分布式文件系統(tǒng)中把作業(yè)JAR文件復(fù)制到TaskTracker所在的文件系統(tǒng),實(shí)現(xiàn)JAR文件的本地化。然后,TaskTracker需要為任務(wù)新建一個(gè)本地工作目錄,再把JAR文件解壓到此文件夾中。最后,啟動(dòng)一個(gè)新的Java虛擬機(jī)來(lái)運(yùn)行每個(gè)任務(wù)(一般情況下,可以在不同的任務(wù)之間重用JVM)。任務(wù)之間是并行執(zhí)行的,而整個(gè)作業(yè)的執(zhí)行必須依賴于各個(gè)并行執(zhí)行的任務(wù),只要其中有一個(gè)任務(wù)出錯(cuò)或者執(zhí)行緩慢必將影響整個(gè)作業(yè)的執(zhí)行進(jìn)度,因此必須采取某種機(jī)制來(lái)處理這種情況的發(fā)生,Hadoop采用一種“推測(cè)執(zhí)行”的機(jī)制來(lái)處理。在實(shí)際應(yīng)用情況中,任務(wù)執(zhí)行緩慢的原因可能有很多,例如硬件老化或者軟件配置出錯(cuò)等等,想要檢測(cè)出具體的原因十分困難,所以Hadoop采取的機(jī)制并不會(huì)嘗試去診斷或者修復(fù)執(zhí)行緩慢的任務(wù),相反,在一個(gè)任務(wù)運(yùn)行得較為緩慢的時(shí)候,它會(huì)盡量檢測(cè),同時(shí)會(huì)啟動(dòng)另一個(gè)相同的任務(wù)作為備份。進(jìn)度和狀態(tài)的更新在MapReuce作業(yè)運(yùn)行期間,必須對(duì)任務(wù)的進(jìn)度進(jìn)行追蹤,以確保該任務(wù)還在運(yùn)行,如果出現(xiàn)意外已經(jīng)停止運(yùn)行,則必須重新啟動(dòng)一個(gè)新的任務(wù)。任務(wù)中有一組計(jì)數(shù)器,負(fù)責(zé)對(duì)任務(wù)運(yùn)行過(guò)程中的各個(gè)階段進(jìn)行計(jì)數(shù),以此為來(lái)構(gòu)成進(jìn)度。作業(yè)的完成JobTracker在接收到作業(yè)的最后一個(gè)任務(wù)已經(jīng)完成的通知后,便把作業(yè)的狀態(tài)設(shè)置為成功,作業(yè)的統(tǒng)計(jì)信息和計(jì)數(shù)值隨后輸出到控制臺(tái)。最后是一些清理工作,如清空作業(yè)的工作狀態(tài),刪除中間的輸出等。MapReduce框架的輸入和輸出都是鍵值對(duì),map任務(wù)的輸出作為reduce任務(wù)的輸入,但是map的輸出并不是直接傳遞給reduce,而是經(jīng)過(guò)按鍵排序,整個(gè)流程大致如下:圖2.3MapReduce數(shù)據(jù)輸入輸出過(guò)程mapper輸出先寫入到內(nèi)存緩沖區(qū)中(緩沖區(qū)默認(rèn)為100MB),當(dāng)緩沖區(qū)中的數(shù)據(jù)達(dá)到一定的數(shù)量時(shí)(默認(rèn)為80%),后臺(tái)線程便會(huì)把數(shù)據(jù)寫到磁盤中。在寫入到磁盤之前,數(shù)據(jù)將根據(jù)要被傳送到的reducer劃分成相對(duì)應(yīng)的分區(qū),在每個(gè)分區(qū)中,數(shù)據(jù)按照鍵來(lái)進(jìn)行排序。如果有combiner時(shí),它會(huì)在排序的輸出后運(yùn)行(combiner函數(shù)處理map函數(shù)的輸出,產(chǎn)生的結(jié)果作為reduce函數(shù)的輸入,目的是為了減少map函數(shù)輸出的數(shù)據(jù)以減少寫入到磁盤的數(shù)據(jù)同時(shí)也節(jié)約網(wǎng)絡(luò)帶寬資源,一般情況下combiner函數(shù)可以等同于reduce函數(shù),也可以自定義,但要保證在有combiner的情況下,最終結(jié)果不會(huì)有不同),reducer通過(guò)HTTP協(xié)議得到輸出文件的分區(qū)信息。在map階段,對(duì)輸入分片中的每條記錄循環(huán)調(diào)用map函數(shù)。在reduce部分,reduce任務(wù)需要多個(gè)map任務(wù)的輸出作為它的分區(qū)文件,它并不會(huì)等所有的map任務(wù)都完成,一旦有一個(gè)任務(wù)完成,它就開始復(fù)制其輸出。分區(qū)的選擇主要依靠mapper輸出的鍵,可以自定義partitioner(默認(rèn)的分區(qū)方式是哈希方式),以達(dá)到自己的要求。在reduce階段,對(duì)已排序輸出的每個(gè)鍵調(diào)用reduce函數(shù)。2.4.2MapReduce中的類型與格式關(guān)于輸入輸出,reduce函數(shù)的數(shù)據(jù)輸入類型必須等于map函數(shù)的輸出類型。一個(gè)map任務(wù)只處理一個(gè)輸入分片,在默認(rèn)情況下,輸入分片的大小等同與文件塊的大小,每個(gè)輸入分片都被劃分為若干條記錄,每條記錄對(duì)就一個(gè)鍵值對(duì),map函數(shù)每次處理一條記錄,直至輸入分片處理完成。輸入分片和記錄僅僅是邏輯概念,在數(shù)據(jù)的存儲(chǔ)上,還是以塊的方式。對(duì)于記錄中的鍵和值,不同的輸入類型有不同的解釋方式,對(duì)于默認(rèn)的文本輸入而言,每條記錄為輸入的一行,鍵是該在整個(gè)文件中的字節(jié)偏移量,值是該行的文本內(nèi)容(不包括終止符)。輸出類型與輸入類型類似,可以自定義輸入輸出類型和鍵值。2.5Hadoop性能調(diào)優(yōu)在整個(gè)Hadoop系統(tǒng)中,我們有很大的選擇權(quán),有很多的配置可以由用戶自行設(shè)置,針對(duì)不同的情況選擇合適的配置是十分關(guān)鍵的一步,也充分體現(xiàn)了Hadoop的適應(yīng)性。Hadoop的性能與很多方面有關(guān),不僅與自身參數(shù)配置有關(guān),還涉及底層硬件,操作系統(tǒng)和Java虛擬機(jī)等,在這里的性能調(diào)優(yōu)是針對(duì)Hadoop系統(tǒng)本身而言。在應(yīng)用中,應(yīng)該考慮實(shí)際情況,對(duì)參數(shù)進(jìn)行配置,例如map任務(wù)緩沖區(qū)占內(nèi)存的大小,緩沖區(qū)內(nèi)存“溢出”比例多少,選擇是否對(duì)map任務(wù)的輸出進(jìn)行壓縮(如果采用壓縮時(shí),應(yīng)該選擇哪一種壓縮策略),還有一些有關(guān)內(nèi)存使用的參數(shù)和設(shè)置線程數(shù)目的參數(shù),可以根據(jù)應(yīng)用情況,動(dòng)態(tài)調(diào)整。1.資源的規(guī)劃Hadoop的計(jì)算資源以槽(slot)來(lái)表示,分為map槽和reduce槽,通過(guò)為TaskTracker配置槽數(shù)目,從而控制TaskTracker上并發(fā)執(zhí)行的map任務(wù)和reduce任務(wù)數(shù)目。2.調(diào)整“心跳”配置“心跳”的間隔對(duì)性能有著不小的影響,時(shí)間間隔過(guò)小時(shí),JobTracker需要處理高并發(fā)的“心跳”信息,給JobTracker造成不小的壓力,間隔過(guò)大時(shí),空閑的資源信息不能及時(shí)匯報(bào)給JobTracke,造成資源的浪費(fèi),同時(shí)也降低了系統(tǒng)整體的吞吐率,影響系統(tǒng)性能。在實(shí)際情況中,根據(jù)集群中節(jié)點(diǎn)數(shù)的不同,“心跳”的間隔有很大的差異,一般來(lái)說(shuō),小規(guī)模的集群間隔也設(shè)置的小。3.磁盤塊配置這里的磁盤塊并不是指文件系統(tǒng)中的塊,而是本地磁盤,map任務(wù)的輸出要寫入到磁盤中,而對(duì)于輸入輸出密集型的任務(wù)來(lái)說(shuō),這會(huì)給本地磁盤造成很大的壓力,而這里的配置指的就是在有多個(gè)磁盤存在的情況下,Hadoop將采用輪詢的方式將map任務(wù)的輸出結(jié)果寫入到多個(gè)磁盤中,以負(fù)載均衡的方式提高系統(tǒng)性能。4.任務(wù)調(diào)度優(yōu)化作為Hadoop的核心組件之一,調(diào)度器負(fù)責(zé)將系統(tǒng)中空閑的資源分配給各個(gè)任務(wù),調(diào)度器的調(diào)度效率直接影響系統(tǒng)的吞吐率,每個(gè)作業(yè)都有分配有優(yōu)先級(jí),默認(rèn)的調(diào)度器采用的是FIFO調(diào)度器(并不支持搶占),Hadoop中還有兩個(gè)多用戶調(diào)度器:公平調(diào)試器(支持搶占)和容量調(diào)試器。在只有一個(gè)作業(yè)運(yùn)行的情況下,作業(yè)會(huì)得到整個(gè)集群的所有資源,在多個(gè)用戶的情況下,每個(gè)用戶有自己的作業(yè)池,因此作業(yè)多的用戶也并不會(huì)獲得更多的集群資源。為了將所有的空閑資源盡可能得分配給任務(wù),三種調(diào)試器都支持批量任務(wù)調(diào)試功能(FIFO調(diào)試器只支持批量調(diào)試),而不是一次只分配一個(gè),通過(guò)配置參數(shù)可以改變?nèi)蝿?wù)調(diào)試方式。第三章文本處理Hadoop非常適合于處理非結(jié)構(gòu)化的文本數(shù)據(jù),Hadoop本身提供了大量的文本處理的接口和實(shí)現(xiàn),所以,在實(shí)現(xiàn)文本處理的過(guò)程中,大部分都調(diào)用接口實(shí)現(xiàn),只有在沒(méi)有提供合適的接口時(shí),才自己實(shí)現(xiàn)。在Hadoop的編程模型中,一般來(lái)說(shuō),我們只需實(shí)現(xiàn)map函數(shù)和reduce函數(shù),在新版API中,使用虛類來(lái)代替舊版中的接口,所以在實(shí)際的程序中,只需要繼承Mapper類與Reducer類,在中實(shí)現(xiàn)map函數(shù)和reduce函數(shù)即可。3.1輸入文件內(nèi)容及輸入輸出文件路徑文件輸入路徑:hdfs://localhost:9000/user/lenovo/input,其中input目錄下有兩個(gè)文件,分別為word1.txt,word2.txt,文件內(nèi)容如下。word1.txt:ApacheHadoop

isan

open-source

softwareframework

writtenin

Java

for

distributedstorage

and

distributedprocessingofverylargedatasetson

computerclusters

builtfrom

commodityhardware.AllthemodulesinHadooparedesignedwithafundamentalassumptionthathardwarefailures(ofindividualmachines,orracksofmachines)arecommonplaceandthusshouldbeautomaticallyhandledinsoftwarebytheframework.ThecoreofApacheHadoopconsistsofastoragepart(HadoopDistributedFileSystem(HDFS))andaprocessingpart(MapReduce).Hadoopsplitsfilesintolargeblocksanddistributesthemamongstthenodesinthecluster.Toprocessthedata,HadoopMapReducetransfers

packagedcode

fornodestoprocessinparallel,basedonthedataeachnodeneedstoprocess.Thisapproachtakesadvantageofdatalocality[3]—nodesmanipulatingthedatathattheyhaveonhand—toallowthedatatobe

processed

fasterandmoreefficientlythanitwouldbeinamoreconventional

supercomputerarchitecturethatreliesona

parallelfilesystem

wherecomputationanddataareconnectedviahigh-speednetworking.[4]ThebaseApacheHadoopframeworkiscomposedofthefollowingmodules:HadoopCommon

–containslibrariesandutilitiesneededbyotherHadoopmodules;HadoopDistributedFileSystem(HDFS)

–adistributedfile-systemthatstoresdataoncommoditymachines,providingveryhighaggregatebandwidthacrossthecluster;HadoopYARN

–aresource-managementplatformresponsibleformanagingcomputingresourcesinclustersandusingthemforschedulingofusers'applications;[5][6]

andHadoopMapReduce

–aprogrammingmodelforlargescaledataprocessing.Theterm"Hadoop"hascometorefernotjusttothebasemodulesabove,butalsotothe"ecosystem",[7]

orcollectionofadditionalsoftwarepackagesthatcanbeinstalledontopoforalongsideHadoop,suchas

ApachePig,

ApacheHive,

ApacheHBase,

ApacheSpark,andothers.[8][9]ApacheHadoop'sMapReduceandHDFScomponentswereinspiredby

Google

papersontheir

MapReduce

and

GoogleFileSystem.[10]TheHadoopframeworkitselfismostlywrittenintheJavaprogramminglanguage,withsomenativecodein

C

andcommandlineutilitieswrittenas

Shellscript.Forend-users,thoughMapReduceJavacodeiscommon,anyprogramminglanguagecanbeusedwith"HadoopStreaming"toimplementthe"map"and"reduce"partsoftheuser'sprogram.[11]

Otherrelatedprojectsexposeotherhigher-leveluserinterfaces.ProminentcorporateusersofHadoopincludeFacebookandYahoo.Itcanbedeployedintraditionalon-sitedatacentersbuthasalsobeenimplementedinpubliccloudspacessuchas

MicrosoftAzure,

AmazonWebServices,

GoogleAppEngine

andIBM

Bluemix.word2.txt:Java

isageneral-purpose

computerprogramminglanguage

thatis

concurrent,

class-based,

object-oriented,[12]

andspecificallydesignedtohaveasfewimplementationdependenciesaspossible.Itisintendedtoletapplicationdevelopers"writeonce,runanywhere"(WORA),[13]

meaningthat

compiled

JavacodecanrunonallplatformsthatsupportJavawithouttheneedforrecompilation.[14]

Javaapplicationsaretypicallycompiledto

bytecode

thatcanrunonanyJavavirtualmachine

(JVM)regardlessof

computerarchitecture.Asof2015,Javaisoneofthemost

popularprogramminglanguagesinuse,[15][16][17][18]

particularlyforclient-serverwebapplications,withareported9milliondevelopers.[citationneeded]

Javawasoriginallydevelopedby

JamesGosling

at

SunMicrosystems

(whichhassincebeenacquiredbyOracleCorporation)andreleasedin1995asacorecomponentofSunMicrosystems'

Javaplatform.Thelanguagederivesmuchofits

syntax

from

C

and

C++,butithasfewer

low-level

facilitiesthaneitherofthem.Theoriginaland

referenceimplementation

Java

compilers,virtualmachines,and

classlibraries

wereoriginallyreleasedbySununderproprietarylicences.AsofMay2007,incompliancewiththespecificationsofthe

JavaCommunityProcess,SunrelicensedmostofitsJavatechnologiesunderthe

GNUGeneralPublicLicense.OthershavealsodevelopedalternativeimplementationsoftheseSuntechnologies,suchasthe

GNUCompilerforJava

(bytecodecompiler),

GNUClasspath

(standardlibraries),and

IcedTea-Web(browserpluginforapplets).文件的輸出路徑根據(jù)不同的程序不同,但它們?cè)谕粋€(gè)目錄下:hdfs://localhost:9000/user/lenovo/output.以單詞共現(xiàn)為例,其輸出文件的路徑:hdfs://localhost:9000/user/lenovo/output/WordConcurrence.由于輸出的文件內(nèi)容比較,在這里只顯現(xiàn)少量數(shù)據(jù)來(lái)說(shuō)明結(jié)果??刂婆_(tái)輸出顯示了作業(yè)的完成過(guò)程,由于使用的輸入文件相同,故此以其中的一個(gè)智育的控制臺(tái)輸出為例進(jìn)行說(shuō)明,其中略去時(shí)間戳信息。INFOinput.FileInputFormat:Totalinputpathstoprocess:2默認(rèn)會(huì)讀取輸入路徑input目錄下的所有文件。INFOmapred.JobClient:Runningjob:job_local662749720_0001每個(gè)作業(yè)都會(huì)分配一個(gè)JobID來(lái)標(biāo)識(shí),JobClient為客戶端與作業(yè)的通信中間件。INFOmapred.LocalJobRunner:WaitingformaptasksINFOmapred.LocalJobRunner:Startingtask:attempt_local662749720_0001_m_000000_0等待map任務(wù)進(jìn)行,每個(gè)map任務(wù)都有一個(gè)ID號(hào)。INFOmapred.MapTask:Processingsplit:hdfs://localhost:9000/user/lenovo/input/word1.txt:0+2861輸入分片信息,此為第一個(gè)分片,默認(rèn)每個(gè)輸入文件為一個(gè)分片,列出輸入文件路徑和偏移量信息。INFOmapred.MapTask:io.sort.mb=100INFOmapred.MapTask:databuffer=79691776/99614720INFOmapred.MapTask:recordbuffer=262144/327680默認(rèn)的內(nèi)存緩沖區(qū)大小為100MB,數(shù)據(jù)緩沖和記錄緩沖的使用情況。INFOmapred.MapTask:Processingsplit:hdfs://localhost:9000/user/lenovo/input/word2.txt:0+1641INFOmapred.MapTask:io.sort.mb=100INFOmapred.MapTask:databuffer=79691776/99614720INFOmapred.MapTask:recordbuffer=262144/327680第二個(gè)map任務(wù)的輸入信息情況。INFOmapred.JobClient:map100%reduce0%INFOmapred.Merger:Merging2sortedsegmentsmap任務(wù)完成,開始reduce任務(wù)之前,進(jìn)行合并。INFOmapred.LocalJobRunner:reduce>reduceINFOmapred.Task:Task'attempt_local662749720_0001_r_000000_0'done.INFOmapred.JobClient:map100%reduce100%在有combiner的情況下,先進(jìn)行combine,再進(jìn)行reduce操作。INFOmapred.JobClient:Jobcomplete:job_local662749720_0001作業(yè)完成。隨后會(huì)打印出許多信息,如輸入輸出分片,記錄使用,堆棧使用等,可根據(jù)此調(diào)整系統(tǒng)性能。如果有多個(gè)MapReduce作業(yè),會(huì)將以上的輸出作為輸入,重新將上述過(guò)程執(zhí)行一遍。3.2單詞計(jì)數(shù)一般情況下,只需要定義一個(gè)map過(guò)程和一個(gè)reduce過(guò)程即可,在單詞計(jì)數(shù)中,輸入類型為<LongWritable,Text>,中間輸出類型是<Text,>,輸出類型為<Text,>,在默認(rèn)情況下,reducer的輸出也會(huì)以鍵排序后輸出,如果需要以<,Text>格式輸出,則必須在reducer之后再加上一個(gè)mapper,使得鍵與值調(diào)換位置,即實(shí)現(xiàn)組合式MapReduce計(jì)算任務(wù)。Hadoop中,數(shù)據(jù)的輸入和輸出都需要指定文件路徑,組合式計(jì)算任務(wù)中,可以通過(guò)臨時(shí)文件的方式存儲(chǔ)中間輸出結(jié)果,在計(jì)算任務(wù)結(jié)束以后再刪除臨時(shí)文件即可。在具體的實(shí)現(xiàn)中,可以利用Hadoop中已經(jīng)有的類實(shí)現(xiàn)。輸出內(nèi)容:1 "Hadoop1 "Hadoop"1 "ecosystem",[7]

or1 "map"1 "reduce"1 "write1 (HDFS))1 (HDFS)

–1 (Hadoop1 (MapReduce).1 (WORA),[13]

meaning1 (browser1 (of1 19951 2007,1 2015,1 91 All1 App3.3Grep實(shí)現(xiàn)Grep是一個(gè)功能強(qiáng)大的文本檢索工具,它使用正則表達(dá)式 來(lái)搜索文本(正則表達(dá)式使用單個(gè)字符串來(lái)描述、匹配一系列符合某個(gè)句法規(guī)則的字符串),本設(shè)計(jì)的主要目標(biāo)是實(shí)現(xiàn)一具簡(jiǎn)單的分布式Grep,對(duì)輸入的文件進(jìn)行逐行的正則匹配,如果匹配成功,則輸出對(duì)應(yīng)的內(nèi)容并且輸出該內(nèi)容在整個(gè)文件中出現(xiàn)的次數(shù)。命令行參數(shù)輸入依次為輸入文件路徑,輸出文件路徑,字符串,group值。本次實(shí)現(xiàn)中,無(wú)論輸入的group值為多少都處理作0。利用Java進(jìn)行開發(fā)的一大好處是它有大量的類實(shí)現(xiàn),Java正則表達(dá)式通過(guò)java.util.regex包下的Pattern類與Matcher類實(shí)現(xiàn)。Pattern類用于創(chuàng)建正則表達(dá)式和實(shí)現(xiàn)簡(jiǎn)單的匹配操作,Matcher類實(shí)現(xiàn)分組支持和多次匹配支持。大致的構(gòu)造構(gòu)架如下所示:Patternp=Ppile(“\\d+”);Mattcherm=p.matcher(“22abc33”);在本設(shè)計(jì)中,關(guān)鍵要解決的問(wèn)題是如何將輸入的字符串參數(shù)和group值傳遞給map任務(wù),本設(shè)計(jì)的實(shí)現(xiàn)是構(gòu)造兩個(gè)配置參數(shù)用來(lái)存儲(chǔ)這兩個(gè)輸入?yún)?shù),在mapper的初始化中(mapper中的setup函數(shù),總是在map函數(shù)之前運(yùn)行,且只在初始化時(shí)運(yùn)行一次)提取這兩個(gè)參數(shù),以配置信息的方式實(shí)現(xiàn)通信。輸入:"Hadoop"輸出:18 Hadoop輸入:"/^\s*$/"輸出:輸出為空,因?yàn)椴淮嬖诳招休斎耄?\d"輸出:12 12 32 42 62 83 23 74 04 54 93.4文檔倒排索引文檔倒排索引應(yīng)用十分廣泛,幾乎所有支持全文檢索的搜索引擎都會(huì)應(yīng)用到。倒排索引存儲(chǔ)某個(gè)單詞或詞組在一個(gè)文檔或一組文檔中存儲(chǔ)位置的映射,即可以通過(guò)文本的內(nèi)容來(lái)查找對(duì)應(yīng)的文檔。在本設(shè)計(jì)的倒排索引附帶詞頻屬性,主要功能是在實(shí)現(xiàn)單詞的倒排索引的同時(shí),統(tǒng)計(jì)出單詞在各自的文檔中出現(xiàn)的次數(shù)。在實(shí)際應(yīng)用中,索引的單詞對(duì)象會(huì)除去一些沒(méi)有必要實(shí)現(xiàn)的單詞,如is,of之類,在實(shí)現(xiàn)中可以采用分布式緩存的機(jī)制,但是很遺憾,在本設(shè)計(jì)中未能實(shí)現(xiàn)。在應(yīng)用中,為了減少map任務(wù)的輸出數(shù)據(jù)傳輸,這里定義了combiner函數(shù)來(lái)對(duì)mapper端的數(shù)據(jù)進(jìn)行歸約。在具體分析如何實(shí)現(xiàn)時(shí),可以采用多種方案,以下以鍵值對(duì)的形式說(shuō)明對(duì)應(yīng)的類設(shè)計(jì)的輸出結(jié)果(輸入都是默認(rèn)的文本輸入方式,鍵和值分別為該行在文件中的偏移量和該行內(nèi)容)。方案一mapper輸出: <word,doc> //LongWritable,Textcombiner輸出: <word,doc#num> //Text,Textreducer輸出: <word,doc1#num1,...> //Text,Text方案二mapper輸出: <word#doc,1> //Text,IntWritablecombiner輸出: <word#doc,num> //Text,IntWritablereducer輸出: <word,doc1#num1,...> //Text,Text在本設(shè)計(jì)中,具體實(shí)現(xiàn)采用的是方案二,輸出內(nèi)容如下:"ecosystem",[7]

or <word1.txt,1>;<total,1>."hadoop" <word1.txt,1>;<total,1>."hadoop <word1.txt,1>;<total,1>."map" <word1.txt,1>;<total,1>."reduce" <word1.txt,1>;<total,1>."write <word2.txt,1>;<total,1>.(browser <word2.txt,1>;<total,1>.(hadoop <word1.txt,1>;<total,1>.(hdfs)) <word1.txt,1>;<total,1>.(hdfs)

– <word1.txt,1>;<total,1>.(mapreduce). <word1.txt,1>;<total,1>.(of <word1.txt,1>;<total,1>.(wora),[13]

meaning <word2.txt,1>;<total,1>.1995 <word2.txt,1>;<total,1>.2007, <word2.txt,1>;<total,1>.2015, <word2.txt,1>;<total,1>.9 <word2.txt,1>;<total,1>.3.5單詞共現(xiàn)單詞共現(xiàn)是對(duì)實(shí)際問(wèn)題的抽象化描述方式,在本設(shè)計(jì)中,實(shí)現(xiàn)的方式是采用pairs算法,偽代碼如下:map(offset,text)forallwordwistextforallworduiswindow(w)Output(pair(w,u),1)reduce(pairp,countlist)s=0forallcountcincountlists=s+coutput(pairp,s)需要定義window,可以是一個(gè)固定長(zhǎng)度,也可以是前后相連出現(xiàn)或在同一句中出現(xiàn)又或者在同一段落中出現(xiàn)的單詞,根據(jù)實(shí)際的使用情況可以自行更改。在map函數(shù)的輸出中,輸出的鍵格式為pair,由于采用輸出的鍵為單詞對(duì)的格式,Hadoop中并沒(méi)有相關(guān)的數(shù)據(jù)格式,因此必須先定義一個(gè)TextPair類來(lái)實(shí)現(xiàn)。在一般情況下也可以通過(guò)將兩個(gè)單詞連接成一個(gè)字符串,再轉(zhuǎn)化為自帶的Text類型來(lái)實(shí)現(xiàn),但是在將單詞對(duì)作為整體同時(shí),也必須實(shí)現(xiàn)自己的partitioner,可以通過(guò)繼承自帶的HashPartitioner來(lái)實(shí)現(xiàn)自定義的分區(qū)方式(如果采用默認(rèn)的分區(qū)方式,則會(huì)以單詞對(duì)作為分區(qū)的關(guān)鍵因素而不是第一個(gè)單詞,這很有可能會(huì)導(dǎo)致錯(cuò)誤)。在實(shí)際應(yīng)用中,還應(yīng)該考慮到應(yīng)該將整個(gè)文檔作為一個(gè)整體,以保證在作為輸入時(shí)不會(huì)被拆分而傳輸?shù)讲煌膍apper中。為此,在這里會(huì)實(shí)現(xiàn)自己的WholeFileInputFormat輸入格式,同時(shí)也需要自定義RecordReader來(lái)讀取文件內(nèi)容作為record的值。在實(shí)現(xiàn)中,以正則表達(dá)式的方式,只匹配單詞,忽略其它字符。數(shù)據(jù)輸出內(nèi)容如下:All the 1Amazon Web 1Apache HBase 1Apache Hadoop 4Apache Hive 1Apache Pig 1Apache Spark 1App Engine 1As of 2Azure Amazon 1C and 2C but 1Classpath standard 1Common contains 1Community Process 1Compiler for 1Corporation and 1Distributed File 2Engine and 1Facebook and 1File System 3第四章結(jié)論在分布式環(huán)境中,Hadoop能有很好的性能,但是本設(shè)計(jì)的環(huán)境采用偽分布來(lái)模擬完全分布式環(huán)境,所以并不能顯示高性能,反而,由于其復(fù)雜的框架使得在偽分布式情況下會(huì)多出許多多余的操作,大大降低了程序的速度。此外,分布式計(jì)算的實(shí)現(xiàn)也不是萬(wàn)能的,雖然分布式計(jì)算是一種很好的解決方案,但是在實(shí)際中也應(yīng)該針對(duì)具體問(wèn)題選擇合適的方法。在選擇Hadoop作為分布式計(jì)算平臺(tái)的時(shí)候,必須考慮實(shí)際運(yùn)行情況對(duì)參數(shù)配置進(jìn)行調(diào)優(yōu),適時(shí)根據(jù)集群和作業(yè)的變化進(jìn)行調(diào)整,以達(dá)到最優(yōu)化效果。MapReduce是一種十分簡(jiǎn)單的計(jì)算模型,也提供了很大的靈活度,所以在實(shí)際開發(fā)過(guò)程中,可能會(huì)遇到各種問(wèn)題,也正是因?yàn)槠鋸?qiáng)大的擴(kuò)展能力,給程序的開發(fā)造成了一定程度上的困難,開發(fā)過(guò)程中也有許多的中間結(jié)果處理方式,選擇合適的中間結(jié)果輸出格式和類型至關(guān)重要。在任務(wù)比較復(fù)雜和情況下,可以采用組合式MapReduce任務(wù)的方式,也可以采用自定義數(shù)據(jù)格式和輸入輸出格式以達(dá)到目的??傊?,Hadoop是一個(gè)很好的分布式存儲(chǔ)和計(jì)算的平臺(tái),適時(shí)選擇其作為開發(fā)工具可能會(huì)有意想不到優(yōu)勢(shì)。致謝在整個(gè)設(shè)計(jì)過(guò)程中,我得到了許多幫助,十分感謝我的導(dǎo)師劉國(guó)才教授,在我對(duì)我的設(shè)計(jì)方向選擇上提供了十分關(guān)鍵的指導(dǎo),也一直在督促我的學(xué)習(xí)和設(shè)計(jì)進(jìn)度,讓我能時(shí)刻保持前進(jìn),路總是要靠自己去走,方向便成了至關(guān)重要的因素。從一開始接觸時(shí)的迷茫到逐漸開始入門到對(duì)整體有大致的了解,我學(xué)會(huì)了大量的新知識(shí),感謝劉國(guó)才老師給我這個(gè)難得的機(jī)會(huì)。參考文獻(xiàn)附錄程序源代碼單詞計(jì)數(shù):importjava.util.Random;importjava.io.IOException;importjava.util.StringTokenizer;importorg.apache.hadoop.conf.Configuration;importorg.apache.hadoop.fs.Path;importorg.apache.hadoop.io.IntWritable;importorg.apache.hadoop.io.LongWritable;importorg.apache.hadoop.io.Text;importorg.apache.hadoop.mapreduce.Job;importorg.apache.hadoop.mapreduce.Mapper;importorg.apache.hadoop.mapreduce.Reducer;importorg.apache.hadoop.mapreduce.lib.input.FileInputFormat;importorg.apache.hadoop.mapreduce.lib.input.TextInputFormat;importorg.apache.hadoop.mapreduce.lib.input.KeyValueTextInputFormat;importorg.apache.hadoop.mapreduce.lib.output.TextOutputFormat;importorg.apache.hadoop.mapreduce.lib.output.FileOutputFormat;//importorg.apache.hadoop.mapreduce.lib.reduce.IntSumReducer;importorg.apache.hadoop.util.GenericOptionsParser;importorg.apache.hadoop.mapreduce.lib.map.InverseMapper;//importorg.apache.hadoop.mapreduce.lib.map.TokenCounterMapper;publicclassWordCount1{publicstaticclassTokenizerMapperextendsMapper<LongWritable,Text,Text,IntWritable>{privatefinalstaticIntWritableone=newIntWritable(1);privateTextword=newText();publicvoidmap(LongWritablekey,Textvalue,Contextcontext)throwsIOException,InterruptedException{StringTokenizeritr=newStringTokenizer(value.toString());while(itr.hasMoreTokens()){word.set(itr.nextToken());context.write(word,one);}}}publicstaticclassIntSumReducerextendsReducer<Text,IntWritable,Text,IntWritable>{privateIntWritableresult=newIntWritable();publicvoidreduce(Textkey,Iterable<IntWritable>values,Contextcontext)throwsIOException,InterruptedException{intsum=0;for(IntWritableval:values){sum+=val.get();}result.set(sum);context.write(key,result);}}/*publicstaticclassNoTwoextendsMapper<Text,Text,Text,Text>{ publicvoidmap(Textkey,Textvalue,Contextcontext)throwsIOException,InterruptedException{context.write(value,key);}}*/publicstaticvoidmain(String[]args)throwsException{ Configurationconf1=newConfiguration(); //theconfigurationissame!String[]otherArgs=newGenericOptionsParser(conf1,args).getRemainingArgs();if(otherArgs.length!=2){System.err.println("Usage:wordcount1<in><out>");System.exit(2);} PathtempDir=newPath("word-count-temp-"+Integer.toString(newRandom().nextInt(Integer.MAX_VALUE))); Jobjob1=newJob(conf1,"wordcount1");job1.setJarByClass(WordCount1.class);job1.setInputFormatClass(TextInputFormat.class); //defaultjob1.setMapperClass(TokenizerMapper.class);job1.setCombinerClass(IntSumReducer.class); //notnecessaryjob1.setReducerClass(IntSumReducer.class);job1.setOutputKeyClass(Text.class);job1.setOutputValueClass(IntWritable.class);FileInputFormat.addInputPath(job1,newPath(otherArgs[0]));FileOutputFormat.setOutputPath(job1,tempDir); job1.setOutputFormatClass(TextOutputFormat.class); //default job1.waitForCompletion(true); Jobjob=newJob(conf1,"wordcount2"); job.setJarByClass(WordCount1.class);job.setInputFormatClass(KeyValueTextInputFormat.class);job.setMapperClass(InverseMapper.class);job.setOutputKeyClass(Text.class);job.setOutputValueClass(Text.class);FileInputFormat.addInputPath(job,tempDir);FileOutputFormat.setOutputPath(job,newPath(otherArgs[1]));job.waitForCompletion(true);}}//調(diào)用自帶的mapper類和reducer類實(shí)現(xiàn)/*publicclassWordCount{ publicstaticvoidmain(String[]args)throwsException { Configurationconf=newConfiguration(); if(args.length!=2) { System.err.println("Usage:wordcount<in><out>"); System.exit(2); } Jobjob=newJob(conf,"wordcount"); job.setJarByClass(WordCount.class); job.setMapperClass(TokenCounterMapper.class); job.setCombinerClass(IntSumReducer.class); job.setReducerClass(IntSumReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); FileInputFormat.addInputPath(job,newPath(args[0])); FileOutputFormat.setOutputPath(job,newPath(args[1])); System.exit(job.waitForCompletion(true)?0:1); }}*/Grep實(shí)現(xiàn)://RegexMapper.javapackagemyHadoop.text;importorg.apache.hadoop.conf.Configuration;importjava.io.IOException;importjava.util.regex.Matcher;importjava.util.regex.Pattern;importorg.apache.hadoop.io.LongWritable;importorg.apache.hadoop.io.Text;importorg.apache.hadoop.mapreduce.Mapper;/**A{@linkMapper}thatextractstextmatchingaregularexpression.*/publicclassRegexMapper<K>extendsMapper<K,Text,T

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論