天天看點

spark 基于ZooKeeper實作HA高可用性以及自動主備切換

北風網spark學習筆記

預設情況下,

standalone cluster manage

r對于worker節點的失敗是具有容錯性的(迄今為止,Spark自身而言對于丢失部分計算工作是有容錯性的,它會将丢失的計算工作遷移到其他worker節點上執行)。然而,排程器是依托于master程序來做出排程決策的,這就會造成單點故障:如果master挂掉了,就沒法送出新的應用程式了。為了解決這個問題,spark提供了兩種高可用性方案,分别是基于zookeeper的HA方案以及基于檔案系統的HA方案。

基于zookeeper的HA方案

概述

使用zookeeper來提供leader選舉以及一些狀态存儲,你可以在叢集中啟動多個master程序,讓它們連接配接到zookeeper執行個體。其中一個master程序會被選舉為leader,其他的master會被指定為standby模式。如果目前的leader master

程序挂掉了,其他的

standby master``會被選舉,進而恢複舊master的狀态。并且恢複作業排程。整個恢複過程(從

leader master

挂掉開始計算)大概會花費1~2分鐘。要注意的是,這隻會推遲排程新的應用程式,master挂掉之前就運作的應用程式是不被影響的。

配置

如果要啟用這個恢複模式,需要在spark-env.sh檔案中,設定

SPARK_DAEMON_JAVA_OPTS

選項:

spark.deploy.recoveryMode		# 設定為ZOOKEEPER來啟用standby master恢複模式(預設為NONE)
spark.deploy.zookeeper.url		# zookeeper叢集url(舉例來說,192.168.75.101:2181,192.168.75.102:2181)
spark.deploy.zookeeper.dir		# zookeeper中用來存儲恢複狀态的目錄(預設是/spark)
           
備注:如果在叢集中啟動了多個master節點,但是沒有正确配置master去使用zookeeper,master在挂掉進行恢複時是會失敗的,因為沒法發現其他master,并且都會認為自己是leader。這會導緻叢集的狀态不是健康的,因為所有master都會自顧自地去排程。

細節

  • 在啟動一個zookeeper叢集之後,啟用高可用性是很直接的。簡單地在多個節點上啟動多個master程序,并且給它們相同的zookeeper配置(

    zookeeper url

    和目錄)。master就可以被動态加入master叢集,并可以在任何時間被移除掉。
  • 為了排程新的應用程式或者向叢集中添加worker節點,它們需要知道目前leader master的ip位址。這可以通過傳遞一個master清單來完成。舉例來說,我們可以将我們的SparkContext連接配接的位址指向

    spark://host1:port1,host2:port2

    。這就會導緻你的

    SparkContext

    嘗試去注冊所有的master,如果host1挂掉了,那麼配置還是正确的,因為會找到新的

    leader master

    ,也就是host2。
  • 對于注冊一個master和普通的操作,這是一個重要的差別。當一個應用程式啟動的時候,或者worker需要被找到并且注冊到目前的

    leader master

    的時候。一旦它成功注冊了,就被儲存在zookeeper中了。如果故障發生了,

    new leader master

    會去聯系所有的之前注冊過的應用程式和worker,并且通知它們master的改變。這樣的話,它們甚至在啟動的時候都不需要知道new master的存在。
  • 正是由于這個屬性,new master可以在任何時間被建立,并且我們唯一需要擔心的一件事情就是新的應用程式和worker可以找到并且注冊到master。一旦注冊上去之後,我們就不用擔心它了。

實驗

  • 192.168.75.101

    機器上的spark叢集先停止
    ./sbin/stop-all.sh
               
  • 修改機器上的spark-env.sh檔案,在其中加入上述三個屬性
    export SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.deploy.zookeeper.url=192.168.75.101:2181,192.168.75.102:2181 -Dspark.deploy.zookeeper.dir=/spark"
               
  • 啟動叢集

    192.168.75.101

    上直接用啟動叢集:

    ./sbin/start-all.sh

  • 192.168.75.102上

    部署spark安裝包,并啟動一個master程序

安裝

scala 2.11.4

  1. 将課程提供的

    scala-2.11.4.tgz

    使用WinSCP拷貝到

    /usr/local/src

    目錄下。
  2. scala-2.11.4.tgz

    進行解壓縮:

    tar -zxvf scala-2.11.4.tgz

  3. 對scala目錄進行重命名:

    mv scala-2.11.4 scala

  4. 配置scala相關的環境變量
    vi ~/.bashrc
    export SCALA_HOME=/usr/local/scala
    export PATH=$SCALA_HOME/bin
    source ~/.bashrc
               
  5. 檢視scala是否安裝成功:

    scala -version

安裝spark用戶端

  1. spark-1.5.1-bin-hadoop2.4.tgz

    使用WinSCP上傳到

    /usr/local/src

    目錄下。
  2. 解壓縮spark包:

    tar -zxvf spark-1.5.1-bin-hadoop2.4.tgz

  3. 重命名spark目錄:

    mv spark-1.5.1-bin-hadoop2.4 spark

  4. 修改spark環境變量
    vi ~/.bashrc
    export SPARK_HOME=/usr/local/spark
    export PATH=$SPARK_HOME/bin
    export CLASSPATH=.:$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
    source ~/.bashrc
               

修改spark-env.sh檔案

cd /usr/local/spark/conf
cp spark-env.sh.template spark-env.sh
vi spark-env.sh
export JAVA_HOME=/usr/java/latest
export SCALA_HOME=/usr/local/scala
export HADOOP_HOME=/usr/local/hadoop
export HADOOP_CONF_DIR=/usr/local/hadoop/etc/hadoop
export SPARK_MASTER_IP=192.168.75.102
export SPARK_DAEMON_MEMORY=100m
export SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.deploy.zookeeper.url=192.168.75.101:2181,192.168.75.102:2181 -Dspark.deploy.zookeeper.dir=/spark"
           

在192.168.1.102上單獨啟動一個standby master程序:

./sbin/start-master.sh

  • 送出應用程式

    将master位址修改為

    192.168.75.101:7077,192.168.75.102:7078

  • 殺掉原先的

    leader master

    ,等到

    standby master

    接管叢集,再次送出應用程式
  • 再次手動啟動原來的

    leader master

    (死掉)

基于檔案系統的HA方案

zookeeper是實作生産級别的高可用性的最佳方式,但是如果你就是想要在master程序挂掉的時候,手動去重新開機它,而不是依靠zookeeper實作自動主備切換,那麼可以使用FILESYSTEM模式。當應用程式和worker都注冊到master之後,master就會将它們的資訊寫入指定的檔案系統目錄中,以便于當master重新開機的時候可以從檔案系統中恢複注冊的應用程式和worker狀态。

配置

要啟用這種恢複模式,需要在

spark-env.sh

中設定

SPARK_DAEMON_JAVA_OPTS

spark.deploy.recoveryMode		# 設定為FILESYSTEM來啟用單點恢複(預設值為NONE)
spark.deploy.recoveryDirectory	# spark在哪個檔案系統目錄記憶體儲狀态資訊,必須是master可以通路的目錄
           

細節

  1. 這個解決方案可以與程序監控或管理器(比如monit)結合使用,或者就僅僅是啟用手動重新開機恢複機制即可。
  2. 檔案系統恢複比不做任何恢複機制肯定是要好的,這個模式更加适合于開發和測試環境,而不是生産環境。此外,通過

    stop-master.sh

    腳本殺掉一個master程序是不會清理它的恢複狀态的,是以當你重新開機一個新的master程序時,它會進入恢複模式。這會增加你的恢複時間至少1分鐘,因為它需要等待之前所有已經注冊的worker等節點先

    timeout。

  3. 這種方式沒有得到官方的支援,也可以使用一個NFS目錄作為恢複目錄。如果原先的master節點完全死掉了,你可以在其他節點上啟動一個master程序,它會正确地恢複之前所有注冊的worker和應用程式。之後的應用程式可以找到新的master,然後注冊。

實驗

  1. 關閉兩台機器上的

    master和worker

  2. 修改

    192.168.75.101

    機器上的

    spark-env.sh

    export SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=FILESYSTEM -Dspark.deploy.recoveryDirectory=/usr/local/spark_recovery"
               
  3. 在`192.168.75.101上啟動spark叢集
  4. spark-shell

    中進行

    wordcount

    計數,到一半,有一個

    running application

  5. 殺掉master程序
  6. 重新開機master程序
  7. 觀察web ui上,是否恢複了worker以及原先正在運作的application

繼續閱讀