分布式集群HA模式部署


一:HDFS系統架構

(一)利用secondary node備份實現數據可靠性

(二)問題:NameNode的可用性不高,當NameNode節點宕機,則服務終止

二:HA架構---提高NameNode服務的可用性

架構中至少有兩個NameNode節點 (此處以兩個NameNode舉例)

(一)兩個NN節點在某個時間只能有一個節點正常響應客戶端請求,響應請求的必須為ACTIVE狀態的那一台。另一台為standby備用

在高可用模式下,這一對NameNode節點,叫做Federation

(二)當active節點宕機,standby狀態節點必須能夠無縫的切換為active狀態。兩台NamaNode節點的元數據必須時刻保持一致,才可以實現無縫的切換狀態

NameNode最新元數據存放在edits文件(存放少量數據)中,因此將edits日志文件放入zookeeper集群中,用於數據同步(可以保持高可用)

 當active節點宕機,standby節點狀態變為active,客戶端訪問新的節點

(三)兩個NameNode節點之間如何檢測狀態變化

方法1:NameNode在zookeeper中注冊各自狀態(可以使用短暫連接,若某節點宕機,則數據銷毀)

方法2:將1中NameNode節點功能獨立出來,在節點所在機器中啟動監控進程,用於監控NameNode狀態,並寫入和監控zookeeper數據

(四)避免狀態切換出現brain split現象---fencing機制

當active節點出現故障,則standby會切換狀態為active。但是如果原始節點出現的是短暫故障,在一段時間后恢復,則出現兩台active機器(出現寫edits文件不一致)

解決方法:使ZKFC進程功能增加,當standby NameNode中ZKFC檢測檢測到原active NameNode節點工作不正常,會先進行下面的工作:

方法1:standby使用ssh 原始active節點 kill -9 namenode進程  即使用ssh遠程殺死對方active節點(會返回一個結果信息),方法1中需要使用網絡通信,可能在通信中出現故障。因此另一種方法是:

方法2:standby執行自定義shell腳本程序,可以去調用命令關閉原active機器

之后才會將standby狀態切換為active狀態

三:Hadoop分布式集群HA模式部署 

補充:訪問該Federation(兩個NameNode主機)

hdfs://Federation名稱/目錄/文件

可以配置多個Federation進行訪問(相當於多個集群)

(一)集群機器數分配

由於zookeeper配置節點與datanode節點無相干性,所以可以進一步將兩者放在同一個機器中!

同樣,可以對機器節點數再次進行精簡

(二)集群規划 

    主機名        IP                安裝的軟件                    運行的進程
    hadoopH1    192.168.58.100    jdk、hadoop                    NameNode、DFSZKFailoverController(zkfc)
    hadoopH2    192.168.58.101    jdk、hadoop                    NameNode、DFSZKFailoverController(zkfc)
    hadoopH3    192.168.58.102    jdk、hadoop                    ResourceManager
    hadoopH4    192.168.58.103    jdk、hadoop                    ResourceManager
    hadoopH5    192.168.58.104    jdk、hadoop、zookeeper        DataNode、NodeManager、JournalNode、QuorumPeerMain
    hadoopH6    192.168.58.105    jdk、hadoop、zookeeper        DataNode、NodeManager、JournalNode、QuorumPeerMain
    hadoopH7    192.168.58.106    jdk、hadoop、zookeeper        DataNode、NodeManager、JournalNode、QuorumPeerMain

(三)zookeeper配置文件

修改zoo.cfg文件

修改myid文件內容 

修改各個機器中zookeeper主目錄下data目錄下的myid內容,對應主機的id

(四)hadoop配置文件

安裝zookeeper和Hadoop按照上面配置和以前文章,修改hadoop-env.sh等文件也是按照以前文章配置。下面只講HA集群所需要修改的

1.修改hadoo-env.sh

export JAVA_HOME=/home/hadoop/App/jdk1.7.0_80

2.修改core-site.xml文件

                <configuration>
 <!-- 指定hdfs的nameservice為ns1 -->  指定Federation名稱 <property> <name>fs.defaultFS</name> <value>hdfs://ns1/</value> </property>
                    <!-- 指定hadoop臨時目錄 -->
                    <property>
                        <name>hadoop.tmp.dir</name>
                        <value>/home/hadoop/app/hadoop-2.7.1/tmp</value>
                    </property>
                    
 <!-- 指定zookeeper地址 --> <property> <name>ha.zookeeper.quorum</name> <value>hadoopH5:2181,hadoopH6:2181,hadoopH7:2181</value> </property>
                </configuration>
                

3.修改hdfs-site.xml

                <configuration>
<!--指定hdfs的nameservice為ns1,需要和core-site.xml中的保持一致 --> <property> <name>dfs.nameservices</name> <value>ns1</value> </property>
    <!-- ns1下面有兩個NameNode,分別是nn1,nn2 --> <property> <name>dfs.ha.namenodes.ns1</name> <value>nn1,nn2</value> </property>
        <!-- nn1的RPC通信地址 --> <property> <name>dfs.namenode.rpc-address.ns1.nn1</name> <value>hadoopH1:9000</value> </property>         <!-- nn1的http通信地址 --> <property> <name>dfs.namenode.http-address.ns1.nn1</name> <value>hadoopH1:50070</value> </property>
<!-- nn2的RPC通信地址 --> <property> <name>dfs.namenode.rpc-address.ns1.nn2</name> <value>hadoopH2:9000</value> </property> <!-- nn2的http通信地址 --> <property> <name>dfs.namenode.http-address.ns1.nn2</name> <value>hadoopH2:50070</value> </property>
<!-- 指定NameNode的元數據在JournalNode上的存放位置,指定zookeeper節點位置 --> <property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://hadoopH5:8485;hadoopH6:8485;hadoopH7:8485/ns1</value> </property>
<!-- 指定JournalNode在本地磁盤存放數據的位置 --> <property> <name>dfs.journalnode.edits.dir</name> <value>/home/hadoop/app/hadoop-2.7.1/journaldata</value> </property>
<!-- 開啟NameNode失敗自動切換 --> <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property>     <!-- 配置失敗自動切換實現方式 --> <property> <name>dfs.client.failover.proxy.provider.ns1</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value> </property>

        <!-- 配置隔離機制方法,多個機制用換行分割,即每個機制暫用一行--> <property> <name>dfs.ha.fencing.methods</name> <value> sshfence shell(/home/App/hadoop/fenceshell/ensure.sh)  <!--如果ssh目標主機出錯,則ssh沒有返回結果,所以配置shell很有必要,可以改變自己的狀態--> </value> </property>     <!-- 使用sshfence隔離機制時需要ssh免登陸 --> <property> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>/home/hadoop/.ssh/id_rsa</value> </property>    <!-- 配置sshfence隔離機制超時時間 --> <property> <name>dfs.ha.fencing.ssh.connect-timeout</name> <value>30000</value> </property> </configuration>

4.修改mapred-site.xml

                <configuration>
                    <!-- 指定mr框架為yarn方式 -->
                    <property>
                        <name>mapreduce.framework.name</name>
                        <value>yarn</value>
                    </property>
                </configuration>    

5.修改yarn-site.xml

                <configuration>
<!-- 開啟RM高可用 --> <property> <name>yarn.resourcemanager.ha.enabled</name> <value>true</value> </property>     <!-- 指定RM的cluster id --> <property> <name>yarn.resourcemanager.cluster-id</name> <value>yrc</value> </property>     <!-- 指定RM的名字 --> <property> <name>yarn.resourcemanager.ha.rm-ids</name> <value>rm1,rm2</value> </property>         <!-- 分別指定RM的地址 --> <property> <name>yarn.resourcemanager.hostname.rm1</name> <value>hadoopH3</value> </property> <property> <name>yarn.resourcemanager.hostname.rm2</name> <value>hadoopH4</value> </property>
<!-- 指定zk集群地址 --> <property> <name>yarn.resourcemanager.zk-address</name> <value>hadoopH5:2181,hadoopH6:2181,hadoopH7:2181</value> </property>
<property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property>
<!--指定yarn web訪問地址,否則查看application實例信息,出現鏈接錯誤-->

                <property>
                  <name>yarn.resourcemanager.webapp.address.rm1</name>
                  <value>hadoopH3:8088</value>
                </property>
                <property>
                  <name>yarn.resourcemanager.webapp.address.rm2</name>
                  <value>hadoopH4:8088</value>
                </property>

                </configuration>
            

6.修改slaves

其中start-dfs.sh會去調用core-site.xml獲取NameNode信息,本地登陸NamdNode節點,調用slaves文件獲取DataNode信息,遠程登陸DataNode節點(需要輸入密碼)。

(slaves是指定子節點的位置,因為要在hadoopH1上啟動HDFS、在hadoopH3啟動yarn,所以hadoopH1上的slaves文件指定的是datanode的位置,hadoopH3上的slaves文件指定的是nodemanager的位置)

hadoopH5
hadoopH6
hadoopH7

7.配置免密碼登陸

其中start-yarn.sh啟動hadoopH3,是使用本地啟動,不需要遠程登陸 hadoopH4的啟動需要手動啟動,可以修改start-yarn文件使得同start-dfs一樣可遠程啟動備用節點

(1)首先要配置hadoopH1到hadoopH1、hadoopH2、hadoopH5、hadoopH6、hadoopH7的免密碼登陸

在hadoopH1中產生一個密鑰

ssh-keygen -t rsa

將公鑰拷貝到其他節點,包括自己:

ssh-copy-id hadoopH1
ssh-copy-id hadoopH2
ssh-copy-id hadoopH5
ssh-copy-id hadoopH6
ssh-copy-id hadoopH7

(2)配置hadoopH3到hadoopH5、hadoopH6、hadoopH7的免密碼登陸

在hadoopH3上生產一對鑰匙

ssh-keygen -t rsa

將公鑰拷貝到其他節點

ssh-copy-id hadoopH5
ssh-copy-id hadoopH6
ssh-copy-id hadoopH7

(3)兩個namenode之間要配置ssh免密碼登陸,別忘了配置hadoopH2到hadoopH1的免登陸

在hadoopH2上生產一對鑰匙

ssh-keygen -t rsa

將公鑰拷貝到HadoopH1

ssh-copy-id -i hadoopH1    

(五)將配置好的Hadoop拷貝到其他節點

四:集群啟動

(一)啟動zookeeper集群(分別在hadoopH5、hadoopH6、hadoopH7上啟動zk)

cd /home//hadoop/App/apache-zookeeper-3.5.6-bin/bin/
./zkServer.sh start
#查看狀態:一個leader,兩個follower
./zkServer.sh status

 

(二)啟動journalnode(分別在hadoopH5、hadoopH6、hadoopH7上執行)

cd /home//hadoop/App/hadoop-2.7.1/sbin./hadoop-daemon.sh start journalnode
#運行jps命令檢驗,hadoopH5、hadoopH6、hadoopH7上多了JournalNode進程

 

(三)格式化HDFS

#在hadoopH1上執行命令:
hadoop namenode -format
#格式化后會在根據core-site.xml中的hadoop.tmp.dir配置,生成一些文件,我們需要將這個目錄下的文件拷貝到standby狀態的namenode節點下
可以使用scp -r 命令 例:scp -r ./data/ hadoopH2:/home/hadoop/App/hadoop-2.7.1/
##也可以這樣,建議在另一個standby節點機器運行:hadoop namenode -bootstrapStandby      

(四)格式化ZKFC(在hadoopH1上執行即可)

hdfs zkfc -formatZK

會在zookeeper集群上生成節點

(五)啟動HDFS(在hadoopH1上執行)

start-dfs.sh

(六)啟動YARN(在hadoopH3、4上都需要執行)

注意:是在hadoopH3上執行start-yarn.sh,把namenode和resourcemanager分開是因為性能問題,因為他們都要占用大量資源,所以把他們分開了,他們分開了就要分別在不同的機器上啟動)
在hadoopH3中使用:start-yarn.sh    在hadoopH4中使用:yarn-daemon.sh start resourcemanager

補充:HA集群中namenode連接不上journalnode,導致namenode啟動不了

補充:由於多次格式化導致文件上傳出錯File***could only be replicated to 0 nodes instead of minReplication (=1)

五:集群啟動后驗證

(一)節點進程查看

hadoopH1:

hadoopH2:

hadoopH3:

 

hadoopH4:

hadoopH5:

hadoopH6:

hadoopH7: 

注意:有可能出現集群中datanode節點部分不能啟動

直接刪除不能啟動的節點的集群下namenode和datanode節點存放數據的目錄下的數據。再從hadoopH1中再次執行start-dfs.sh即可。

(二)通過瀏覽器訪問

        http://192.168.58.100:50070
        NameNode 'hadoopH1:9000' (active)
        http://192.168.58.101:50070
        NameNode 'hadoopH2:9000' (standby)

 

(三)驗證HDFS HA

1.首先向hdfs上傳一個文件

hadoop fs -mkdir /test
hadoop fs -put jdk-8u241-linux-x64.tar.gz /test/ hadoop fs
-ls /

2.然后再kill掉active的NameNode

kill -9 <pid of NN>

3.通過瀏覽器訪問:http://192.168.58.101:50070

NameNode 'hadoopH2:9000' (active) 這個時候hadoopH2上的NameNode變成了active

4.再執行命令:查看文件

hadoop fs -ls /

剛才上傳的文件依然存在!!!

5.手動啟動那個掛掉的NameNode

hadoop-daemon.sh start namenode

通過瀏覽器訪問:http://192.168.1.201:50070
NameNode 'hadoopH1:9000' (standby)

(四)驗證YARN

運行一下hadoop提供的demo中的WordCount程序:

hadoop jar hadoop-mapreduce-examples-2.7.1.jar wordcount /wordcount/input /wordcount/output

六:hadoop datanode節點超時時間設置 

(一)配置項解釋

datanode進程死亡或者網絡故障造成datanode無法與namenode通信,
namenode不會立即把該節點判定為死亡,要經過一段時間,這段時間暫稱作超時時長。

HDFS默認的超時時長為10分鍾+30秒。如果定義超時時間為timeout,則超時時長的計算公式為: timeout = 2 * heartbeat.recheck.interval + 10 * dfs.heartbeat.interval。 而默認的heartbeat.recheck.interval 大小為5分鍾,dfs.heartbeat.interval默認為3秒。 需要注意的是hdfs-site.xml 配置文件中的 heartbeat.recheck.interval的單位為毫秒, dfs.heartbeat.interval的單位為秒。

所以,舉個例子,如果heartbeat.recheck.interval設置為5000(毫秒),dfs.heartbeat.interval設置為3(秒,默認),則總的超時時間為40秒。

(二)hdfs-site.xml中的參數設置格式:

<property>
<name>heartbeat.recheck.interval</name>
<value>2000</value>
</property>
<property>
<name>dfs.heartbeat.interval</name>
<value>1</value>
</property>

(三)結果測試

先kill一個datanode節點:

結果查看: 

七:HDFS冗余數據塊的自動刪除

注意:要生成冗余塊,則必須設置文件block副本數大於等於2---即一個datanode失效后還存在一個副本,當一個新的節點加入,則會進行數據拷貝!!!

修改hdfs-site.xml文件 文件:

    <property>
            <name>dfs.replication</name>
            <value>2</value>            偽分布指定一個即可
    </property>  

(一)配置項解釋

在日常維護hadoop集群的過程中發現這樣一種情況:

某個節點由於網絡故障或者DataNode進程死亡,被NameNode判定為死亡,
HDFS馬上自動開始數據塊的容錯拷貝;
當該節點重新添加到集群中時,由於該節點上的數據其實並沒有損壞,
所以造成了HDFS上某些block的備份數超過了設定的備份數。
通過觀察發現,這些多余的數據塊經過很長的一段時間才會被完全刪除掉,
那么這個時間取決於什么呢?
該時間的長短跟數據塊報告的間隔時間有關。
Datanode會定期將當前該結點上所有的BLOCK信息報告給Namenode,
參數dfs.blockreport.intervalMsec就是控制這個報告間隔的參數。

(二)hdfs-site.xml文件中有一個參數:

<property>
<name>dfs.blockreport.intervalMsec</name>
<value>10000</value>
<description>Determines block reporting interval in milliseconds.</description>
</property>

其中3600000為默認設置,3600000毫秒,即1個小時,也就是說,塊報告的時間間隔為1個小時,所以經過了很長時間這些多余的塊才被刪除掉。通過實際測試發現,當把該參數調整的稍小一點的時候(60秒),多余的數據塊確實很快就被刪除了。

(三)在六的基礎上,啟動一個新的datanode節點,加入集群 

hadoop-daemon.sh start datanode

注意:該節點也是需要配置到namenode節點的slave文件中,需要保持該datanode節點VERSION中集群號同namenode節點VERSION集群號一致。

(四)恢復被kill的datanode節點 

hadoop-daemon.sh start datanode

八:HA的Java API訪問

只需要修改路徑,其他操作基本一致。

以HDFS上傳文件為例:

package cn.hadoop.ha;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

public class HdfsUtilHA {
    public static void main(String[] args) throws IOException, InterruptedException, URISyntaxException {
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://ns1/"), conf, "hadoop");
        fs.copyFromLocalFile(new Path("C:\\eula.1028.txt"), new Path("hdfs://ns1/"));
    }
}

注意:要將core-site.xml和hdfs-site.xml放入項目src目錄下。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM