虛擬機CentOS 7.5.1804下無外網Hadoop HA集羣安裝

網上有很多Hadoop HA集羣安裝的資料,我當時安裝也是參考了官方文檔和這些資料才安裝成功的。由於使用的環境和軟件版本可能有所不同,且因工作環境網絡所限無法連接外網,加之記錄一下自己的安裝過程,不枉花費時間來研究Hadoop環境的搭建,故作此文章。

一、集羣架構表

IP地址

主機名

角色

 

端口

192.168.52.2

namenode

NameNode,JournalNode,ZKFC,

ResourceManager,MapReduce歷史服務器

hdfs-site(http://namenode:50070)

yarn-site(http://namenode:8088)

192.168.52.3

datanode1

NameNode,JournalNode,ZKFC,DataNode,ZooKepper

hdfs-site(http://datanode1:50070)

192.168.52.4

datanode2

ResourceManager,JournalNode,DataNode,ZooKepper

yarn-site(http://namenode:8088)

192.168.52.5

datanode3

DataNode,ZooKepper

 

注:ZKFC並不依賴ZooKeeper,所以無須在namenode上安裝ZooKeeper。

 

二、操作系統環境及軟件版本(都是當時的最新版本)

我安裝的是1臺虛擬機,克隆了3個,具體安裝過程在此不加贅述。

1、CentOS 7.5.1804 ,最小化安裝

2、Hadoop 2.9.2

3、JDK8(最開始裝的JDK11,屢試不行,去官網查版本支持,發現不支持JAVA 11,於是下的JDK8)

4、ZooKeeper-3.4.13

5、ntpdate或者CentOS 7默認的chrony時間同步,二選一

6、psmisc(很重要,fuser指令所需的包,後面會詳細說明)

 

cat /etc/redhat-release

hadoop -version

java -version

alternatives --config java (配置java多版本環境)

yum install psmisc

 

 

三、安裝過程

1、配置主機名

1.1 分別在4臺服務器上用root賬戶執行:

hostnamectl set-hostname namenode 

hostnamectl set-hostname datanode1 

hostnamectl set-hostname datanode2

hostnamectl set-hostname datanode3

1.2 在4臺服務器上用root用戶執行(亦可在namenode上修改,然後scp複製到其他主機上):

vi /etc/hosts

然後在文本末尾插入如下4行信息

192.168.52.2 namenode 

192.168.52.3 datanode1 

192.168.52.4 datanode2 

192.168.52.5 datanode3 

192.168.52.1 win             #這行最好也加上,方便本機windows與4臺虛擬機的相互訪問

2、關閉SELINUX

因爲CentOS的所有訪問權限都是有SELinux來管理的,爲了簡化安裝過程避免權限導致的問題,先將其關閉,以後根據需要再進行重新管理。

執行如下指令關閉:

setenforce 0 #臨時設置SELINUX狀態

vi /etc/selinux/config # 編輯 config 文件將 SELINUX=enforcing 修改爲 SELINUX=disabled(重啓生效)

查看執行結果:

getenforce #查看當前SELINUX狀態,permissive或disabled代表SELINUX處於關閉狀態

3、關閉防火牆

同樣是爲了簡化安裝,避免防火牆策略帶來的影響。

先查看防火牆狀態:

[hadoop@namenode hadoop]$ systemctl status firewalld 

● firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled) #disabled表示非開機啓動 

Active: inactive (dead) #inactive表示當前未激活,active表示已激活 

Docs: man:firewalld(1)

4、新建hadoop賬戶

由於Hadoop 集羣中的各節點默認會使用當前的賬號SSH免密碼登錄其它節點,所以需要在每個節點中創建一個相同的供 Hadoop 集羣專用的賬戶,本例中使用的賬戶爲 hadoop 。

useradd hadoop #創建賬戶 passwd hadoop #設置密碼

5、配置ssh互信(root、hadoop)

5.1 開啓 sshd 祕鑰認證

編輯每一臺服務器的  /etc/ssh/sshd_config 文件,去掉下面這3行前的 “#” 註釋。

執行:

vi  /etc/ssh/sshd_config

刪除行首"#",取消註釋: 

   # RSAAuthentication yes

   # PubkeyAuthentication yes

   # AuthorizedKeysFile      .ssh/authorized_keys

然後重啓sshd服務:

systemctl restart sshd

5.2 配置root賬戶的ssh互信

5.2.1 生成公鑰和私鑰

在4臺服務器上執行,一直按回車默認即可:

ssh-keygen -t rsa

執行完後會在hadoop用戶的家目錄(/home/hadoop)中生成一個.ssh文件夾,裏面有兩個文件,其中id_rsa是私鑰,id_rsa.pub是公鑰。

 

在namenode服務器上以下執行:

5.2.2 將4臺服務器公鑰文件的內容追加輸入到authorized_keys文件

(1) 先將namenode的公鑰內容插入到authorized_keys文件

cat /home/root/.ssh/id_rsa.pub >> /home/root/.ssh/authorized_keys

(2) 通過ssh輸入密碼再將三臺datanode的公鑰內容插入到authorized_keys文件

ssh hadoop@datanode1 cat /home/root/.ssh/id_rsa.pub >> /home/root/.ssh/authorized_keys 

ssh hadoop@datanode2 cat /home/root/.ssh/id_rsa.pub >> /home/root/.ssh/authorized_keys 

ssh hadoop@datanode3 cat /home/root/.ssh/id_rsa.pub >> /home/root/.ssh/authorized_keys

5.2.3 ssh連接namenode自己,以在/home/root/.ssh/known_hosts生成自己的那條記錄

ssh hadoop cat /home/root/.ssh/id_rsa.pub >> /home/root/.ssh/authorized_keys

5.2.4 將authorized_keys和known_hosts通過scp複製到三臺datanode服務器上

scp /home/root/.ssh/authorized_keys datanode1:/home/root/.ssh/ 

scp /home/root/.ssh/authorized_keys datanode2:/home/root/.ssh/ 

scp /home/root/.ssh/authorized_keys datanode3:/home/root/.ssh/ 

scp /home/root/.ssh/known_hosts datanode1:/home/root/.ssh/ 

scp /home/root/.ssh/known_hosts datanode2:/home/root/.ssh/ 

scp /home/root/.ssh/known_hosts datanode3:/home/root/.ssh/

5.2.5 修改ssh目錄和authorized_keys的權限

chmod -R 700 /home/root/.ssh chmod 600 /home/root/.ssh/authorized_keys

5.2.6 測試一下,不需要輸入密碼就能登錄則成功,注意下命令行中的主機名哦

ssh root@datanode1 ssh root@datanode2 ssh root@datanode3

5.3 同理,配置hadoop賬戶的ssh互信

用hadoopz賬戶登錄,生成公、私鑰:

ssh-keygen -t rsa

其他步驟按照5.2的順序來,只要把root替換成hadoop就可以了。

6、 用root用戶給hadoop用戶授予sudo權限

執行如下指令:

visudo

在文末添加如下內容,目的是爲了授予hadoop用戶組所有權限,可使用sudo指令執行一些只有root用戶才能執行的指令。

%hadoop ALL=(ALL) ALL

7、安裝JDK

從下面網站下載Oracle JDK8的tar.gz包,第一個網站可以下載8u202版本,第二個可以下載8u192版本,Oracle官方說了2019年1月以後將不支持Java 8的公開版更新。

http://jdk.java.net/8/

https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

ftp、rz或通過虛擬機共享文件夾上傳到服務器,找到安裝包所在目錄,解壓安裝即可,

tar -zxf java8.tar.gz -C 要解壓到的文件路徑 #想要看安裝過程輸出信息的可以加個v參數,即-zxvf

8、配置時間同步,避免服務器間時間不一致帶來的影響

注意:ntp配置後,要延遲一陣纔開始時間同步,所以用ntpstat -p指令查看是否配置成功時,不要以爲輸出的結果不對就是沒配置正確,最好等一段時間再看。

9、安裝ZooKeeper

這個也沒什麼說的,下載,解壓,配置。在ZooKeeper服務器比如datanode1上安裝配置好後,然後scp整個ZooKeeper目錄即可。

下載地址:

https://www.apache.org/dyn/closer.cgi/zookeeper/

到ZooKeeper服務器上,解壓指令:

tar -zxf zookeeper.tar.gz -C 要解壓到的文件路徑

配置:

到ZooKeeper的安裝目錄下的conf子目錄下新建zoo.cfg:

cp zoo_sample.cfg zoo.cfg

配置zoo.cfg:

vi zoo.cfg

把原來的dataDir那行註釋掉,新加如下兩行:

dataDir=/hadoop/software/zookeeper-3.4.13/data
dataLogDir=/hadoop/software/zookeeper-3.4.13/logs
server.1=datanode1:2888:3888
server.2=datanode2:2888:3888
server.3=datanode3:2888:3888

新建兩個目錄——data目錄和logs目錄,對應zoo.cfg中的配置,並在data目錄下新建myid文件,內容對應zoo.cfg中的server單詞後的數字,如果是複製的文件別忘了改哦!

至此ZooKeeper就配好了,是不是很簡單?

10、安裝、配置Hadoop

安裝hadoop難點無非就是配置問題,在遇到問題時確保配置正確,結合log文件查找原因。

注意:下面所有指令都是以hadoop用戶登錄執行的:

10.1 安裝Hadoop

下載地址:

http://hadoop.apache.org/

下載好tar.gz包,解壓(建議不要下source源碼版本的,需要各種包和docker包,很煩),注意四臺服務器上都要安裝哦!

tar -zxf hadoop.tar.gz -C hadoop的安裝目錄

10.2 配置hadoop的環境變量和全局環境變量

可以分別配置/etc/profile和/home/hadoop/.bash_profile,這樣權限方面更安全一點,但我嫌麻煩,索性都配到/etc/profile裏了。

vi /etc/profile

在文末加入如下內容:

# Configure JAVA 
export JAVA_HOME=/software/jdk1.8.0_202 
export JAVA_BIN=$JAVA_HOME/bin 
export JAVA_LIB=$JAVA_HOME/lib 
export CLASSPATH=.:$JAVA_LIB/tools.jar:$JAVA_LIB/dt.jar 
# Configure Hadoop 
export HADOOP_HOME=/hadoop/hadoop-2.9.2 
export HADOOP_CONF_DIR=${HADOOP_HOME}/etc/hadoop 
# Configure Zookeeper 
export ZOOKEEPER_HOME=/hadoop/software/zookeeper-3.4.13 
# Configure PATH export PATH=$PATH:$HOME/.local/bin:$HOME/bin:$JAVA_BIN:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$ZOOKEEPER_HOME/bin

進入到配置文件所在目錄:

cd /hadoop/hadoop-2.9.2/etc/hadoop

10.3 在配置hdfs時用到的配置文件是hadoop-env.sh、core-site.xml和hdfs-site.xml,具體配置如下:

10.3.1 配置hadoop-env.sh

將其中的export JAVA_HOME行替換爲JAVA_HOME的絕對路徑:

export JAVA_HOME=/software/jdk1.8.0_202

根據自己的實際環境配置。注意,我開始覺得沒必要修改,因爲JAVA_HOME全局變量已經在/etc/profile中聲明瞭,且測試shell腳本echo出的變量值也對,運行Hadoop卻報錯,看樣必須要設置成絕對路徑。

10.3.2 配置core-site.xml,在<configuration>標籤內加入(如果裏面有內容,則替換)如下內容:

<property>
<!-- hdfs默認文件系統名 -->
          <name>fs.defaultFS</name>
          <value>hdfs://mycluster</value>
        </property> 
<!-- 序列文件的緩衝區大小 -->
        <property> 
                <name>io.file.buffer.size</name>
                <value>131072</value>
        </property> 
<!-- 臨時文件目錄-->
        <property> 
                <name>hadoop.tmp.dir</name>
                <value>file:/hadoop/hadoop-2.9.2/tmp_ha</value>
        </property>
<!-- 指定ZKFC故障自動切換轉移 -->
        <property>
                <name>ha.zookeeper.quorum</name>
                <value>namenode:2181,datanode1:2181</value>
        </property>

10.3.3 配置hdfs-site.xml

<!-- reducer獲取數據的方式 -->
 <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
<!--啓用ResourceManager ha-->
    <property>
        <name>yarn.resourcemanager.ha.enabled</name>
        <value>true</value>
    </property>
<!--啓用ResourceManager ha自動切換-->
    <property>    
        <name>yarn.resourcemanager.ha.automatic-failover.enabled</name>
        <value>true</value>
    </property>
<!--聲明兩臺ResourceManager的地址-->
    <property>
        <name>yarn.resourcemanager.cluster-id</name>
        <value>rmCluster</value>
    </property>
<!--定義兩臺ResourceManager的rm-id--> 
<property>
        <name>yarn.resourcemanager.ha.rm-ids</name>
        <value>rm1,rm2</value>
    </property>
<!--定義rm-id爲rm1的ResourceManager的主機名-->
    <property>
        <name>yarn.resourcemanager.hostname.rm1</name>
        <value>namenode</value>
    </property>
<!--定義rm-id爲rm2的ResourceManager的主機名-->
    <property>
        <name>yarn.resourcemanager.hostname.rm2</name>
        <value>datanode2</value>
    </property>
<!--指定zookeeper集羣的地址-->
    <property>
        <name>yarn.resourcemanager.zk-address</name>
        <value>datanode1:2181,datanode2:2181,datanode3:2181</value>
    </property>
<!--啓用自動恢復-->
    <property>
        <name>yarn.resourcemanager.recovery.enabled</name>
        <value>true</value>
    </property>
<!--指定ResourceManager的狀態信息存儲在zookeeper集羣-->
    <property>
        <name>yarn.resourcemanager.store.class</name>    
        <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
    </property>

至此,hdfs HA就配置完了。

10.4 在配置yarn ResourceManager時用到的配置文件是yarn-env.sh、yarn-site.xml

10.4.1 配置yarn-env.sh

將其中的export JAVA_HOME行替換爲JAVA_HOME的絕對路徑:

export JAVA_HOME=/software/jdk1.8.0_202 

10.4.2 配置yarn-site.xml

<!-- reducer獲取數據的方式 -->
 <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
<!--啓用ResourceManager ha-->
    <property>
        <name>yarn.resourcemanager.ha.enabled</name>
        <value>true</value>
    </property>
<!--啓用ResourceManager ha自動切換-->
    <property>    
        <name>yarn.resourcemanager.ha.automatic-failover.enabled</name>
        <value>true</value>
    </property>
<!--聲明兩臺ResourceManager的地址-->
    <property>
        <name>yarn.resourcemanager.cluster-id</name>
        <value>rmCluster</value>
    </property>
<!--定義兩臺ResourceManager的rm-id--> 
<property>
        <name>yarn.resourcemanager.ha.rm-ids</name>
        <value>rm1,rm2</value>
    </property>
<!--定義rm-id爲rm1的ResourceManager的主機名-->
    <property>
        <name>yarn.resourcemanager.hostname.rm1</name>
        <value>namenode</value>
    </property>
<!--定義rm-id爲rm2的ResourceManager的主機名-->
    <property>
        <name>yarn.resourcemanager.hostname.rm2</name>
        <value>datanode2</value>
    </property>
<!--指定zookeeper集羣的地址-->
    <property>
        <name>yarn.resourcemanager.zk-address</name>
        <value>datanode1:2181,datanode2:2181,datanode3:2181</value>
    </property>
<!--啓用自動恢復-->
    <property>
        <name>yarn.resourcemanager.recovery.enabled</name>
        <value>true</value>
    </property>
<!--指定ResourceManager的狀態信息存儲在zookeeper集羣-->
    <property>
        <name>yarn.resourcemanager.store.class</name>    
        <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
    </property>

至此,yarn HA就配置完了。

10.5 複製配置到其他3臺服務器

10.5.1 爲了省事,可以先配好一臺服務器,比如namenode,然後再用scp指令複製hadoop配置文件到其他機器上。

在其餘三臺服務器上分別用hadoop用戶執行:

scp -r namenode:/hadoop/hadoop-2.9.2/etc/hadoop /hadoop/hadoop-2.9.2/etc/hadoop

也可以反過來,只在namenode服務器上執行:

scp -r /hadoop/hadoop-2.9.2/etc/hadoop datanode1:/hadoop/hadoop-2.9.2/etc/hadoop
scp -r /hadoop/hadoop-2.9.2/etc/hadoop datanode1:/hadoop/hadoop-2.9.2/etc/hadoop 
scp -r /hadoop/hadoop-2.9.2/etc/hadoop datanode1:/hadoop/hadoop-2.9.2/etc/hadoop  

10.5.2 建議依據服務器在集羣中的角色做個性化配置

如果只是安裝個Hadoop HA集羣玩玩,可以按10.5.1那麼做;可如果想深入瞭解Hadoop的配置參數,建議結合官方文檔,對不同角色的服務器做個性化配置,少配一些不必要的參數。

11、啓動Hadoop HA集羣

(1)在任意ZooKeeper節點上執行:

hdfs zkfc -formatZK

(2)啓動ZKFC (ZookeeperFailoverController是用來監控NameNode狀態,協助實現主備NameNode切換的,所以僅僅在主備NameNode節點上啓動就行)

在namenode、datanode1上分別執行:

hadoop-daemon.sh start zkfc

用jps指令查看執行結果:

(3)啓動用於主備NameNode之間同步元數據信息的共享存儲系統JournalNode。在集羣中各個節點上執行。

兩個NameNode爲了數據同步,會通過一組稱作JournalNodes的獨立進程進行相互通信。當active狀態的NameNode的命名空間有任何修改時,會告知大部分的JournalNodes進程。standby狀態的NameNode有能力讀取JournalNodes中的變更信息,並且一直監控Edit log的變化,把變化應用於自己的命名空間。standby可以確保在集羣出錯時,命名空間狀態已經完全同步了。

按如上所說,只在NameNode上啓動JournalNode即可,可是JournalNode機制有額外的限制,需要N-1/2個節點且至少有3個節點,因此必須要在其他服務器上加一個JournalNode節點。

分別在namenode、datanode1、datanode2三臺JournalNode服務器上執行:

hadoop-daemon.sh start journalnode

用jps指令查看執行結果:

(4)格式化並啓動主NameNode

在namenode上執行:

hdfs namenode -format

用jps指令查看執行結果:

(5)在備NameNode上同步主NameNode的元數據信息

在datanode1上執行:

hdfs namenode -bootstrapStandby

如果安裝過程中出現問題,多次執行會有報錯,需要關掉服務或殺死進程,清空報錯提示的目錄。

(6)啓動備NameNode

在datanode1上執行:

hadoop-daemon.sh start namenode

用jps指令查看執行結果:

 

(7)主NameNode上啓動DataNode

在namenode上,啓動所有datanode

hadoop-daemons.sh start datanode

所有節點啓動完成後,驗證主備切換。

在瀏覽器中打開

http://namenode:50070/dfshealth.html#tab-overview

http://datanode1:50070/dfshealth.html#tab-overview

查看狀態

 

 

然後,在主NameNode(主機名namenode)上執行:

ps -ef|grep namenode-namenode #正常只要ps -ef|grep namenode即可,因爲我的主機名也叫namenode,所以需要改動一下

找到進程號後,

kill -9 剛剛找到的進程號

然後查看

 

http://datanode1:50070/dfshealth.html#tab-overview

無需查看namenode的網頁,想也知道進程被殺了根本打不開。

發現datanode1的狀態由standby變爲active,則驗證成功。

 

最後,不放心的話可以在namenode上啓動NameNode。可以看到,狀態由active變爲standby。

至此,hdfs HA就驗證完了。

注:

1)這裏也可以用hdfs haadmin指令查看NameNode狀態

hdfs haadmin -getServiceState nn2 #nn1、nn2爲上面定義的NameNode節點名 

hdfs haadmin -getServiceState nn1 #報錯正常,因爲進程被kill了,還沒啓動

2)在驗證時也可以通過hdfs haadmin指令來進行主備切換,但這樣並不能驗證HA主備切換真的配置成功了。我最開始配置錯誤,這樣操作仍然可以驗證成功,可kill進程就無法驗證成功了,證明配置存在問題。

hdfs haadmin -failover nn1 nn2

(8)在主ResourceManager(namenode)、備(datanode2)上啓動Yarn

yarn-daemon.sh start resourcemanager

打開

http://namenode:8088/cluster/cluster

http://datanode2:8088/cluster/cluster

 

關掉resourcemanager服務,或者kill掉該進程後,驗證主備切換。

yarn-daemon.sh stop resourcemanager

 

此時,主ResourceManager網頁無法訪問。再次在namenode上啓動ResourceManager服務:

yarn-daemon.sh start resourcemanager

可以看到

至此,Yarn HA就驗證完了。

12、遇到的問題

(1)好多年沒關注Linux版本變更了,只是偶爾用到一些常用指令,在安裝CentOS 7時,發現好多指令都不能用了,比如SysV服務變成了systemd服務,導致chkconfig、service指令某些功能不能用了,系統建議用原生的systemctl指令。不禁感慨現在知識迭代太快了。

(2)因爲工作地點網絡環境所限,需要做額外工作。剛開始想配reposever連到阿里雲或者教育網作爲yum源,屢試不行,應該是殺毒軟件和網絡策略限制了,網絡不通。我記得以前直接用iso文件作爲yum源就行,我4臺服務器,只需要一臺做yum源,其他3臺用它當yum源,於是就按這個思路配置yum源。這樣,整個集羣就是純內網Hadoop集羣了。

(3)在配置ntp同步時,我打算用namenode作爲集羣ntp服務器,其他三臺datanode同步其時間,而namenode的時間由本機windows同步過去。其實可以用VMware Workstation自帶的時間同步。可我就是想試試windows ntp服務,於是又研究了一下,安裝了個njinx和ntp,最終實現同步。

但在驗證時驗證過早,總以爲配置有問題,因爲幾年前裝過ntp服務,大致知道怎麼配,可怎麼也找不到哪兒配置錯了。最後偶然發現ntpstat -p居然同步了,證明配置沒問題,搜了下資料才發現ntp第一次同步會有一定的延遲。

(4)在配置hdfs HA時,將ssh驗證那塊的私鑰當成公鑰了,以爲是ssh互信呢,給改成authorized_keys了,後來看log才找到原因。

(5)改完ssh後,發現kill進程主備切換還是失敗,查看log和hadoop java源碼才發現調用的是fuser指令,而CentOS 7最小化安裝默認是不安裝fuser對應的軟件包的。於是:

yum install psmisc

安裝好後,再次驗證,果然成功了!你說這有多坑吧,所以建議想省心的還是完整安裝操作系統吧,省着少這包那包的。

 

總結,架構整體挺簡單,但因涉及到的方面比較多,再加上環境原因,導致在配yum源、ntp時間同步和驗證hdfs HA時多花了些時間。在hadoop配置方面,多看看官方文檔,挺簡單的,但也不能盡信之,因爲這個文檔好像很久沒更新了,連支持的jdk都是7,聽說java是3個版本一個大版本,所以jdk 6、7、8應該差異不大。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章