2016-05-27 42 views
3

我有一個使用ZooKeeper進行領導選舉的分佈式應用程序。只有當選的領導者可以提交數據庫。我最近發現有一種潛在的情況可能導致多個領導者。這種情況出現在當選領導人因長期GC而暫停時,可能會失去對ZooKeeper的心跳,導致選舉新領導人。在這一點上,兩個節點都認爲自己是領導者,並可能導致衝突。動物園管理員多領導選舉問題

有關如何避免此類情況的任何建議?

+0

我會首先調查爲什麼GC暫停了這麼久,它可能會導致您出現性能問題。如果GC是唯一的原因,那麼一定要等待更長的時間? –

+0

謝謝明。 GC暫停在大多數大型應用程序中是不可避免的。您可以優化以減少暫停,但完全避免長時間的GC暫停實際上不可能。而且,等待時間更長的問題是,這可能導致長時間沒有領導者的情況。 – Piyg

+1

當然,但是暫停這麼長時間,導致系統認爲它停機並不理想。您可以調整等待時間或縮短暫停時間。 –

回答

1

當您使用ZooKeeper的的領導人選舉,你不能保證領導。它有可能遇到這種情況的特殊性,即使沒有GC暫停。例如,當網絡分區期間領導者與ZooKeeper法定人數隔離時,或領導者發出長時間運行的查詢時,死亡人員和新領導者可在當前仍處於活動狀態時發出新查詢。

解決方法是在更新數據庫時使用比較和設置。一旦選出新領導者,你應該得到一個不斷增加的領導者id(例如,通過更新ZooKeeper中的一個節點並使用其版本或mzxid)並使用它來保護由該領導者發佈的每個交易。

例如,如果你想改變數據庫的狀態,則不要使用以下交易:

BEGIN TRANSACTION; 
db.update($change); 
END TRANSACTION; 

你應該使用類似

BEGIN TRANSACTION; 
if (db.leaderID <= $leaderID) { 
    db.leaderID = $leaderID; 
    db.update($change); 
} 
END TRANSACTION; 

這招會保護您的系統免受不確定性由並行領導者引起。當然你的數據庫應該是線性化的並且支持比較和設置。

+0

啊,我明白了。所以你在選舉後立即把leaderId保存到數據庫中,然後在提交時進行比較和設置。好主意! – Piyg