學(xué)習(xí)hadoop平臺(tái)搭建也有一段時(shí)間了,期間也遇到很多問題,為了解決這些問題查了很多資料,浪費(fèi)不少時(shí)間,今天寫下這篇博客,為了幫助初學(xué)者,更快解決遇到的問題。
首先,我們要搭建的是完全分布式,mysql作為hive元數(shù)據(jù)庫,spark完全分布式,如果有需要會(huì)更新hadoop HA,這個(gè)等下次再說,這次需要用到的軟件有 hadoop-2.7.5.tar,jdk-8u151-linux-x64.tar,apache-hive-2.1.1-bin.tar,mysql-connector-java-6.0.6.tar,spark-2.0.2-bin-hadoop2.7,我會(huì)把這些軟件放到百度云里分享給大家,大家可以到文章結(jié)尾查找。
現(xiàn)在開始部署環(huán)境我用到的系統(tǒng)是ubuntu-16.04.3-desktop-amd64,我也會(huì)放在最后的百度云里,這次會(huì)用到三臺(tái)虛擬機(jī)分別為:
master 192.168.0.1 namenode secondarynamenode? resourcemanager hive?
slave1 192.168.0.2 datanode nodemanager worker
slave2 192.168.0.3?datanode nodemanager worker
修改主機(jī)名的命令為:sudo vi /etc/hosts,將上面內(nèi)容粘貼進(jìn)去即可,可以用scp /etc/hosts x@slave1:/etc 發(fā)送到其他的電腦,但要注意修改hosts文件需要有權(quán)限,如果你的用戶沒有權(quán)限,可以自己一臺(tái)一臺(tái)的用sudo vi /etc/hosts修改。
修改完主機(jī)名之后需要重啟才能生效,重啟之后就要給虛擬機(jī)上傳軟件了,如果你用的crt連接虛擬機(jī)的話,可以用rz上傳文件,如果沒有安裝,可以用 sudo apt install lrzsz 安裝, 如果沒有crt,也可以用ftp上傳,我用的是FlashFTP,這些軟件一會(huì)也會(huì)分享給大家。
上傳完之后,開始解壓這些軟件,用到的命令是 tar zxvf XXX -C ~ ,這里我喜歡直接解壓到家目錄里,~
代表家目錄。
XXX:為文件名
這是tar命令常用到的參數(shù):
-z:有g(shù)zip屬性的??gz
-j:有bz2屬性的?? bz2
-J?:有xz屬性的?? xz
-v:顯示所有過程
-c: 建立壓縮檔案
-x:解壓
-C 指定輸出路徑
解壓完要修改環(huán)境變量這是我的環(huán)境變量命令是:sudo vi /etc/profile,按G到最后一行,添加你的環(huán)境變量,因?yàn)槲椅募冀鈮旱絩oot的家目錄里所以HOOM都在root里,修改完同樣用命令 scp /etc/profile X@slavex 傳給別的虛擬機(jī)。
查看java的環(huán)境變量有沒有設(shè)置好可以用命令java查看,如果設(shè)置好會(huì)出現(xiàn):
下面開始修改hadoop文件,進(jìn)入到hadoop目錄下,hadoop的配置文件為etc/hadoop,進(jìn)入會(huì)看到很多配置文件,我們需要配置的只有5個(gè)分別為 core-site.xml,haoop-env.sh,hdfs-site.xml,mapred-site.xml(這個(gè)文件默認(rèn)為mapred-site.xml.template 需要改名為mapred-site.xml),yarn-site.xml,slaves,配置這幾個(gè)文件的時(shí)候我查找了許多大神的博客,但配置項(xiàng)實(shí)在是太多了,后來經(jīng)過很多次的調(diào)試,我找的了一個(gè)最簡化的配置項(xiàng)。
首先配置core-site.xml文件
fs.default.name也可以寫為fs.defaultFS,后面的應(yīng)該是比較新的版本寫法但意思一樣,這個(gè)配置項(xiàng)是配置namenode的9000是它的端口,
hadoop.tmp.dir 是配置他的臨時(shí)文件存放地址,如果不配置的話他默認(rèn)存放在/tmp下,如果重啟虛擬機(jī)的話,這個(gè)目錄會(huì)清空,導(dǎo)致hadoop無法正常啟動(dòng)。所以一般把這個(gè)目錄配置到hadoop目錄下,如果多次格式化hadoop的時(shí)候可能會(huì)導(dǎo)致namendoe id 和datanode id 不一致。后面我會(huì)詳細(xì)講解這個(gè)問題。
haoop-env.sh
這個(gè)文件需要修改你的JAVA_HOME,找到這一行把#去掉,然后修改路徑
hdfs-site.xml 這個(gè)配置項(xiàng)是用來配置DataNode個(gè)數(shù),在這次配置中我們有一個(gè)namenode,和兩個(gè)datanode,所以dfs.replication配置項(xiàng)應(yīng)該為2。
mapreduce-site.xml
這個(gè)文件里,只有一個(gè)必須的配置項(xiàng),但為了給大家拓展一下,我會(huì)寫出兩個(gè)不是必要的配置項(xiàng)。
必要:

這個(gè)配置項(xiàng)指定使用yarn運(yùn)行mapreduce程序,yarn是hadoop2版本才使用的資源管理框架,負(fù)責(zé)集群資源管理和調(diào)度。Hadoop 1.0資源管理由兩部分組成:資源表示模型和資源分配模型,想詳細(xì)了解的同學(xué)可以自行百度。
不是必要的:
<property>
<name>dfs.name.dir</name>
<value>xxx</value>
</property>
這個(gè)參數(shù)用于確定將HDFS文件系統(tǒng)的元信息保存在什么目錄下。
如果這個(gè)參數(shù)設(shè)置為多個(gè)目錄,那么這些目錄下都保存著元信息的多個(gè)備份。
<property>
<name>dfs.data.dir</name>
<value>xxx<value>
</property>
這個(gè)參數(shù)用于確定將HDFS文件系統(tǒng)的數(shù)據(jù)保存在什么目錄下。
我們可以將這個(gè)參數(shù)設(shè)置為多個(gè)分區(qū)上目錄,即可將HDFS建立在不同分區(qū)上。
重點(diǎn)
yarn-site.xml?
這個(gè)文件配置項(xiàng)很多,而且都很重要,如果涉及到調(diào)優(yōu)的話,一般都會(huì)涉及到這個(gè)文件的內(nèi)容。

下面我來解釋一下這三個(gè)配置項(xiàng)的意思:
yarn.resourcemanager.address
參數(shù)解釋:ResourceManager 對客戶端暴露的地址。客戶端通過該地址向RM提交應(yīng)用程序,殺死應(yīng)用程序等。
yarn.resourcemanager.scheduler.address
參數(shù)解釋:ResourceManager對ApplicationMaster暴露的訪問地址。ApplicationMaster通過該地址向RM申請資源、釋放資源等。
yarn.resourcemanager.resource-tracker.address
參數(shù)解釋:ResourceManager對NodeManager暴露的地址.。NodeManager通過該地址向RM匯報(bào)心跳,領(lǐng)取任務(wù)等。
這三個(gè)參數(shù)在偽分布式時(shí)可以不用配置,但在完全分布式中,如果不配置,yarn進(jìn)程會(huì)正常啟動(dòng),但執(zhí)行任務(wù)時(shí)會(huì)卡主。一會(huì)我會(huì)詳細(xì)講解這個(gè)問題。

yarn.nodemanager.resource.memory-mb
【存疑】
表示該節(jié)點(diǎn)上YARN可使用的物理內(nèi)存總量,默認(rèn)是8192(MB),注意,如果你的節(jié)點(diǎn)內(nèi)存資源不夠8GB,則需要調(diào)減小這個(gè)值,而YARN不會(huì)智能的探測節(jié)點(diǎn)的物理內(nèi)存總量,這個(gè)參數(shù)另一種說法是,該參數(shù)的默認(rèn)值是8192MB,即使你的機(jī)器內(nèi)存不夠8192MB,YARN也會(huì)按照這些內(nèi)存來使用,對于這兩種說法,我比較認(rèn)可第二種,因?yàn)槲乙郧岸际怯?G內(nèi)存搭建的平臺(tái),這個(gè)參數(shù)都是默認(rèn),但一直正常運(yùn)行,不用修改。
講到這我想給大家擴(kuò)展一下yarn框架。
ResourceManager做的事情是負(fù)責(zé)協(xié)調(diào)集群上計(jì)算資源的分配。調(diào)度、啟動(dòng)每一個(gè) Job 所屬的 ApplicationMaster、另外監(jiān)控 ApplicationMaster 的存在情況。
NodeManager 功能比較專一,根據(jù)要求啟動(dòng)和監(jiān)視集群中機(jī)器的計(jì)算容器container。負(fù)責(zé) Container 狀態(tài)的維護(hù),并向 RM 保持心跳匯報(bào)該節(jié)點(diǎn)資源使用情況。
ApplicationMaster 負(fù)責(zé)一個(gè) Job 生命周期內(nèi)的所有工作。注意每一個(gè)Job都有一個(gè) ApplicationMaster。它和MapReduce任務(wù)一樣在容器中運(yùn)行。AM通過與RM交互獲取資源,然后然后通過與NM交互,啟動(dòng)計(jì)算任務(wù)。
容器是由ResourceManager進(jìn)行統(tǒng)一管理和分配的。有兩類container:一類是AM運(yùn)行需要的container;另一類是AP為執(zhí)行任務(wù)向RM申請的。
Container是YARN中的資源抽象,它封裝了某個(gè)節(jié)點(diǎn)上的多維度資源,如內(nèi)存、CPU、磁盤、網(wǎng)絡(luò)等,當(dāng)AM向RM申請資源時(shí),RM為AM返回的資源便是用Container表示的。
這只是對yarn初步的理解,在此需要注意的是,cotainer是一個(gè)抽象的理解。
yarn.nodemanager.vmem-pmem-ratio
任務(wù)每使用1MB物理內(nèi)存,最多可使用虛擬內(nèi)存量,默認(rèn)是2.1,因?yàn)殚_始運(yùn)行任務(wù)的時(shí)候,會(huì)先檢查分配給他的資源,如果需要的虛擬內(nèi)存小于分配給他的虛擬內(nèi)存任務(wù)會(huì)失敗,如果不想讓他運(yùn)行時(shí)檢查虛擬內(nèi)存,可以通過下一個(gè)參數(shù)關(guān)閉檢測,并不會(huì)影響任務(wù)運(yùn)行。
yarn.nodemanager.vmem-check-enabled
是否啟用一個(gè)線程檢查每個(gè)任務(wù)證使用的虛擬內(nèi)存量,如果任務(wù)超出了分配值,則直接將其kill,默認(rèn)是true,修改是將參數(shù)改為 false。
最后一個(gè)文件 slaves

在這個(gè)文件里添加上,你的datanode節(jié)點(diǎn)的主機(jī)名。
修改完配置文件就可以下發(fā)hadoop文件到slave節(jié)點(diǎn)用到的命令是:scp -r [hadoop-版本] [用戶名]@[主機(jī)名]:~
發(fā)送到slave主機(jī)的用戶的家目錄。
將hadoop文件下發(fā)到slave文件之后就可以格式化文件系統(tǒng)了,在此,我用一張圖來描述linux文件系統(tǒng)和hdfs文件系統(tǒng)的區(qū)別。

需要注意的是 hadoop1 版本的默認(rèn)hdfs塊大小為64M,而Hadoop2默認(rèn)的塊大小為128M。
hdfs文件系統(tǒng)的特點(diǎn)
高容錯(cuò)性:數(shù)據(jù)自動(dòng)保存多個(gè)副本,副本丟失后,自動(dòng)恢復(fù)
適合批處理:移動(dòng)計(jì)算而飛數(shù)據(jù)。數(shù)據(jù)位置暴露給計(jì)算框架
適合大數(shù)據(jù)處理:GB,TB,設(shè)置PB級數(shù)據(jù)。百萬規(guī)模以上文件數(shù)量。10K+節(jié)點(diǎn)規(guī)模。
流式文件訪問:一次性寫入,多次讀取。保證數(shù)據(jù)一致性。
可構(gòu)建在廉價(jià)機(jī)器上:通過多副本提高可靠性。提供容錯(cuò)和恢復(fù)機(jī)制。
不適合低延遲數(shù)據(jù)訪問場景:比如毫秒級,低延遲與高吞吐率。
不適合小文件存取場景:占用NameNode大量內(nèi)存。尋道時(shí)間超過讀取時(shí)間。
不適合并發(fā)寫入,文件隨機(jī)修改場景:一個(gè)文件只能有一個(gè)寫者。僅支持append。
hdfs文件系統(tǒng)在存儲(chǔ)文件的流程是,client客戶端向namenode發(fā)送存儲(chǔ)請求,namenode檢查路徑是否可以存儲(chǔ),如果可以回復(fù)請求,client客戶端將文件分為128M一個(gè)塊的文件(如果文件小于128M占一個(gè)塊,但存儲(chǔ)在分布式系統(tǒng)上是它實(shí)際大?。热缫粋€(gè)257M的文件,client會(huì)把它且分為2個(gè)128M的文件和1個(gè)1M的文件,當(dāng)寫完一份文件后,datanode會(huì)將這份文件復(fù)制到其他的節(jié)點(diǎn)上面,默認(rèn)是存放三份,HDFS文件系統(tǒng)主要是用來處理大量數(shù)據(jù)時(shí)使用,增大他的數(shù)據(jù)塊容量有利于文件塊的定位,但也不是越大越好,如果有大量的小數(shù)據(jù)存入到HDFS系統(tǒng)中,因?yàn)閿?shù)據(jù)的元數(shù)據(jù)都存放在datanode中,因此,HDFS所能存儲(chǔ)的文件數(shù)量會(huì)受到namenode內(nèi)存的限制。
拓展
namenode 作用,運(yùn)行原理
NameNode主要是用來保存HDFS的元數(shù)據(jù)信息,比如命名空間信息,塊信息等。當(dāng)它運(yùn)行的時(shí)候,這些信息是存在內(nèi)存中的。但是這些信息也可以持久化到磁盤上。
在此引出secondary namenode 的概念,初次聽到這個(gè)詞可能很多人以為這是namenode的備份,其實(shí)不然,這里就要講一下namenode的工作原理:
namenode主要由兩個(gè)文件組成fsimage,edit logs 。當(dāng)“寫請求”到來時(shí)namenode會(huì)首先寫editlog到磁盤,即向edits文件中寫日志,成功返回后,才會(huì)修改內(nèi)存,并且向客戶端返回。只有在NameNode重啟時(shí),edit logs才會(huì)合并到fsimage文件中,從而得到一個(gè)文件系統(tǒng)的最新快照。但是在產(chǎn)品集群中NameNode是很少重啟的,這也意味著當(dāng)NameNode運(yùn)行了很長時(shí)間后,edit logs文件會(huì)變得很大。在這種情況下就會(huì)出現(xiàn)下面一些問題:
edit logs文件會(huì)變的很大,怎么去管理這個(gè)文件是一個(gè)挑戰(zhàn)。
NameNode的重啟會(huì)花費(fèi)很長時(shí)間,因?yàn)橛泻芏喔膭?dòng)[筆者注:在edit logs中]要合并到fsimage文件上。
如果NameNode掛掉了,那我們就丟失了很多改動(dòng)因?yàn)榇藭r(shí)的fsimage文件非常舊](此處摘自hadoop的NAMENODE的管理機(jī)制,工作機(jī)制和DATANODE的工作原理 - CSDN博客 想詳細(xì)了解可以去看看)

因此為了克服這個(gè)問題,我們需要一個(gè)易于管理的機(jī)制來幫助我們減小edit logs文件的大小和得到一個(gè)最新的fsimage文件,這樣也會(huì)減小在NameNode上的壓力。
SecondaryNameNode就是來幫助解決上述問題的,它的職責(zé)是合并NameNode的edit logs到fsimage文件中。

上面的圖片展示了Secondary NameNode是怎么工作的。
首先,它定時(shí)到NameNode去獲取edit logs,并更新到fsimage上。[筆者注:Secondary NameNode自己的fsimage]
一旦它有了新的fsimage文件,它將其拷貝回NameNode中。
NameNode在下次重啟時(shí)會(huì)使用這個(gè)新的fsimage文件,從而減少重啟的時(shí)間。總之我理解的secondary name是用來幫助namenode處理元數(shù)據(jù)的更新。
好,講解完namenode,secondary namenode開始重回搭建平臺(tái)的話題,上回說到修改完配置文件,開始格式化文件系統(tǒng)命令為:hdfs namenode -format 或者h(yuǎn)adoop namenode -format 成功后會(huì)顯示

成功格式化后,就可以啟動(dòng)你的進(jìn)程了。
start-dfs.sh的作用在于啟動(dòng)主節(jié)點(diǎn)的namenode,啟動(dòng)secondnamenode,以及各從節(jié)點(diǎn)的datanode進(jìn)程。
stop-dfs.sh的作用在于關(guān)閉主節(jié)點(diǎn)的namenode,啟動(dòng)secondnamenode,以及各從節(jié)點(diǎn)的datanode進(jìn)程。
啟動(dòng)完進(jìn)程,可以用命令:jps 查看
我的namenode節(jié)點(diǎn):bootstrap不是我啟動(dòng)的,他是一個(gè)前端框架。

我的datanode節(jié)點(diǎn)

start-yarn.sh 啟動(dòng)yarn?
namenode節(jié)點(diǎn)

datanode節(jié)點(diǎn): org 那個(gè)不是

啟動(dòng)完進(jìn)程就可以測試一下搭建的環(huán)境首先建一個(gè)文件a.txt,在里面隨便寫上一些內(nèi)容

然后上傳文件到hdfs系統(tǒng)上,命令hadoop fs -put a.txt? /? 上傳a.txt 到hdfs的根目錄,然后開始我們第一個(gè)wordcount 程序,hadoop jar xxx(你的hadoop路徑)/share/hadoop/mapreduce/hadoop-mapreduce-examples-xxx(你的hadoop版本).jar wordcount ? ? /a.txt(輸入路徑 我把a(bǔ).txt 放在根下) ?? /output(輸出路徑這里我放在根下的output目錄中),這是我的運(yùn)行命令:注意輸出目錄必須是之前不存在的

運(yùn)行完之后,檢查一下輸出的結(jié)果:hadoop fs -cat /output/part-00000

成功,這是最簡單的wordcount,用到的是hadoop自帶的一個(gè)jar包,以后根據(jù)不同的需求,需要自己寫wordcount程序,基本會(huì)用java或者python寫,都有自己的框架,學(xué)習(xí)起來也不算太難。
在這里我放上基本的一些hadoop命令:
復(fù)制?hadoop fs -cp /tmp/input/hadoop1/hadoop/*.* /tmp/input/hadoop
本地文件上傳到hdfs上?hadoop fs -put /tmp/input/hadoop1/hadoop/*.* /tmp/input/hadoop
從hdfs上下載文件??hadoop fs -get /tmp/input/hadoop1/hadoop/*.* /tmp/input/hadoop
查看文件列表 ?hadoop fs -ls /tmp/input/hadoop1/hadoop/
這些是最基本的命令,hadoop 的命令和linux 差別不大,學(xué)會(huì)linux即可掌握這些命令。
測試完之后,hadoop搭建基本完成,我們開始搭建hive,首先來簡單介紹一下hive:
Hive是一個(gè)數(shù)據(jù)倉庫基礎(chǔ)工具在Hadoop中用來處理結(jié)構(gòu)化數(shù)據(jù)。它架構(gòu)在Hadoop之上,總歸為大數(shù)據(jù),并使得查詢和分析方便。并提供簡單的sql查詢功能,可以將sql語句轉(zhuǎn)換為MapReduce任務(wù)進(jìn)行運(yùn)行。
搭建hive,我們用到了mysql作為元數(shù)據(jù)庫,在ubuntu中可以使用命令:sudo apt install mysql-client mysql-server 安裝mysql,安裝完之后會(huì)出現(xiàn)配置界面讓你輸入root用戶密碼,輸入完成,再輸入一遍密碼,配置完成。
賦給hive用戶權(quán)限,在這里給hive登錄的用戶名為hive密碼也是hive。
1.進(jìn)入mysql,我給mysql,root用戶密碼為123456,mysql-uroot -p,登錄成功。
2.grant all on *.* to hive@'%' identified by 'hive'? 這里賦予權(quán)限還有幾種遠(yuǎn)程登錄,感興趣的可以去看一下。
3.配置完權(quán)限,需要用命令 flush privileges 刷新一下權(quán)限,然后退出。
4.修改hive配置項(xiàng),進(jìn)入$HIVE_HOME/conf,首先修改hive-site.xml.temp,改名為hive-site.xml,然后找到里面的HADOOP_HOME 刪掉前面的#,修改后面的路徑為你的hadoop目錄,然后新建文件hive-site.xml,添加配置項(xiàng)

修改這個(gè)配置文件有點(diǎn)小技巧,可以去hive-default.xml.template文件中粘貼這些配置項(xiàng),然后修改。
修改完之后進(jìn)入$HIVE_HOME/lib 拷貝jline-2.1.2(可能和我的版本不一樣) ,到$HADOOP_HOME/share/hadoop/yarn/lib

這時(shí)還有一個(gè)mysql和hive連接的驅(qū)動(dòng) mysql-connector-java-5.1.45.tar(最好別用太高版本,這個(gè)文件我也會(huì)上傳),將這個(gè)文件放到$HIVE_HOME/lib中

進(jìn)入$HIVE_HOME/bin,執(zhí)行./schematool -initSchema -dbType mysql ,初始化元數(shù)據(jù)庫,如果出現(xiàn)初始化失敗,首先檢查配置文件有沒有出錯(cuò),如果配置文件沒有問題,那就可能要修改mysql的綁定ip,修改 /etc/mysql/mysql.conf.d/mysqld.cnf,找到里面的bind-address 默認(rèn)為127.0.0.1 修改為0.0.0.0,此時(shí)在重新初始化。

初始化完成之后,進(jìn)入$HIVE_HOME/sbin目錄下,執(zhí)行./hive ,啟動(dòng)hive。
有些任務(wù)可能涉及到將查詢到的結(jié)果輸出到控制臺(tái)或者重定向到某個(gè)文檔內(nèi) 可以使用hive -e "xxxx"
重定向 hive -e "xxx" >>xx.txt,還有大量數(shù)據(jù)在hive和hdfs互導(dǎo)時(shí)會(huì)用到sqoop,感興趣的可以去看一下。
spark 分布式搭建
我用的軟件版本是spark-2.0.2-bin-hadoop2.7,解壓完軟件包之后,進(jìn)入conf目錄,將slaves.template改名為slaves,
添加slave主機(jī)名,修改spark-env.sh.template為spark-env.sh,添加配置項(xiàng)

spark_master_ip 為namenode的 ip
下發(fā)spark到datanode節(jié)點(diǎn),下發(fā)完成后,進(jìn)入$SPARK_HOME/sbin,執(zhí)行start-all.sh,啟動(dòng)spark進(jìn)程,看到namenode上有master,datanode上有worker就說明正常啟動(dòng)了。
遇到的問題
在剛開始搭建平臺(tái)的時(shí)候,遇到過很多問題,但問題解決后都沒有記下來,現(xiàn)在只能一點(diǎn)一點(diǎn)回去找,所以暫時(shí)更新到這里,后續(xù)會(huì)添加上這一塊。
未完待續(xù).....
資源
密碼:5dct