922
技術社區[雲棲]
最近分布式係統開發小結
用最簡單的語言梳理一下最近十天做的分布式係統模塊的開發。這是一個還在開發中的項目,配圖也是設計原圖。希望能更多地從開源項目裏汲取營養,一邊實戰,一邊積累。
係統概述
最近在設計和開發一個分布式係統的流式處理模塊,整個係統用於跨集群、跨機房搬運不同數據源內的數據到另一份或多份數據源上,包括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。
整個模塊的設計圖如下:
網絡通信

我今天參考了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