閱讀922 返回首頁    go 技術社區[雲棲]


最近分布式係統開發小結

用最簡單的語言梳理一下最近十天做的分布式係統模塊的開發。這是一個還在開發中的項目,配圖也是設計原圖。希望能更多地從開源項目裏汲取營養,一邊實戰,一邊積累。


係統概述

最近在設計和開發一個分布式係統的流式處理模塊,整個係統用於跨集群、跨機房搬運不同數據源內的數據到另一份或多份數據源上,包括HDFS、MySQl、MongoDB、FTP等。功能比較像Hadoop的Sqoop,但是能擴展支持更多的數據源,且本身是個集群部署,不像Sqoop需要依賴Hadoop的MR。

我們整個cluster的資源管理借助Mesos來完成,由自己定製的Mesos Scheduler向Mesos Master申請可用的資源,具體把數據搬運的任務分發到Mesos Slave的Executor上,而我主要負責的就是Slave模塊,包括Slave上Executors的實現、不同Slave上Executor之間的通信、消息處理、每次Task的容錯和可靠性等內容。


Executor設計

一共有三種Executors,簡單分為Input、Cache、Output,直觀理解Input就是讀取數據源,Cache用於從input到output的緩存,Output是獲取cache裏的數據,向目標數據源

導出數據。

Executor具體涉及到下麵一些問題:

1.      Executor之間的網絡通信

2.      數據流裏每個Tuple在網絡中的序列化、壓縮等流通問題

3.      消息隊列

4.      其他:多線程、雙隊列緩存設計、狀態記錄等

我們還具體考慮了Input、Cache、Output分別掛掉要怎樣繼續去執行整個數據流的搬運,這裏涉及到了把一些描述和狀態更新統一寫到Zookeeper裏,需要Cache模塊做對消息的鈍化/checkpoint/JournalLog。

整個模塊的設計圖如下:


網絡通信

Netty有很優雅的設計,封裝了Java的網絡NIO接口,還重寫了ChannelBuffer。利用Netty框架,Executors之間的通信簡化為下麵這樣的模式:

我今天參考了Storm0.9.0裏新增加的Netty模塊,優化了下Slave模塊裏的Netty部分。其實Storm裏的Netty部分蠻簡單,比較我們想要做的實現更簡單,主要體現在兩處:

1.  Cache作為Netty Server,既要接收InputClient的寫,又要接受OutputClient的讀請求。

2.  Cache交互的Queue不是一個java concurrent包裏的某個Queue容器,而是一個輕量級的workqueue:beanstalkd

消息隊列

采用的是beanstalkd,每個tube對應一個output,之前的博文介紹了beanstalkd。


數據流通

數據的序列化和反序列化,本來想要使用kryo這樣的在開源軟件中經常見到的高效工具。後來參考了Storm裏的TaskMessage結構,發現不如直接把POJO設計成一個byte[],自己定義一下byte數組的結構來的更高效。畢竟一個java對象轉bytes,再高效也不如直接拚byte[]快。

數據壓縮方麵Snappy有很快的壓縮速度。

Storm設計參考

其實我們的Input比較像Storm的spout,Cache和Output比較像bolt,但是又沒有Storm裏的shuffle grouping等機製,Input與Cache是指定的一對一的,Cache與Output是一對多,而這些對應關係會在物理執行計劃模塊裏生成。

在Storm的設計裏,參考了它的Acker。Storm能保證消息不會丟失,並且每條消息都會被完整處理,即這個tuple以及由這個tuple所導致的所有的tuple都被成功處理。而一個tuple會被認為處理失敗了如果這個消息在timeout所指定的時間內沒有成功處理。能做到這點,他的Acker起到了很重要的作用。(Arker模塊的設計和源碼分析)

我們打算做一個Acker模塊,但消息的執行狀態和更新會寫在znode上,讓Arker模塊與ZK打交道,然後去更新Beanstalkd裏已經reserve了的job。有時間還要把Storm的源碼和模塊仔細讀讀,盡量能多參考一些設計思路。

 

(全文完)

最後更新:2017-04-03 12:54:00

  上一篇:go linux下載:wget命令
  下一篇:go linux驅動開發--內核定時器