zookeeper 筆記--curator分佈式鎖

使用ZK實現分佈式獨佔鎖,

原理就是利用ZK同級節點的惟一性.服務器

Curator框架下的一些分佈式鎖工具
InterProcessMutex:分佈式可重入排它鎖 網絡

InterProcessSemaphoreMutex:分佈式排它鎖 session

InterProcessReadWriteLock:分佈式讀寫鎖框架


 

使用 Zookeeper 實現 leader 選舉分佈式

Leader Latch ide

參與選舉的全部節點,會建立一個順序節點,其中最小的 節點會設置爲 master 節點, 沒搶到 Leader 的節點都監聽前一個節點的刪除事件,在前一個節點刪除後進行從新搶主,當 master 節點手動調用 close()方法或者 master 節點掛了以後,後續的子節點會搶佔 master。 其中 spark 使用的就是這種方法 工具

LeaderSelector ui

LeaderSelector 和 Leader Latch 最的差異在於,leader 能夠釋放領導權之後,還能夠繼續參與競爭this

 

public class LeaderSelectorClient extends LeaderSelectorListenerAdapter implements Closeable {

    private  String name;  //表示當前的進程
    private  LeaderSelector leaderSelector;  //leader選舉的API
    private CountDownLatch countDownLatch=new CountDownLatch(1);

    public LeaderSelectorClient(){

    }

    public LeaderSelectorClient(String name) {
        this.name = name;
    }

    public LeaderSelector getLeaderSelector() {
        return leaderSelector;
    }

    public void setLeaderSelector(LeaderSelector leaderSelector) {
        this.leaderSelector = leaderSelector;
    }

    public void start(){
        leaderSelector.start(); //開始競爭leader
    }

    @Override
    public void takeLeadership(CuratorFramework client) throws Exception {
        //若是進入當前的方法,意味着當前的進程得到了鎖。得到鎖之後,這個方法會被回調
        //這個方法執行結束以後,表示釋放leader權限
        System.out.println(name+"->如今是leader了");
//        countDownLatch.await(); //阻塞當前的進程防止leader丟失
    }

    @Override
    public void close() throws IOException {
        leaderSelector.close();
    }
    private static String CONNECTION_STR="x.x.x.x:2181;

    public static void main(String[] args) throws IOException {
        CuratorFramework curatorFramework = CuratorFrameworkFactory.builder().
                connectString(CONNECTION_STR).sessionTimeoutMs(50000000).
                retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();
        curatorFramework.start();
        LeaderSelectorClient leaderSelectorClient=new LeaderSelectorClient("ClientA");
        LeaderSelector leaderSelector=new LeaderSelector(curatorFramework,"/leader",leaderSelectorClient);
        leaderSelectorClient.setLeaderSelector(leaderSelector);
        leaderSelectorClient.start(); //開始選舉
        System.in.read();
    }
}

 


ZAB 協議介紹

ZAB 協議包含兩種基本模式,spa

1. 崩潰恢復[master節點選擇]

2. 原子廣播[數據恢復,數據同步]

當整個集羣在啓動時,或者當 leader 節點出現網絡中斷、 崩潰等狀況時,ZAB 協議就會進入恢復模式並選舉產生新 的 Leader,當 leader 服務器選舉出來後,而且集羣中有過 半的機器和該 leader 節點完成數據同步後(同步指的是數 據同步,用來保證集羣中過半的機器可以和 leader 服務器 的數據狀態保持一致),ZAB 協議就會退出恢復模式。

當集羣中已經有過半的 Follower 節點完成了和 Leader 狀 態同步之後,那麼整個集羣就進入了消息廣播模式。這個時候,在 Leader 節點正常工做時,啓動一臺新的服務器加入到集羣,那這個服務器會直接進入數據恢復模式,和 leader 節點進行數據同步。同步完成後便可正常對外提供非事務請求的處理。

須要注意的是:leader 節點能夠處理事務請求和非事務請 求,follower 節點只能處理非事務請求,若是 follower 節 點接收到非事務請求,會把這個請求轉發給 Leader 服務器

 

ZK數據同步流程

ZK數據同步流程過程其實是一個 簡化版本的二階段(2pc)提交過程

1. leader 接收到消息請求後,將消息賦予一個全局惟一的 64 位自增 id,叫:zxid,經過 zxid 的大小比較既能夠實現因果有序這個特徵

2. leader 爲每一個 follower 準備了一個 FIFO 隊列(經過 TCP 協議來實現,以實現了全局有序這一個特色)將帶有 zxid 的消息做爲一個提案(proposal)分發給全部的 follower

3. 當 follower 接收到 proposal,先把 proposal 寫到磁盤, 寫入成功之後再向 leader 回覆一個 ack

4. 當 leader 接收到合法數量(超過半數節點)的 ACK 後,leader 就會向這些 follower 發送 commit 命令,同時會 在本地執行該消息

5. 當 follower 收到消息的 commit 命令之後,會提交該消息

 

 

 

 


 

關於 ZXID

爲了保證事務的順序一致性,zookeeper 採用了遞增的事 務 id 號(zxid)來標識事務。

全部的提議(proposal)都 在被提出的時候加上了 zxid。實現中 zxid 是一個 64 位的 數字,它高 32 位是 epoch(ZAB 協議經過 epoch 編號來 區分 Leader 週期變化的策略)用來標識 leader 關係是否改變,每次一個 leader 被選出來,它都會有一個新的 epoch=(原來的 epoch+1),標識當前屬於那個 leader 的 統治時期。低 32 位用於遞增計數。

 

epoch:能夠理解爲當前集羣所處的年代或者週期,每一個leader 就像皇帝,都有本身的年號,因此每次改朝換代,leader 變動以後,都會在前一個年代的基礎上加1。這樣就算舊的 leader 崩潰恢復以後,也沒有人聽他的了,由於 follower 只遵從當前年代的 leader 的命令。
相關文章
相關標籤/搜索