Hadoop學習03——高可用HA搭建

這是我參與更文挑戰的第11天,活動詳情查看:更文挑戰html

高可用HA

概念

1、hadoop1.0的侷限

  1. namenode的問題
    • 單點故障:只有一個namenode
    • 單點瓶頸:一個namenode,可能內存不足以管理全部datanode

2、高可用(high availability)

  • 用於解決單點故障
  • hadoop2.0只支持2個節點的HA,3.0能夠一主多從
  • 若是主節點(master)出現故障,就轉到備用節點(stand by)
  1. HA的架構

01.jpg

  • HDFS的高可靠性(HA)主要體如今利用zookeeper實現主備NameNode,以解決單點NameNode故障問題。
  • ZooKeeper主要用來存儲HA下的狀態文件,主備信息。 ZK個數建議3個及以上且爲奇數

java

  • NameNode主備模式,主提供服務,備同步主元數據並做爲主的熱備。
  • ZKFC(ZooKeeper Failover Controller)用於監控NameNode節點的主備狀態。
  • JN(JournalNode)用於存儲Active NameNode生成的Editlog。 Standby NameNode加載JN上Editlog,同步元數據。
  • ZKFC控制NameNode主備仲裁
    • ZKFC做爲一個精簡的仲裁代理,其利用zookeeper的分佈式鎖功能,實現主備仲裁,再經過命令通道,控制NameNode的主備狀態。 ZKFC與NN部署在一塊兒,二者個數相同。
  • 元數據同步
  1. 兩個NN的數據同步:兩個namenode並非同時在工做,同時間只有一個NN在工做
    1. 兩個NN必須同步數據信息
      • 塊位置信息(block imformation),它是由datanode處理的,而且要向NN彙報————動態數據信息
      • 偏移量,大小,id,這些都是由NN本身來處理完成————靜態信息
    2. 動態信息的同步
      • 由DN向NN彙報
      • 由原來的DN向單一NN彙報變成向多個NN彙報
    3. 靜態信息的同步
      • 既然靜態數據信息都由NN本身處理完成,那麼有兩個NN,要怎麼同步這兩個NN的信息呢?
        • 使用journalnode集羣
      • 把多個journalnode節點部署在不一樣的服務器上,其實每一個節點都是接收相同信息,多個節點就是爲了防止單點故障
      • 主NN把數據往journalnode節點裏寫,備份NN從journalnode裏讀數據
      • 過半機制(弱一致性):容許一小半的journalnode節點失效
        • 主NN寫數據不必定要全部journalnode都肯定寫入完成,容許有一小半失效
        • 通常會配置奇數個journalnode節點
        • 好比3個容許1個失效,5個容許兩個失效
  2. 元數據持久化
    • 主NameNode對外提供服務。生成的Editlog同時寫入本地和JN,同時更新主NameNode內存中的元數據。
    • 備NameNode監控到JN上Editlog變化時,加載Editlog進內存,生成新的與主NameNode同樣的元數據。元數據同步完成。
    • 主備的FSImage仍保存在各自的磁盤中,不發生交互。 FSImage是內存中元數據定時寫到本地磁盤的副本,也叫元數據鏡像

02.png

  • EditLog:記錄用戶的操做日誌,用以在FSImage的基礎上生成新的文件系統鏡像。
  • FSImage:用以階段性保存文件鏡像。
  • FSImage.ckpt:在內存中對fsimage文件和EditLog文件合併(merge)後產生新的fsimage,寫到磁盤上,這個過程叫checkpoint.。備用NameNode加載完fsimage和EditLog文件後,會將merge後的結果同時寫到本地磁盤和NFS。此時磁盤上有一份原始的fsimage文件和一份新生成的checkpoint文件: fsimage.ckpt. 然後將fsimage.ckpt更名爲fsimage(覆蓋原有的fsimage)。
  • EditLog.new: NameNode每隔1小時或Editlog滿64MB就觸發合併,合併時,將數據傳到Standby NameNode時,因數據讀寫不能同步進行,此時NameNode產生一個新的日誌文件Editlog.new用來存放這段時間的操做日誌。 Standby NameNode合併成fsimage後回傳給主NameNode替換掉原有fsimage,並將Editlog.new 命名爲Editlog。
  1. zookeeper集羣
    • 主NN發生故障時,用於自動切換NN
    • zookeeper會把zkfc進程部署在NN上,進行選舉和健康檢查,一旦發現NN掛掉了,就會通知stand by NN(注意,zookeeper只會監控狀態,切換主從都是NN本身決定的)
    • 一旦主NN掛掉,它當即切換爲stand by,而另外一個NN自動切換爲active

3、聯邦(federation)

  • 解決單點瓶頸
  1. 架構

03.png

  • 產生緣由:單Active NN的架構使得HDFS在集羣擴展性和性能上都有潛在的問題,當集羣大到必定程度後, NN進程使用的內存可能會達到上百G, NN成爲了性能的瓶頸。
  • 應用場景:超大規模文件存儲。如互聯網公司存儲用戶行爲數據、電信歷史數據、語音數據等超大規模數據存儲。此時NameNode的內存不足以支撐如此龐大的集羣。
  • 經常使用的估算公式爲1G對應1百萬個塊,按缺省塊大小計算的話,大概是128T (這個估算比例是有比較大的富裕的,其實,即便是每一個文件只有一個塊,全部元數據信息也不會有1KB/block)。
  • Federation簡單理解:各NameNode負責本身所屬的目錄。與Linux掛載磁盤到目錄相似,此時每一個NameNode只負責整個hdfs集羣中部分目錄。如NameNode1負責/database目錄,那麼在/database目錄下的文件元數據都由NameNode1負責。各NameNode間元數據不共享,每一個NameNode都有對應的standby。
  • 塊池(block pool) :屬於某一命名空間(NS)的一組文件塊。
  • 聯邦環境下,每一個namenode維護一個命名空間卷(namespace volume),包括命名空間的元數據和在該空間下的文件的全部數據塊的塊池。
  • namenode之間是相互獨立的,兩兩之間並不互相通訊,一個失效也不會影響其餘namenode。
  • datanode向集羣中全部namenode註冊,爲集羣中的全部塊池存儲數據。
  • ameSpace(NS):命名空間。 HDFS的命名空間包含目錄、文件和塊。能夠理解爲NameNode所屬的邏輯目錄。

HA高可用搭建

1、各服務節點安裝位置

04.png

  • ZK位置任意,必須先啓動(它要肯定主NN)
  • ZKFC必須在NN上
  • JNN位置任意

2、準備

  1. 實現node1和node2之間免密登陸
    • 因爲node一、node2都爲NN,所以它們故障時須要切換,因此這兩個node之間要配置SSH免密

3、配置hdfs-site.xml

  1. dfs.nameservices - the logical name for this new nameservice
    • 主節點服務id(這裏配置的是mycluser)
    • 提供了惟一的一個名稱,指向須要作主從配置的兩個namenode節點
    • 至關與是一個入口
    • 這個名字只是表明一隊主從(hadoop2.0只能有兩個NN),若是要作聯邦,那麼能夠用逗號隔開不一樣的id名
<property>
  <name>dfs.nameservices</name>
  <value>mycluster</value>
</property>
複製代碼
  1. dfs.ha.namenodes.[nameservice ID] - unique identifiers for each NameNode in the nameservice
    • 指定哪些NN是上面的id所屬的服務
    • 能夠看出下面的nn1,nn2也是邏輯名
    • 但能夠指出上面配置的nameservices指向哪些NN
    • dfs.ha.namenodes.mycluster最後一個詞是上面的nameservices的id
<property>
  <name>dfs.ha.namenodes.mycluster</name>
  <value>nn1,nn2</value>
</property>
複製代碼
  1. dfs.namenode.rpc-address.[nameservice ID].[name node ID] - the fully-qualified RPC(remote produce call) address for each NameNode to listen on
    • 經過這個配置映射到真正的namenode地址
<property>
  <name>dfs.namenode.rpc-address.mycluster.nn1</name>
  //物理機的ip地址
  <value>node1:8020</value>
</property>
<property>
  <name>dfs.namenode.rpc-address.mycluster.nn2</name>
  <value>node2:8020</value>
</property>
複製代碼
  1. dfs.namenode.http-address.[nameservice ID].[name node ID] - the fully-qualified HTTP address for each NameNode to listen on
    • 給瀏覽器提供服務,用瀏覽器訪問hadoop集羣
    • 端口是50070
<property>
  <name>dfs.namenode.http-address.mycluster.nn1</name>
  <value>node1:50070</value>
</property>
<property>
  <name>dfs.namenode.http-address.mycluster.nn2</name>
  <value>node2:50070</value>
</property>
複製代碼
  1. dfs.namenode.shared.edits.dir - the URI which identifies the group of JNs where the NameNodes will write/read edits
    • journalnode部署在哪些服務器上,對外通信的地址是什麼
<property>
  <name>dfs.namenode.shared.edits.dir</name>
  <value>qjournal://node2:8485;node3:8485;node4:8485/mycluster</value>
</property>
複製代碼
  1. dfs.client.failover.proxy.provider.[nameservice ID] - the Java class that HDFS clients use to contact the Active NameNode
    • 故障轉移的時候使用的java代理類是什麼
<property>
  <name>dfs.client.failover.proxy.provider.mycluster</name>
  <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
複製代碼
  1. dfs.ha.fencing.methods - a list of scripts or Java classes which will be used to fence the Active NameNode during a failover
    • 當一個NN發生故障的時候要當即把它隔離,不然會形成腦裂;而另外一個會當即變爲active
//採用ssh方式隔離
<property>
  <name>dfs.ha.fencing.methods</name>
  <value>sshfence</value>
</property>

<property>
  <name>dfs.ha.fencing.ssh.private-key-files</name>
  <value>/root/.ssh/id_dsa</value>
</property>
複製代碼
  1. fs.defaultFS - the default path prefix used by the Hadoop FS client when none is given
    • 配置在core-site.xml文件中
    • 配置客戶端訪問HA的hasoop的邏輯路徑,使用以前的nameservice ID做爲hdfs path
<property>
  <name>fs.defaultFS</name>
  #注意這裏手打mycluster時千萬不要打成mycluser
  <value>hdfs://mycluster</value>
</property>

//以前是下面這樣配置的,只有一個namenode,因此直接配置了哪一個NN的路徑,這裏使用服務id
<property>
        <name>fs.defaultFS</name>
        <value>hdfs://node1:9000</value>
    </property>
    
    
//順便再作一個修改
//把NN和DN存儲數據位置的目錄再改變一下
 <property>
        <name>hadoop.tmp.dir</name>
        <value>/var/hadoop/ha</value>
    </property>
複製代碼
  1. dfs.journalnode.edits.dir - the path where the JournalNode daemon will store its local state
    • journalnode產生的日誌存在節點的哪一個目錄下
<property>
  <name>dfs.journalnode.edits.dir</name>
  <value>/var/hadoop/ha/journalnode</value>
</property>
複製代碼

4、配置zookeeper

  1. The configuration of automatic failover requires the addition of two new parameters to your configuration. In your hdfs-site.xml file, add:
<property>
   <name>dfs.ha.automatic-failover.enabled</name>
   <value>true</value>
 </property>
複製代碼
  1. This specifies that the cluster should be set up for automatic failover. In your core-site.xml file, add:
<property>
   <name>ha.zookeeper.quorum</name>
   <value>node2:2181,node3:2181,node4:2181</value>
 </property>
複製代碼

5、啓動前準備

  1. 把修改好的core-site.xml和hdfs-site.xml分發到其餘節點

6、zookeeper配置文件修改

  1. 打開zookeeper軟件的/conf/zoo_sample.cfg目錄
#1. 更名
mv zoo_sample.cfg zoo.cfg 

#2. 配置文件修改
#autopurge.purgeInterval=1
#autopurge.purgeInterval=1
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
//這裏要修改,這個目錄不存在,要手動建立
dataDir=/var/hadoop/zk
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
//添加下面三行(有幾臺服務器參與,以繼通訊端口)
server.1=node2:2888:3888
server.2=node3:2888:3888
server.3=node4:2888:3888
複製代碼
  1. 添加幾個文件
    • 上面修改了zookeeper配置文件,添加了路徑/var/hadoop/zk
    • 在每個要配置zookeeper服務的節點上都要在這個目錄的下面建立文件myid
    //三臺服務器上
    echo 1 >> /var/hadoop/zk/myid
    echo 2 >> /var/hadoop/zk/myid
    echo 3 >> /var/hadoop/zk/myid
    複製代碼
  2. 配置zookeeper環境變量

7、執行

  1. 啓動zookeeper
    • 啓動命令zkServer.sh start
    • 做用在node2,node3,node4
    • 啓動後,狀態以下
    [root@node4 hadoop]# jps
    7590 QuorumPeerMain
    7607 Jps
    複製代碼
    • 能夠經過命令查看每一個節點的狀態
    [root@node4 conf]# zkServer.sh status
    JMX enabled by default
    Using config: /opt/hadoop/zookeeper-3.4.6/bin/../conf/zoo.cfg
    //說明這個節點是zookeeper集羣主節點
    Mode: leader
    複製代碼
  2. 啓動journalnode(第一次啓動集羣時執行,之後不用執行)
    • 啓動命令:hadoop-daemon.sh start journalnode
    • 做用在node1,node2,node2
    • 產生了一個新的進程
    [root@node1 hadoop]# jps
    7912 Jps
    7866 JournalNode
    複製代碼
  3. 格式化hdfs(第一次啓動集羣時執行,之後不用執行)
    • 隨機選擇一個NN執行hdfs namenode -format
    • 只需在一個節點上執行一遍格式化命令,屢次執行的話,集羣id就不一致了
    • 那麼咱們有兩個NN,怎麼讓它們兩個都格式化呢?
      • 先啓動格式化好的那個NNhadoop-daemon.sh start namenode
      //該NN現有進程
      [root@node1 ~]# jps
      6673 Jps
      6603 NameNode
      6462 JournalNode
      複製代碼
      • 在另外一個NN上執行hdfs namenode -bootstrapStandby把啓動的那個NN的數據複製到這臺NN所在服務器上
  4. hdfs在zookeeper上註冊(第一次啓動集羣時執行,之後不用執行)
    • hdfs在zookeeper上建立本身的節點
    • 使用命令hdfs zkfc -formatZK
    • zookeeper能夠同時維護多個集羣的信息,因此這個命令的意思就是把這個集羣的信息格式化到zookeeper上
    • zookeeper會建立一個/hadoop-ha/mycluster目錄在保存這個集羣的全部信息
  5. 啓動集羣
    • start-dfs.sh
    • 要說明的是zkfc進程不須要手動啓動,它會隨集羣本身啓動
    //node1
    [root@node1 ~]# jps
    7185 Jps
    6603 NameNode
    7116 DFSZKFailoverController
    6462 JournalNode
    
    //node2
    [root@node2 ~]# jps
    6945 Jps
    6770 DataNode
    6899 DFSZKFailoverController
    6700 NameNode
    6445 QuorumPeerMain
    6494 JournalNode
    
    //node3
    [root@node3 ~]# jps
    6629 DataNode
    6492 JournalNode
    6718 Jps
    6447 QuorumPeerMain
    
    //node4
    [root@node4 ~]# jps
    6454 QuorumPeerMain
    6598 DataNode
    6667 Jps
    複製代碼
相關文章
相關標籤/搜索