• zookeeper应用之leader选举


    在分布式系统中,ZooKeeper可用于实现领导者选举(leader election)功能,确保集群中的多个节点能够协调地选举出一个领导者来负责协调整个集群的工作。

    具体还是使用zookeeper的临时顺序节点。临时节点特点是当当前服务异常挂掉(与zookeeper的连接关闭)时创建的临时节点会自动消失。

    1、首先每个参与选举节点都在zookeeper固定路径下创建临时顺序节点。假设在/leader路径下。

    2、当节点创建完临时顺序节点后,查询/leader下所有子节点,找到自己创建的节点的顺序号,也就是自己的位置

    3、如果自己是最小的节点,则该节点成为领导者;否则监听自己前一个节点的变化,当前一个节点删除时,再次判断自己是否是最小的节点,是则成为领导者否则继续监听新的前一节点的变化,重复上面的判断操作。

    一旦成为了领导者,节点就可以开始执行领导者的职责,而其他节点则作为follower来跟随领导者执行任务。

    整个选举的过程大家是不是感觉有点熟悉,没错就是和前面的分布式锁的原理大致是一致的。curator有对leader选举的具体实现类:LeaderSelector。

    下面使用LeaderSelector搞个简单的例子。

    先定义一个选举的逻辑方法:

    static void execSelect() throws InterruptedException {
        CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", new ExponentialBackoffRetry(1000, 3));
        client.start();
    
        CountDownLatch latch = new CountDownLatch(1);
        LeaderSelector selector = new LeaderSelector(client, "/leader", new LeaderSelectorListener() {
            @Override
            public void takeLeadership(CuratorFramework client) throws Exception {
                System.out.println("I'm the leader "+Thread.currentThread().getName());
                //do sth
                Thread.sleep(5000);
                latch.countDown();
            }
    
            @Override
            public void stateChanged(CuratorFramework client, ConnectionState newState) {
    
            }
        });
        selector.start();
        latch.await();
        selector.close();
        client.close();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    这里使用LeaderSelector指定在"/leader"目录下创建临时节点进行选举,注册了一个LeaderSelectorListener监听器。将当前节点选举为leader时候,会回调takeLeadership()方法。这里成为leader之后休眠5s后然后关闭当前连接,也就是leader挂掉,触发下一次选举。

    LeaderSelector内部选举的过程就是用的InterProcessMutex来实现的。拿到锁就是当前节点选中leader。

    下面起几个线程模拟多节点进行选举:

    ExecutorService executor = Executors.newFixedThreadPool(5);
    for (int i = 0; i < 5; i++) {
        executor.execute(()->{
            try {
                execSelect();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }
    
    executor.shutdown();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    最后会看到输出:

    I’m the leader Curator-LeaderSelector-0
    I’m the leader Curator-LeaderSelector-2
    I’m the leader Curator-LeaderSelector-4
    I’m the leader Curator-LeaderSelector-1
    I’m the leader Curator-LeaderSelector-3

  • 相关阅读:
    session认证
    Is the docker daemon running问题解决方法
    OushuDB存算分离的湖仓一体模式有何不同 | 偶数科技
    《Effective Java 中文版》读书笔记
    Java实现常用的排序算法(冒泡排序、选择排序、插入排序、希尔排序)
    python刷题笔记1(42例题)
    机器学习笔记 - 基于pytorch、grad-cam的计算机视觉的高级可解释人工智能
    云原生容器平台——新华资产数字化转型加速器
    dma epoll kernel thread
    Springboot毕设项目旅游助手系统wp1hv(java+VUE+Mybatis+Maven+Mysql)
  • 原文地址:https://blog.csdn.net/sinat_16493273/article/details/134445482