fourinone分佈式協調設計解析

分佈式協同是分佈式應用中不可缺少的,通常擔任協調者的角色,或者說是將多機協同的職責從分佈式應用中獨立出來,以減少系統的耦合性和增強擴充性。Apache的Zookeeper, google的Chubby都是分佈式協同的實現者。fourinone實際上可以單獨當做Zookeeper用,它使用最少的代碼實現了Zookeeper的所有功能,並且力圖做到功能更強但是使用更簡潔。

一、實現原理
fourinone對分佈式協同的實現, 是通過建立一個domain,node兩層結構的節點信息去完成,domain可以是分類或者包,node可以是具體屬性,domain和node都是自己根據需求設計命名,比如可以將domain命名爲“a.b.c...”表示一個樹型類目。
一個domain下可以有很多個node,每個node只指定一個domain,可以通過domain返回它下面所有的node。
domain不需要單獨建立,通常在建立node時,如果不存在domain會自動創建。
如果domain下沒有node了,該domain會自動刪除。
如果刪除domain,該domain下面node也都會刪除。
每個node下可以存放一個值,可以是任意對象。
所有的節點信息存放在parkserver裏,parkserver提供協同者的功能。如下圖所示:



從上圖可以看到,其他分佈式進程可以通過parkserver的用戶接口ParkLocal,對節點進行增加、修改、刪除、指定心跳、指定權限等操作,並且結合parkserver提供同步備份、領導者選舉、過期時間設置等功能,共同來實現衆多分佈式協同功能,比如:
1、分佈式配置,多個機器的應用公用一個配置信息,並且掛掉能夠領導者選舉,詳細見指南和demo
2、分佈式鎖,多個機器競爭一個鎖,當某個機器釋放鎖或者掛掉,其他機器可以競爭到鎖繼續,詳細見指南和demo
3、集羣管理,集羣內機器可以互相感知和領導者選舉,詳見指南和demo

二、核心API
ParkLocal核心api說明:
//創建node,可以根據是否需要權限和心跳屬性調用不同方法
public ObjectBean create(String domain, Serializable obj);//自動創建node
public ObjectBean create(String domain, String node, Serializable obj);
public ObjectBean create(String domain, String node, Serializable obj, AuthPolicy auth);
public ObjectBean create(String domain, String node, Serializable obj, boolean heartbeat);
public ObjectBean create(String domain, String node, Serializable obj, AuthPolicy auth, boolean heartbeat);

//更新node 
public ObjectBean update(String domain, String node, Serializable obj);

//獲取node
public ObjectBean get(String domain, String node);
//獲取最新node,需要傳入舊node進行對照 
public ObjectBean getLastest(String domain, String node, ObjectBean ob);
//獲取最新domain
public List<ObjectBean> get(String domain);
//獲取最新domain下所有node,需要傳入舊的node集合對照
public List<ObjectBean> getLastest(String domain, List<ObjectBean> oblist);
//刪除node
public ObjectBean delete(String domain, String node);
//強行設置domain可刪除
public boolean setDeletable(String domain);
//刪除domain及下所有node
public List<ObjectBean> delete(String domain);
//添加node的事件監聽
public void addLastestListener(String domain, String node, ObjectBean ob, LastestListener liser);
//添加domain的事件監聽
public void addLastestListener(String domain, List<ObjectBean> oblist, LastestListener liser);


三、權限機制:
public ObjectBean create(String domain, String node, Serializable obj, AuthPolicy auth);
通過上面方法創建node時,可以指定一個權限參數,有隻讀(AuthPolicy.OP_READ)、讀寫(AuthPolicy.OP_READ_WRITE)、所有(AuthPolicy.OP_ALL)三種屬性,默認爲AuthPolicy.OP_ALL

注意:這裏的權限屬性是指創建進程對其他使用進程的權限約束,而不包括它自己。也就是對node的創建進程來說,它擁有對該node和domain所有操作權限(讀寫刪,只要它不退出或者中止)

建設現在創建了一個domain爲d,node爲n的節點, 對於其他使用進程來說,操作權限如下表所示:


從上表可以發現,當創建進程指定node的權限爲AuthPolicy.OP_ALL時,其他使用進程可以刪除該node,但是不能刪除其domain,這是爲什麼呢?
因爲domain下通常還有其他node,它們的權限並不都是AuthPolicy.OP_ALL,比如還有一個n1的node權限爲AuthPolicy.OP_READ,按照正常操作,該使用進程無法刪除n1,假設它可以刪除domain,那麼它最後間接刪除了n1,於是發生了悖論,因此,爲了避免風險,所有的使用進程只能根據權限刪除node,但是無法刪除domain。

不過你允許承擔這樣的刪除風險,也可以在創建進程裏強行指定該domain可刪除,通過在domain創建後,調用:
public boolean setDeletable(String domain);
該方法只能被domain的創建進程調用,其他使用進程沒有權限調用。
強行指定可刪除後,其他進程可以直接刪除該domain及所含node並忽略後果。

四、相對於zookeeper的優勢
Zookeeper無疑是一款成功的開源產品,並擁有廣泛的信任者和應用場景,和以往一樣,老外作者在apache網站上發佈了一款產品,我們的工程師馬上會虛心的學習和忠心的捍衛,而國產原創的產品往往會遭到百般質疑,因爲我們的原創更多是抄襲和粗製濫造,我們的國產更多是框架集成而不是架構設計,所以這種情感上的傾向性不是一天能改變。
做產品對比和列舉優勢往往容易引起激烈爭論,會被認爲是在宣傳和引導產品使用,實際上在都能滿足功能需求的情況下,選擇使用哪款產品更多的是個政治問題,而不是技術問題,領導意志及工程師本身的熟悉程度和愛好等等都是決定因素。

這裏我們僅僅從技術角度闡述幾點優勢,Zookeeper做爲一個chubby和paxos模仿品,缺乏創新型的設計改進,它仍然存在以下缺點:
1、樹型配置節點的繁瑣複雜,性能低下。爲了保證這種結構,Zookeeper需要維持一套虛擬文件結構的開銷,對於目錄結構深的樹節點,造成性能影響,而配置信息結構實際上往往不一定需要樹結構。

2、“觀察”(watch)機制的僵化設計:zookeeper沒有獲取最新版本信息的方法支持,它只能粗暴的在每次寫入更新等方法時註冊一個watch,當這些方法被調用後就回調,它不考慮信息內容是否變化,對於沒有使信息內容發生改變的更新,zookeeper仍然會回調,並且zookeeper的回調比較呆板,它只能用一次,如果信息持續變化,必須又重新註冊watch。而fourinone的事件處理則可以自由控制是否持續響應信息變化。

3、領導者選舉機制實現的太過侷限,集羣只有兩個節點,zookeeper無法進行領導者選舉,zookeeper的領導者選舉必須要奇數節點的奇怪限制。另外,ZooKeeper的領導者選舉實現雖然比原始的Paxos要簡化,但是它仍然存在領導者(Leader)、跟隨者(Follower)、觀察者(observer)、學習者 (Learner)等衆多角色和跟隨狀態(Following)、尋找狀態(Looking)、觀察狀態(Observing)、領導狀態 (Leading)等複雜狀態。相對於fourinone的領導者選舉,zookeeper仍然不夠直觀簡潔,難以用較少配置和代碼演示。

4、Windows系統上幾乎不支持,需要安裝linux殼,並且僅建議用於學習研究。Fourinone支持windows、linux集羣混合使用。

Fourinone提出一種新的分佈式協同系統設計,在滿足zookeeper所有功能下,並克服了以上缺點,提出了新的配置結構、變化事件機制、簡化的領導者選舉實現,能更好的滿足分佈式協調需求。

五、演示demo
下面是一個操作節點的演示demo,請留意各自節點的權限範圍,程序說明:
1、 ParkServerDemo: 啓動parkserver(它的IP端口已經在配置文件的PARK部分的SERVERS指定
2、 ParkSet:往parkserver裏創建了d1n1、d2n2、d3n3、d4n4共4個節點,分別對應只讀、讀寫,所有,所有+強行刪除權限
3、 ParkGet:依次對d1n1、d2n2、d3n3、d4n4進行讀、寫、刪除、刪除domain操作,觀察結果輸出,如果沒有權限操作,parkserver會輸出信息,並且操作返回的結果對象爲空

啓動命令和順序:
Javac –classpath fourinone.jar; *.java
Java –classpath fourinone.jar; ParkServerDemo
Java –classpath fourinone.jar; ParkSet
Java –classpath fourinone.jar; ParkGet

如果沒有fourinone.jar,可以到以下地址下載:
http://www.skycn.com/soft/68321.html


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章