Storm在1.0之后對(duì)nimbus支持了HA,根據(jù)官方提供的文檔,同樣是利用了zk來(lái)做分布式鎖,并且配置文件中新增了storm.seeds,而原來(lái)的storm.hosts改為deprecated。但是nimbus如果想成為leader,必須有一個(gè)先決條件就是這個(gè)nimbus本地必須包含所有的topo的代碼(code),否則這個(gè)nimbus是不會(huì)接受leader角色的。
首先看啟動(dòng),nimbus的啟動(dòng)通過(guò)命令行的方式./storm nimbus,在啟動(dòng)腳本中又調(diào)用storm.py的腳本,而這個(gè)python腳本則直接指向了
o.a.s.d.nimbus
、


在初始化的過(guò)程中,首先實(shí)現(xiàn)了INimbus的接口

接下來(lái),-lauch方法對(duì)配置文件做了解析,然后實(shí)際啟動(dòng)server是launch-server方法

launch-server方法做了如下幾件事情

1. 驗(yàn)證是否為本地模式,如果是local模式則拋異常
2. 驗(yàn)證端口是否可用,就是配置文件中的thrift.server的端口
3. 注意service-handler這個(gè)方法,在它的內(nèi)部其實(shí)做了很多事情
接下來(lái)看看service-handler這個(gè)方法,service-handler定義了一系列的方法,這些方法都是用于提供對(duì)外服務(wù)。
首先service-handler通過(guò)let綁定了nimbus (nimbus-data conf inimbus), nimbus-data其實(shí)提供了許多運(yùn)行時(shí)需要的nimbus數(shù)據(jù)。

這里只談HA,在nimbus-data中有這樣一對(duì)鍵值對(duì)

而zk-leader-elector利用了zk的leader-latch做leader選舉
nimbus.clj下的這一段是定時(shí)從其他nimbus同步代碼的核心

在這里,blob-sync做了在不同nimbus上同步sync。這里的注釋寫(xiě)的很明白,定期去同步其他nimbus的code。blob-sync是個(gè)多態(tài)方法。首先看看下面這個(gè)邏輯
1. 判斷是不是leader,如果不是leader,轉(zhuǎn)到2(是leader就有全部的code了,自然不需要做其他事情)
2. 構(gòu)建一個(gè)BlobSyncronizer對(duì)象,執(zhí)行syncBlobs方法

blob-sync方法中通過(guò)let綁定的值有幾個(gè),這里可以看一下相對(duì)比較復(fù)雜的zk-key-set,這個(gè)zk-key-set綁定了一個(gè)set的數(shù)據(jù)結(jié)構(gòu),
而這個(gè)set的數(shù)據(jù)結(jié)構(gòu)的值又是來(lái)源于storm-cluster-stat的blobstore方法。那么現(xiàn)在就看看storm-cluster-state方法是怎么來(lái)的。
可以看到通過(guò)追溯代碼,能夠發(fā)現(xiàn)其來(lái)源于nimbus-data的一個(gè)綁定,這個(gè)綁定中的一個(gè)方法就是mk-storm-cluster-state.

那么mk-storm-cluster-state這個(gè)方法有做了什么呢?
讓我們進(jìn)入定義它的cluster.clj去看一下。

這里詳細(xì)解釋了cluster-state的來(lái)源,其實(shí)它是通過(guò)mk-distributed-cluster-state方法創(chuàng)建出來(lái)的一個(gè)對(duì)象,而這個(gè)對(duì)象就是通過(guò)反射得到的org.apache.storm.cluster_state.zookeeper_state_factory這樣一個(gè)對(duì)象

弄清楚cluster-state的來(lái)源,我們回頭再看zk-key-set的blobstore方法

這個(gè)方法其實(shí)就是調(diào)用了org.apache.storm.cluster_state.zookeeper_state_factory的幾個(gè)方法。至于sync_path和get_chmk的邏輯就不再贅述了。
blob-sync方法在做完綁定之后,執(zhí)行了syncBlobs方法,這個(gè)方法定義在BlobSyncronizer中。首先這個(gè)方法利用synchronized表明這是個(gè)同步方法。這個(gè)方法中
1. ?刪除不在zk上,而在blobstore中的key

2. updateKeySetForBlobStore,這個(gè)方法里檢查了zk上所有的最近一個(gè)version的blobstore,并且檢查當(dāng)前的nimbus是否含有這個(gè)最近版本的key。如果沒(méi)有,那么則在zk上創(chuàng)建一個(gè)。而創(chuàng)建的方法則是通過(guò)thrift接口調(diào)用createStateInZookeeper實(shí)現(xiàn)的


3. 既然zk上的路徑也創(chuàng)建了,那么接下來(lái)就應(yīng)該創(chuàng)建本地文件了(如何下載的沒(méi)有深究,好像是用到了bt協(xié)議?)

這樣就完成了HA的分析,總結(jié)一下:
通過(guò)定時(shí)任務(wù),定時(shí)去檢查是否有未下載的blob,如果有則下去下載。另外通過(guò)zk的leader-latch做選舉,
如果被選為leader,那么需要檢查是否有足夠多的key,如果沒(méi)有則放棄。