環境:
spark 2.3.3
scala 2.11.8
Java 1.8.0_141
本文主要內容:
Spark集羣HA安裝部署
Spark Master HA 主備切換流程
Spark Master HA 在Zookeeper上的持久化
spark集羣安裝部署
節點分佈
|
Master |
Worker |
|
node01.zf.com |
√ |
|
192.168.0.100 |
node02.zf.com |
√ |
√ |
192.168.0.110 |
node03.zf.com |
|
√ |
192.168.0.120 |
修改配置,修改所有節點上的${SPARK_HOME}/conf/spark-env.sh
#配置java的環境變量
export JAVA_HOME=/soft/install/jdk1.8.0_141
#配置zk相關信息
export SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.deploy.zookeeper.url=node01:2181,node02:2181,node03:2181 -Dspark.deploy.zookeeper.dir=/spark"
修改配置,修改所有節點上的${SPARK_HOME}/conf/slaves
node02
node03
啓動前,先查看下zookeeper下有沒有/spark
此時沒有/spark znode
啓動Spark集羣
1.在node01 執行$SPARK_HOME/sbin/start-all.sh
此時會在node01啓動一個Master
從啓動日誌,可以看到
同時,jps
會有一個master進程
此時查看zookeeper下 /spark znode信息
此時/spark znode已經創建,並在在/spark/master_status下面保存兩個worker節點信息
2.此時在node02上,執行$SPARK_HOME/sbin/start-master.sh,再啓動一個master
從啓動日誌和jps信息,可以判斷
此時,查看zookeeper的/spark/leader_election
發現,又進行了一次master elect。
此時通過spark webUI進行確認node01:8080,node02:8080
node01爲active狀態,node02爲standby狀態。
3.驗證HA
kill掉node01 的Master進程,看node02的Master是否變爲active
在node01執行kill 34099, 殺掉Master進程
查看zookeeper
可以看到master發生變化
通過spark webUI
可以看到node02已經重新被選舉爲active,同時也爲從zookeeper中獲取worker信息。
下面從代碼層面來分析下:
org.apache.spark.deploy.master.Master類,在啓動後,會匹配到onStart事件,在onstart方法的最後,會設置持久化方式。
首先獲取RECOVERY_MODE
private val RECOVERY_MODE = conf.get("spark.deploy.recoveryMode", "NONE")
通過spark-env.sh中的配置項-Dspark.deploy.recoveryMode=ZOOKEEPER,可以獲得RECOVERY_MODE爲ZOOKEEPER
而ZooKeeperRecoveryModeFactory.createPersistenceEngine方法
會創建ZooKeeperPersistenceEngine對象
在實例化ZooKeeperPersistenceEngine對象時,會在zookeeper中創建/spark/master_status的znode。
而ZooKeeperRecoveryModeFactory.createLeaderElectionAgent方法會ZooKeeperLeaderElectionAgent對象,用於代理zookeeper選舉領導角色的對象。
在實例化ZooKeeperLeaderElectionAgent對象時,
會痛LeaderLatch對象的leaderLatch.start()方法創建/spark/leader_election znode。具體的調用邏輯如下:
LeaderLatch.start() -> LeaderLatch.internalStart() -> LeaderLatch.reset()
在 LeaderLatch.reset()方法的最後會創建znode
client.create().creatingParentsIfNeeded().withProtection().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).inBackground(callback).forPath(ZKPaths.makePath(latchPath, LOCK_NAME), LeaderSelector.getIdBytes(id));
由於創建的zknode是CreateMode.EPHEMERAL_SEQUENTIAL,在Master掛掉後,該znode會被刪掉