Curator 主節點選舉LeaderLatch和LeaderSelector

LeaderLatch

一旦節點成爲主節點,那麼只有調用close方法,其它節點纔會繼續爭奪

List<LeaderLatch> latches = new ArrayList<>();
        List<CuratorFramework> clients = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", new ExponentialBackoffRetry(1000, 3));
            client.start();
            clients.add(client);

            LeaderLatch leaderLatch = new LeaderLatch(client, "/master", "node-" + i, LeaderLatch.CloseMode.NOTIFY_LEADER);
            leaderLatch.addListener(new LeaderLatchListener() {
                @Override
                public void isLeader() {
                    System.out.println(leaderLatch.getId() + " is a leader ");
                }

                @Override
                public void notLeader() {
                    System.out.println(leaderLatch.getId() + " not a leader ");
                }
            });
            latches.add(leaderLatch);
        }
        for (LeaderLatch latch : latches) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        latch.start();
                        latch.await();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    System.out.println(latch.getId()+" elect end");
                }
            }).start();
        }
        Thread.sleep(10000);
        for (LeaderLatch latch : latches) {
            System.out.println(latch.getId() + " leader:" + latch.getLeader() + " isLeader:" + latch.hasLeadership());
            if(latch.hasLeadership()){
                latch.close();
            }
        }
        for (CuratorFramework client : clients) {
            System.out.println(client.getData() + " is close");
            client.close();
        }
        Thread.sleep(100000);

在上面的例子中創建了10個clien,當某一個clien成爲主節點後,就會觸發isLeader方法,調用close方法後會觸發notLeader,然後再在其它節點中選舉一個新的leader,並且只有主節點才能繼續執行latch.await()後面的邏輯。

LeaderSelector

當實例被選爲leader之後,調用takeLeadership方法進行業務邏輯處理,處理完成即釋放領導權。

autoRequeue()方法的調用確保此實例在釋放領導權後還可能獲得領導權。

這樣保證了每個節點都可以獲得領導權。

List<LeaderSelector> leaderSelectors = new ArrayList<>();
        List<CuratorFramework> clients = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", new ExponentialBackoffRetry(1000, 3));
            client.start();
            clients.add(client);

            LeaderSelector leaderSelector = new LeaderSelector(client, "/master", new LeaderSelectorListenerAdapter() {
                @Override
                public void takeLeadership(CuratorFramework curatorFramework) throws Exception {
                    System.out.println(Thread.currentThread().getName() + " is a leader");
                    Thread.sleep(Integer.MAX_VALUE);
                }

                @Override
                public void stateChanged(CuratorFramework client, ConnectionState newState) {
                    super.stateChanged(client, newState);
                }
            });
            leaderSelectors.add(leaderSelector);
        }
        leaderSelectors.forEach(leaderSelector -> {
            leaderSelector.autoRequeue();
            leaderSelector.start();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        System.out.println("==================");
        clients.forEach(client -> {
            client.close();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread.sleep(100 * 1000);

在上面的例子中同樣新建10個客戶端然後進行選舉,當調用close方法後其它節點會重新選舉新的主節點。

當我們把takeLeadership方法中的Thread.sleep(Integer.MAX_VALUE);改爲Thread.sleep(3*1000);當takeLeadership方法執行結束,就自動放棄領導權,其它節點重新選舉。

當註釋掉leaderSelector.autoRequeue()後,釋放了領導權的節點不能再次獲取領導權。

區別

  1. leaderlatch需要調用close方法才能釋放主導權,並且不能重新獲得。leaderselector當執行完takeleadership方法後自動釋放主導權,並且可以設置autorequeue重新再獲取領導權
  2. 實現方式不同leaderselector使用分佈式鎖InterProcessMutex實現
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章