当前位置:   article > 正文

2021-04-23-zookeeper学习总结_zookeeper过半数存活

zookeeper过半数存活

1.ZooKeeper介绍

在这里插入图片描述

  • ZooKeeper是一个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。简单来说zookeeper=文件系统+监听通知机制。
  • ZooKeeper最为主要的使用场景,是作为分布式系统的分布式协同服务。在学习zookeeper之前,先要对分布式系统的概念有所了解。

2.分布式系统面临的问题

  • 分布式系统如何实现对同一资源的访问,保证数据的强一致性?
    集群中的Master挂了,传统做法是什么?zookeeper又是如何做的?
    在这里插入图片描述

3.Zookeeper树形结构

在这里插入图片描述

  • 每个子目录项如 NameService 都被称作为 znode(目录节点),和文件系统一样,我们能够自由的增加、删除znode,在一个znode下增加、删除子znode,唯一的不同在于znode是可以存储数据的。

3.1znode类型

  • PERSISTENT-持久化目录节点
    客户端与zookeeper断开连接后,该节点依旧存在
  • PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点
    客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号
  • EPHEMERAL-临时目录节点
    客户端与zookeeper断开连接后,该节点被删除
  • EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点
    客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号

3.2通过客户端操作Zookeeper

  • 略。。。

3.3Java操作Zookeeper

3.3.1添加依赖

<dependency>
   <groupId>org.apache.zookeeper</groupId>
   <artifactId>zookeeper</artifactId>
   <version>3.4.9</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

3.3.2通过API操作

public static void main(String[] args) throws  Exception{
   String hostPort = "192.168.193.110:2181";

   // 1.连接ZooKeeper
   ZooKeeper zooKeeper = new ZooKeeper(hostPort, 1000, null);


   // 2.创建节点
   String s = zooKeeper.create("/testRootPath", "testRootData".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
         CreateMode.PERSISTENT); // 永久节点

   // 3.获取节点数据
   byte[] data = zooKeeper.getData("/testRootPath", null, null);
   System.out.println(new String(data,"utf-8"));

   // 4.判断节点是否存在
   Stat exists = zooKeeper.exists("/testRootPath", true);
   System.out.println(exists);

   // 5.删除节点
   zooKeeper.delete("/testRootPath",0);

   zooKeeper.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

4.监听通知机制(Watch)

在这里插入图片描述

  • zookeeper提供了节点watch的功能,zookeeper的client监控zookeeper上的节点,当节点变动的时候,client会收到变动事件和变动后的内容,基于zookeeper的这个特性,我们可以给服务器集群中的所有机器都注册watch事件,监控特定znode,节点中存储部署代码的配置信息,需要更新代码的时候,修改znode中的值,服务器集群中的每一台server都会收到代码更新事件,然后触发调用,更新目标代码。也可以很容易的横向扩展,可以随意的增删机器,机器启动的时候注册监控节点事件即可。
 static ZooKeeper zkCli = null;
    public static void main(String[] args) throws Exception {

        zkCli = new ZooKeeper("192.168.193.110:2181", 3000, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                    System.out.println("监听回调函数");
//                try {
//                    byte[] data1 = zkCli.getData("/demo2", true, null);
//                    System.out.println("修改后的值:"+new String(data1));
//                } catch (KeeperException e) {
//                    e.printStackTrace();
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }

                try {
                    List<String> children = zkCli.getChildren("/", true);
                    for(String c:children){
                        System.out.println(c);
                    }
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        });

        // 注册监听目录
        zkCli.getChildren("/",true);

        // 注册监听节点
        zkCli.getData("/demo2",true,null);

        Thread.sleep(Long.MAX_VALUE);

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

5.Zookeeper应用场景

5.1配置文件管理

5.1.1什么是配置文件管理

  • 程序通常会需要进行一些配置文件进行配置的管理。但是如果对于分布式项目来说,可能会部署在不同的服务器上,这样每台服务都会有自己的一套配置,如果需要对某些配置进行调整,则需要逐一的对各个服务器进行修改。zookeeper能够实现统一的配置文件管理。

5.1.2 Zookeeper管理配置文件的

  • 将需要统一管理的配置全部放到zookeeper上去,保存在 Zookeeper 的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到 Zookeeper 的通知,然后从 Zookeeper 获取新的配置信息应用到系统中。
  • 在这里插入图片描述

5.2 集群管理

  • 所有机器约定在父目录GroupMembers下创建临时目录节点,然后监听父目录节点的子节点变化消息。一旦有机器挂掉,该机器与 zookeeper的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个兄弟目录被删除。新机器加入也是类似
  • 我们稍微改变一下,所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为master就好。

5.3分布式锁

  • 我们将zookeeper上的一个znode看作是一把锁,通过createznode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。用完删除掉自己创建的distribute_lock 节点就释放出锁

5.4命名服务(Dubbo监控中心原理)

  • 在日常开发中,我们会遇到这样的场景:服务A需要访问服务B,但是服务B还在开发过程中(未完成),那么服务A(此时已完成)就不知道如何获取服务B的访问路径了,使用zookeeper的服务就可以简单解决:服务B部署成功后,可以先到zookeeper注册服务(即在zookeeper添加节点/service/B和节点数据)。服务A开发结束后,部署到服务器,然后服务A监控zookeeper服务节点/service/B,如果发现节点有数据了,那么服务A就可以访问服务B了。

5.5发现服务

在这里插入图片描述

  • 注册一个持久节点/service/business/what,他下面的每个子节点都是一个可用服务,保存了服务的地址端口等信息,服务调用者通过zookeeper获取/service/business/what所有子节点信息来得到可用的服务。下面的节点都是临时节点,服务器启动的时候会过来注册一个临时节点,服务器挂掉之后或主动关闭之后,临时节点会自动移除,这样就可以保证使用者获取的what服务都是可用的,而且可以动态的扩容缩容。

6.Zookeeper集群

  • Zookeeper集群存在两个角色,一个是Leader其他都是Follower。一个 ZooKeeper 集群同一时刻只会有一个 Leader,其他都是 Follower。
  • ZooKeeper 集群的所有机器通过一个 Leader 选举过程来选定一台被称为『Leader』 的机器,Leader服务器为客户端提供读和写服务。Follower只提供读服务,不能提供写服务。
    1.如果有机器要对节点做更新,这个机器先告诉Leader。
    2.Leader收到后广播给所有的节点进行写操作,每个角色都在自己的机器中写。
    3.每个机器写完后都给Leader汇报是否写入成功
    4.如果有一半的机器写成功了Leader就下发第二个指令
    5.广播提交事务

6.1Leader选举

  • 所有节点都有两个属性,SID和ZXID。选举的目的就是选目前所有节点中拥有最大ZXID的节点作为Leader,如果拥有的ZXID相同,就选取SID最大的节点作为Leader,其他节点变为follower。
  • zxid:服务器中存放的最大数据ID,值越大说明数据越新,在选举算法中数据越新权重越 大,每次数据变动都会自增。
    sid:该投票信息所属的serverId(比如有三台服务器,编号分别是1,2,3)

6.2过半数存活原则

  • 在zookeeper集群中,当存活的机器数量超过总机器的一半的时候,整个集群才能正常工作,否则拒绝访问。基于过半数存活原则,zookeeper的集群机器数量一定是奇数台,因为2N+1和2N+2的容灾能力是一样的,基于成本考虑2N+1台的选择方案更优。

6.3为什么zookeeper需要设计一个过半数存活机制?

  • 脑裂问题
    集群中的节点监听不到leader节点的心跳, 就会认为leader节点出了问题, 此时集群将分裂为不同的小集群, 这些小集群会各自选举出自己的leader节点, 导致原有的集群中出现多个leader节点。
  • 为了防止网络脑裂,保证数据的强一致性,因为整个集群中,有可能因为网络问题"脑裂",导致整个集群分为2个甚至多个集群,如果没有过半数存活机制,那么整个zookeeper会变成多个集群,那么zookeeper提供的数据无法再保证数据一致性;
    在这里插入图片描述
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/94609
推荐阅读
相关标签
  

闽ICP备14008679号