1. 程式人生 > >虛擬機器CentOS 7.5.1804下無外網Hadoop HA叢集安裝

虛擬機器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、關閉防火牆

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

先檢視防火牆狀態:

[[email protected] 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 [email protected] cat /home/root/.ssh/id_rsa.pub >> /home/root/.ssh/authorized_keys 

ssh [email protected] cat /home/root/.ssh/id_rsa.pub >> /home/root/.ssh/authorized_keys 

ssh [email protected] 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 [email protected] ssh [email protected] ssh [email protected]

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應該差異不大。