storm源碼之一個class解決nimbus單點問題【轉】 【原】storm源碼之一個class解決nimbus單點問題

 本文導讀:html

1 storm nimbus 單節點問題概述 2 storm與解決nimbus單點相關的概念 3 nimbus目前沒法作到多節點的緣由 4 解決nimbus單點問題的關鍵 5 業界對nimbus單點問題的努力 6 nimbus單點問題的解決思路 7 NimbusCloudStorage的實現 8 總結:

 

1、storm nimbus 單節點問題概述java

一、storm集羣在生產環境部署以後,一般會是以下的結構:
                                         
從圖中能夠看出zookeeper和supervisor都是多節點,任意1個zookeeper節點宕機或supervisor節點宕機均不會對系統總體運行形成影響,但nimbus和ui都是單節點。ui的單節點對系統的穩定運行沒有影響,僅提供storm-ui頁面展現統計信息。但nimbus承載了集羣的許多工做,若是nimbus單節點宕機,將會使系統總體的穩定運行形成極大風險。所以解決nimbus的單點問題,將會更加完善storm集羣的穩定性。

二、storm nimbus單節點的風險
(1)功能上,nimbus進程退出後,若是再同時發生worker進程宕機,宕機的worker將沒法重啓,集羣將會有部分消息始終沒法獲得處理。
(2)監控上,nimbus進程不可用時,storm ui將沒法訪問。
(3)概率上,機房因爲演練或故障不可用時即會出現nimbus與worker進程同時故障的情形,面對風險的概率較大。

2、storm與解決nimbus單點相關的概念git

一、【nimbus進程】storm集羣工做的全局指揮官
(1)經過thrift接口,監聽並接收client對topology的submit,將topology代碼保存到本地目錄/nimbus/stormdist/下
(2)爲client提交的topology計算任務分配,根據集羣worker資源狀況,計算出topology的spout和bolt的task應該如何在worker間分配,任務分配結果寫入zookeeper
(3)經過thrift接口,監聽supervisor的下載topology代碼的請求,並提供下載
(4)經過thrift接口,監聽ui對統計信息的讀取,從zookeeper上讀取統計信息,返回給ui
(5)若進程退出後,當即在本機重啓,則不影響集羣運行。

二、【supervisor進程】storm集羣的資源管理者,按需啓動worker進程。
(1)定時從zookeeper檢查是否有代碼未下載到本地的新topology,定時刪除舊topology代碼
(2)根據nimbus的任務分配結果,在本機按需啓動1個或多個worker進程,監控守護全部的worker進程。
(3)若進程退出,當即在本機重啓,則不影響集羣運行。

三、【worker進程】storm集羣的任務構造者,構造spout或bolt的task實例,啓動executor線程。
(1)根據zookeeper上分配的task,在本進程中啓動1個或多個executor線程,將構造好的task實例交給executor去運行(死循環調用spout.nextTuple()或bolt.execute()方法)。
(2)向zookeeper寫入心跳
(3)維持傳輸隊列,發送tuple到其餘的worker
(4)若進程退出,當即在本機重啓,則不影響集羣運行。

四、【executor線程】storm集羣的任務執行者,循環執行task代碼。
(1)執行1個或多個task(每一個task對應spout或bolt的1個並行度),將輸出加入到worker裏的tuple隊列
(2)執行storm內部線程acker,負責發送消息處理狀態給對應spoult所在的worker

【注1】Worker、Executor、Task關係能夠參考 http://www.cnblogs.com/xymqx/p/4374909.html

3、nimbus目前沒法作到多節點的緣由github

一、nimbus節點的ip地址在配置文件中storm.yaml,更換機器後ip地址變化,須要更新集羣全部節點的配置文件後重啓集羣
二、客戶端submitTopology時也須要取得nimbus ip上傳代碼。nimbus更換機器後,client也須要修改配置文件
三、nimbus機器的本地硬盤存放了topology的代碼,更換機器後代碼所有丟失,新啓動的supervisor將沒法下載正在運行的topology代碼
四、storm ui是從nimbus讀取集羣統計信息的,nimbus更換機器後ui也須要修改配置文件後重啓。
五、同時啓動多個nimbus節點,會面臨多個nimbus併發計算topology的任務分配,併發寫入zookeeper,併發清理zookeeper等諸多不可預料的問題。即便存在多個nimbus節點,storm-ui、supervisor、client等也只會使用配置文件指定的ip的節點。
                                                                
【注】storm在設計之初就作到了節點進程間經過zookeeper鬆散耦合,進程相對獨立,單個進程的退出不會影響集羣運行,所以nimbus作到多節點並不存在十分巨大的困難。但做者@Nathanmarz認爲nimbus單節點問題並非storm最緊急和嚴重的問題,所以在0.8.2版本以前nimbus ip地址依舊是在配置文件。

4、解決nimbus單點問題的關鍵併發

一、supervisor、client、ui對nimbus節點ip動態獲取,而非由配置文件指定。
二、在nimbus更換機器後,supervisor仍然可隨時下載到topology的代碼

5、業界對nimbus單點問題的努力jvm

一、storm做者Nathanmarz對高可用的nimbus提出了這樣的規劃分佈式

  • nimbus目前的本地存儲topology代碼方式須要更加靈活,好比既支持本地存儲,也支持分佈式存儲
  • nimbus節點之間須要實現基於zookeeper的自選舉機制
  • 客戶端可以經過zookeeper找到nimbus leader的ip地址來submit topology

二、來自俄羅斯的@Frostmanfork了storm-0.8.2,並在此版本基礎上着手實現Nathanmarz對nimbus-ha的規劃。Frostman抽象出了INimbusStorage.java存儲接口:post

複製代碼
1 public interface INimbusStorage {
2     void init(Map conf);
3     InputStream open(String path);
4     OutputStream create(String path);
5     List<String> list(String path);
6     void delete(String path);
7     void mkdirs(String path);
8     boolean isSupportDistributed();
9 }
複製代碼

【注1】INimbusStorage爲topology代碼的分佈式存儲與本地存儲預留了接口,Forstman同時提供了本地存儲實現類storage.clj
【注2】Nathanmarz所以在0.8.2版本的基礎上,新開了storm-0.8.2-ha分支,專門用來解決nimbus單點問題,並將Frostman已完成的nimbus-storage代碼合併到該分支。

三、Frostman在nimbus-storage基礎上繼續增長了nimbus多節點選舉機制,(目前還沒有被Nathanmarz合併入storm-ha分支)。
    nimbus多節點選舉機制真正實現了nimbus的多節點啓動。nimbus進程啓動後即經過搶佔zookeeper的InterProcessMutex鎖成爲leader,非leader的nimbus進程一直處於block狀態,不進行後續工做,當leader宕機時,搶佔到鎖的下1個節點成爲新leader。由此解決了多nimbus進程會併發讀寫zookeeper的問題。
Frostman同時將全部配置文件中的nimbus ip地址轉移到了zookeeper中存儲leader ip地址,並在storm-ui中增長了nimbus多節點leader狀態的展現。
                                  
但因爲本地存儲是不支持分佈式的,即沒法同時啓動多個nimbus節點(非leader節點無topology代碼),所以其選舉功能也僅限於演示,沒法實際運用。

四、來自yahoo的@anfeng (twitter @Andy Feng)試圖將nimbus及ui使用的端口號由配置文件指定改成自動查找可用端口,但做者建議其在Frostman的nimbus-ha基礎上增長此feature,這樣storm-ha將更加趨於智能化。

6、nimbus單點問題的解決思路ui

一、Frostman的工做已爲完全解決nimbus單點問題奠基了重要基礎:google

  • nimbus ip地址動態獲取
  • topology代碼存儲方案可定製
  • nimbus多節點選舉,宕機自動切換
  • nimbus leader狀態ui展現

在Frostman工做的基礎上繼續深刻,將極大減小工做量。

二、Frostman並未解決topology代碼如何在多個nimbus節點或集羣全部節點間共享的問題。Nathamarz的理想規劃是:實現storm集羣中全部nimbus、supervisor機器之間經過P2P協議共享topology代碼,但目前限於BitTorrent未完成的工做,目前暫停了nimbus-ha分支的開發。

三、最終選定的解決方案:實現定製的nimbus-storage插件NimbusCloudStorage,使得全部nimbus節點在啓動後均從leader 輪詢下載本地不存在的topology代碼。依次知足supervisor在nimbus節點切換後下載代碼的需求。

7、NimbusCloudStorage的實現

                   
一、 工做機制

  在nimbus進程啓動後,NimbusCloudStorage會啓動1個新的線程,定時輪詢zookeeper上正在運行的topology id,並依此比對本地存儲的代碼中是否有未下載的,一旦發現代碼未下載,則從zookeeper獲取nimbus leader節點的ip,並向其請求下載topology的代碼。

二、 使用方法

  在storm/conf/storm/yaml配置文件中增長【nimbus.storage: "backtype.storm.nimbus.NimbusCloudStorage"】便可

【注】Frostman已經2個月沒看github了,⊙﹏⊙b汗,致使NimbusCloudStorage的pull request一直處於open狀態。目前新的工做一直在fork出來的storm-ha分支commit,本地編譯release版本storm-0.8.2-tb。

總結:

    基於開源社區對storm-nimbus-ha的推動,經過實現新的storage插件既解決了nimbus-ha方案中重要的topology代碼共享問題,又避免了對storm源碼的過分侵入,實現了1個class解決nimbus-ha問題,爲實現nimbus-ha提供了一種思路。其中,NimbusCloudStorage實現源碼參見GitHub

 

【原】storm源碼之一個class解決nimbus單點問題

相關文章
相關標籤/搜索