摘要:
本文詳細介紹了基於centos7的Hadoop集羣的搭建過程,給出了Hadoop的基礎知識和項目搭建的流程,搭建了一個master結點和兩個slave結點的Hadoop集羣,在master和slave服務器上配置HDFS(hadoop分佈式文件系統) ,HBase(集羣數據庫),zookeeper(集羣維護服務),以及 kafka(消息隊列),同時詳細給出搭建過程和測試結果,並對搭建過程遇到的bug進行詳細的記錄
文章目錄
1 關於Hadoop
1.1 Hadoop是什麼
Hadoop是由java語言編寫的,在分佈式服務器集羣上存儲海量數據並運行分佈式分析應用的開源框架,其核心部件是HDFS與MapReduce。
HDFS是一個分佈式文件系統:引入存放文件元數據信息的服務器Namenode和實際存放數據的服務器Datanode,對數據進行分佈式儲存和讀取。
MapReduce是一個分佈式計算框架:MapReduce的核心思想是把計算任務分配給集羣內的服務器裏執行。通過對計算任務的拆分(Map計算/Reduce計算)再根據任務調度器(JobTracker)對任務進行分佈式計算。
1.2 Hadoop能做什麼
大數據存儲:分佈式存儲
日誌處理:擅長日誌分析
ETL:數據抽取到oracle、mysql、DB2、mongdb及主流數據庫
機器學習: 比如Apache Mahout項目
搜索引擎:Hadoop + lucene實現
數據挖掘:目前比較流行的廣告推薦,個性化廣告推薦
Hadoop是專爲離線和大規模數據分析而設計的,並不適合那種對幾個記錄隨機讀寫的在線事務處理模式。
1.3 怎麼使用Hadoop
-
Hadoop集羣的搭建
無論是在windows上裝幾臺虛擬機玩Hadoop,還是真實的服務器來玩,說簡單點就是把Hadoop的安裝包放在每一臺服務器上,改改配置,啓動就完成了Hadoop集羣的搭建。 -
上傳文件到Hadoop集羣,實現文件存儲
Hadoop集羣搭建好以後,可以通過web頁面查看集羣的情況,還可以通過Hadoop命令來上傳文件到hdfs集羣,通過Hadoop命令在hdfs集羣上建立目錄,通過Hadoop命令刪除集羣上的文件等等。 -
編寫map/reduce程序,完成計算任務
通過集成開發工具(例如eclipse)導入Hadoop相關的jar包,編寫map/reduce程序,將程序打成jar包扔在集羣上執行,運行後出計算結果。
2 項目準備
2.1 Linux centos環境準備
- 三臺centos 7機器,本例中使用 vmware 創建三臺虛擬機作爲替代
- 準備好 jdk 8(不要使用jdk8以上的版本,會出n多bug) 和 hadoop-3.1.3 安裝包
- 準備三臺虛擬機配置靜態ip點這裏
創建虛擬機,並且將網絡適配器選用 NAT模式,並且配置爲靜態 ip, 機器靜態ip配置參考 靜態ip設置 分別將三臺機器的ip 設置爲 [192.168.19.200,192.168.19.201,192.168.19.202]
2.2安裝 java 環境(三臺機器都要安裝)
由於 hadoop 框架的啓動是依賴 java 環境,因此需要準備 jdk 環境,本例中使用的 jdk8 在/home/min/tar目錄下進行演示,使用 jdk-8u202-linux-x64.tar.gz 解壓jdk ,然後使用 mv jdk1.8.0_201 jdk8 將目錄改名
- 配置 jdk 環境變量
使用命令 vi /etc/profile 將如下代碼添加到文件末尾,JAVA_HOME 變量設置爲自己的目錄
export JAVA_HOME=/home/min/tar/jdk8
export CLASSPATH=.$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$JAVA_HOME/bin:$PATH
配置好以後使用 source /etc/profile 重新加載配置文件,使用 java -version 測試jdk 配置是否成功
2.3 修改三臺主機 hostname
本例中Linux操作系統爲爲 centos 7,使用自帶的 hostnamectl 修改hostname
//192.168.19.200 上執行
hostnamectl set-hostname master
//192.168.19.201 上執行
hostnamectl set-hostname slave1
//192.168.19.202 上執行
hostnamectl set-hostname slave2
- 修改 host文件
使用 vi /etc/hosts 編輯該文件,在文件最後追加主機與ip的對應關係 最後重啓機器,將這些配置生效
192.168.19.200 master
192.168.19.201 slave1
192.168.19.202 slave2
2.4 配置集羣機器之間的免密登錄
hadoop 集羣是通過主節點的 rpc 調用來對整個集羣進行統一的操作管理,如果不配置免密登錄,在每次啓動集羣時需要輸入每個從節點的機器密碼,免密登錄很好的解決此問題
- 分別在三臺機器上生成 ssh 鏈接的私鑰和公鑰(一直回車,直到結束),在用戶的家目錄下生成一個隱藏文件 .ssh
ssh-keygen -t rsa
2. 將本機的公鑰拷貝到其餘兩臺機器和本機,以 master 機器爲例
ssh-copy-id -i .ssh/id_rsa.pub slave1
ssh-copy-id -i .ssh/id_rsa.pub slave2
ssh-copy-id -i .ssh/id_rsa.pub master
-
將三臺機器公鑰都拷貝完成後,會在 ~/.ssh 文件下生成 authorized_keys,known_hosts 兩個文件,存放的是一些免密登錄的信息
-
關閉防火牆
關閉防火牆,並且設置開機不啓動
systemctl stop firewalld.service
systemctl disable firewalld.service
3 安裝 hadoop
3.1 解壓 hadoop 壓縮包
使用命令 tar -zxvf hadoop-3.1.3.tar.gz 解壓 hadoop 壓縮包
3.2 配置環境變量
在三臺機器上都配置 HADOOP_HOME ,vi /etc/profile 添加圖中內容,保存後,使用 source /etc/profile 使配置文件生效
export JAVA_HOME=/home/min/tar/jdk-11.0.4
export CLASSPATH=.JAVA_HOME/lib/tools.jar
export HADOOP_HOME=/home/min/tar/hadoop-3.1.3
export PATH=JAVA_HOME/bin:HADOOP_HOME/bin
3.3 修改配置文件
修改Hadoop目錄下的 etc/hadoop文件夾中的core-site.xml,hadoop-env.sh,hdfs-site.xml,mapred-site.xml,yarn-site.xml,workers。先修改 master 節點上的配置文件,然後通過遠程複製到 slave1 與 slave2
- 修改core-site.xml
- 修改 hadoop-env.sh
- 修改hdfs-site.xml
- 修改mapred-site.xml
- 修改workers
- 修改yarn-site.xml
3.4 拷貝文件
將 hadoop 目錄從 master 拷貝到 slave1 與 slave2,由於之前配置了免密登錄,所以不需要輸入密碼即可完成拷貝
scp -qr /home/min/tar/hadoop-3.1.3 slave1:/home/min/tar
scp -qr /home/min/tar/hadoop-3.1.3 slave2:/home/min/tar
3.5 創建臨時文件目錄
創建臨時文件目錄 (三臺機器都需創建), 創建的目錄對應於 第六步 hdfs-site.xml 中配置的目錄
mkdir -p /data/hadoop/hdfs/data
mkdir -p /data/hadoop/hdfs/name
3.6 格式化 hdfs 文件系統
在master結點上的hadoop的安裝目錄下的 bin 目錄下執行以下命令
./hdfs namenode -format
注意:
如果需要重新格式化NameNode,需要先將原來NameNode和DataNode下的文件全部刪除,不然會報錯,NameNode和DataNode所在目錄是在core-site.xml中hadoop.tmp.dir、dfs.namenode.name.dir、dfs.datanode.data.dir屬性配置的。
因爲每次格式化,默認是創建一個集羣ID,並寫入NameNode和DataNode的VERSION文件中(VERSION文件所在目錄爲hdfs/name/current 和 hdfs/data/current),重新格式化時,默認會生成一個新的集羣ID,如果不刪除原來的目錄,會導致namenode中的VERSION文件中是新的集羣ID,而DataNode中是舊的集羣ID,不一致時會報錯。
3.7 啓動hadoop
主節點上在hadoop目錄下執行:
./sbin/start-all.sh
- 主節點上jps進程如下:
- 每個子節點上的jps進程如下:
如果這樣表示hadoop集羣配置成功
4 測試Hadoop
4.1 web 頁面測試
以下幾個web頁面是否可以正常打開(注意關閉防火牆)
http://192.168.19.200:8088/cluster hadoop 集羣信息
http://192.168.19.200:9870/dfshealth.html#tab-overview hdfs 地址
http://192.168.19.200:9864/datanode.html dataNode 地址
http://192.168.19.200:8042/node nodeManager 地址
http://192.168.19.200:9868/status.html secondaryNameNode
4.2 hdfs 功能測試
- 提前打開web界面查看 hdfs 文件系統,目前根目錄下沒有任何文件
- 使用命令 hdfs dfs -put start-dfs.sh / 將sbin文件夾中的 start-dfs.sh 文件上傳到 hdfs 文件系統的根目錄下
- 重新打開web界面查看 hdfs 文件系統文件是否上傳成功
4.3 mapreduce 功能測試
- /home/min 目錄下創建一個文件 wordtest 文件內容如下,下面我們用自帶的庫函數 統計各個單詞出現的次數
Good morning, everyone. Thank you for taking your time. It’s really my honor to have this opportunity to take part in this interview. Now, I would like to introduce myself briefly.
- 將該文件上傳到 hdfs 文件系統上(因爲 mapreduce 功能是在 hdfs 基礎之上)【使用的是另一種 hdfs 上傳文件的命令】
hadoop fs -put wordtest /wordtest
- 執行 mapreduce 後生成結果文件
hadoop jar /home/min/hadoop-3.1.3/share/hadoop/mapreduce
/hadoop-mapreduce-examples-3.1.3.jar wordcount /wordtest /result
- 查看統計結果
5 安裝配置Zookeeper集羣
解壓zookeeper安裝包,並重命名爲zookeeper,然後進行以下操作。
5.1 修改配置文件zoo.cfg
進入~/zookeeper/conf目錄,拷貝zoo_sample.cfg文件爲zoo.cfg
cp zoo_sample.cfg zoo.cfg
對zoo.cfg進行編輯,內容如下:
dataDir=/home/min/tar/zookeeper/data
server.1=192.168.19.200:2888:3888
server.2=192.168.19.201:2888:3888
server.3=192.168.19.202:2888:3888
5.2 新建並編輯myid文件
在dataDir目錄下新建myid文件,輸入一個數字(master爲1,slave1爲2,slave2爲3),比如master主機上的操作如下:
mkdir /home/min/tar/zookeeper/data
echo "1" > /home/min/tar/zookeeper/data/myid
同樣,也可以使用scp命令進行遠程複製,只不過要修改每個節點上myid文件中的數字
scp -qr /home/min/tar/zookeeper slave1:/home/min/tar
scp -qr /home/min/tar/zookeeper slave2:/home/min/tar
注意事項:
如果啓動報類似異常:QuorumCnxManager@384] – Cannot open channel to 2 at election address slave-02/192.168.0.178:3888 是可以忽略的,因爲該服務啓動時會嘗試連接所有節點,而其他節點尚未啓動。通過後面部分可以看到,集羣在選出一個Leader後,最後穩定 了。其他結點可能也出現類似問題,屬於正常。
6 安裝配置HBase集羣
將hbase安裝包進行解壓,並重命名爲hbase,然後進入habase的bin目錄進行如下配置。
6.1 修改配置文件
- 配置hbase-env.sh
export JAVA_HOME=/home/min/tar/jdk-11.0.4
export HBASE_CLASSPATH=/home/min/tar/hadoop-3.1.3/etc/hadoop/
export HBASE_MANAGES_ZK=false
- 配置hbase-site.xml
<configuration>
<property>
<name>hbase.rootdir</name>
<value>hdfs://master:9000/hbase</value>
</property>
<property>
<name>hbase.master</name>
<value>master</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.zookeeper.property.clientPort</name>
<value>2181</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>master,slave1,slave2</value>
</property>
<property>
<name>zookeeper.session.timeout</name>
<value>60000000</value>
</property>
<property>
<name>dfs.support.append</name>
<value>true</value>
</property></configuration>
- 配置regionservers
在 regionservers 文件中添加slave列表:
master
slave1
slave2
6.2分發並同步安裝包
將整個hbase安裝目錄都遠程拷貝到所有slave服務器:
scp -qr /home/min/tar/hbase slave1:/home/min/tar
scp -qr /home/min/tar/hbase slave2:/home/min/tar
6.3 啓動hbase
./hbase/bin/start-hbase.sh
7 安裝配置kafka集羣
將kafka安裝包進行解壓,並重命名爲kafka,對config目錄下的server.properties添加配置
7.1 修改配置文件
- 添加broker.id
broker.id=01
host.name=master
- 添加zookeeper節點地址和端口
zookeeper.connect=master:2181,slave1:2181,slave2:2181
7.2 分發並同步安裝包
scp -qr /home/min/tar/kafka slave1:/home/min/tar
7.3 slave1和slave2上更改broker id
將broker id改爲02和03
7.4 啓動kafka
由於沒有配置環境,需要再kafka目錄下啓動
./bin/kafka-server-start.sh -daemon config/server.properties
8 啓動集羣
-
啓動ZooKeeper
zookeeper/bin/zkServer.sh start -
啓動hadoop
./hadoop-3.1.3/sbin/start-all.sh -
啓動hbase
./hbase/bin/start-hbase.sh -
啓動kafka
./bin/kafka-server-start.sh -daemon config/server.properties -
啓動後,master上進程和slave進程列表
Mater
Slave
9 測試kafka
- 在master上創建topic-test
./bin/kafka-topics.sh --create --zookeeper master:2181,slave1:2181,slave2:2181 --replication-factor 3 --partitions 3 --topic test
Created topic "test".
- 在master,slave1,2上查看已創建的topic列表
./bin/kafka-topics.sh --list --zookeeper localhost:2181
3. 在master上啓動生產者
./bin/kafka-console-producer.sh --broker-list master:9092,slave1:9092,slave2:9092 --topic test
4. 在其他節點上啓動控制檯消費者
./bin/kafka-console-consumer.sh --bootstrap-server master:9092,slave1:9092,slave2:9092 --from-beginning --topic test
10 測試Hbase
這個測試是通過HBase Shell 命令來完成一個 HBase 表的創建、插入、查找、刪除操作。
-
進入shell模式
-
創建test1表
-
顯示錶
-
插入數據
-
查看數據
-
獲取數據
-
刪除表
11 遇到的bug
11.1 啓動hdfs時,datanodes報錯
Starting datanodes
ERROR: Refusing to run as root: root account is not found. Aborting.
解決辦法:
在hadoop/etc/hadoop/hadoop-env.sh中的配置文件中的root多打了個空格,更正即可
11.2 啓動hdfs時,datanode無法正常啓動
當我們多次格式化文件系統(hadoop namenode -format)時,會出現DataNode無法啓動。
多次啓動中發現有NameNode節點,並沒有DataNode節點
如圖所示:
經查看相關日誌發現問題所在:
datanode的clusterID 和 namenode的clusterID 不匹配。
當我們執行文件系統格式化時,會在namenode數據文件夾(即配置文件中dfs.name.dir在本地系統的路徑)中保存一個current/VERSION文件,記錄namespaceID,標誌了所有格式化的namenode版本。如果我們頻繁的格式化namenode,那麼datanode中保存(即dfs.data.dir在本地系統的路徑)的current/VERSION文件只是你地第一次格式化時保存的namenode的ID,因此就會造成namenode和datanode之間的ID不一致。
解決辦法:
刪除DataNode的所有資料及將集羣中每個datanode節點的/dfs/data/current中的VERSION刪除,然後重新執行hadoop namenode -format進行格式化,重啓集羣,錯誤消失。
出現該問題的原因:
在第一次格式化dfs後,啓動並使用了hadoop,後來又重新執行了格式化命令(hdfs namenode -format),這時namenode的clusterID會重新生成,而datanode的clusterID 保持不變。
11.3 yarn無法正常啓動 (resourceManager/nodeManager)
./sbin/start-yarn.sh
jps上找不到 resourceManager 和 nodeManger的進程, 查詢日誌發現是jdk版本問題
解決辦法: 從jdk9以後 java9默認禁用訪問許多javax. * API。更換jdk8即可
11.4 webHDFS出錯
如下圖,提示"Failed to retrieve data from /webhdfs/v1/?op=LISTSTATUS:Server Error“,也無法透過Web界面上傳文件
經過一番查找之後(可找Hadoop的Log日誌)確認是Jdk的版本問題,更換jdk版本爲 jdk8
這件事得到一個教訓,軟件並不是版本越高越好