zoukankan      html  css  js  c++  java
  • Zookeeper学习总结

    一.Zookeeper概述和基本概念

    1.Zookeeper背景

    随着互联网技术的发展,企业对计算机系统的计算,存储能力要求越来越高,各大IT企业都在追求高并发,海量存储的极致,在这样的背景下,单纯依靠少量高性能单机来完成计算机,云计算的任务已经无法满足需求,
    企业的IT架构逐渐由集中式往分布式过渡。所谓的分布式是指:把一个计算任务分解成若干个计算单元,并分派到不同的计算机中去执行,最终汇总计算结果的过程。
    

    2.Zookeeper概述

    Zookeeper是源代码开放的分布式协调服务,是一个高性能的分布式数据一致性的解决方案,它将那些复杂的,容易出错的分布式一致性服务封装起来。用户可以通过调用Zookeeper提供的接口来解决一些分布式应用中的实际问题。
    

    3.Zookeeper典型应用场景

    (1)数据发布/订阅

    数据的发布与订阅,顾名思义就是一方把数据发布出来,另一方通过某种手段获取。
    通常数据发布与订阅有两种模式:推模式和拉模式,推模式一般是服务器主动往客户端推送信息,拉模式是客户端主动去服务端请求目标数据(通常采用定时轮询的方式)
    Zookeeper采用两种方式互相结合:发布者将数据发布到Zookeeper集群节点上,订阅者通过一定的方法告诉Zookeeper服务器,自己对哪个节点的数据感兴趣,那么在服务端数据发生变化时,就会通知客户端去获取这些信息。
    

    (2)负载均衡

    首先在服务端启动的时候,把自己在zookeeper服务器上注册成一个临时节点。zookeeper拥有两种形式的节点,一种是临时节点,一种是永久节点。这两种节点后面的博客会有较为详细的介绍。注册成临时节点后,再服务端出问题时,节点会自动的从 
    zookeeper上删除,如此zookeeper服务器上的列表就是最新的可用的列表。
    客户端在需要访问服务器的时候首先会去Zookeeper获得所有可用的服务端的连接信息。
    客户端通过一定的策略(如随机)选择一个与之建立连接。
    当客户端发现连接不可用时,会再次从zookeeper上获取可用的服务端连接,并同时删除之前获取的连接列表。
    

    (3)命名服务

    提供名称的服务。如一般使用较多的有两种id,一种是数据库自增长id,一种是UUID,两种id都有局限,自增长id仅适合在单表单库中使用,uuid适合在分布式系统中使用但由于id没有规律难以理解。
    而ZK提供了一定的接口可以用来获取一个顺序增长的,可以在集群环境下使用的id。
    

    (4)分布式协调,通知,心跳服务

    在分布式服务系统中,我们常常需要知道哪个服务是可用的,哪个服务是不可用的,传统的方式是通过ping主机来实现的,ping得200的结果说明说明该服务是OK的。
    
    而在使用 zookeeper时,可以将所有的服务都注册成一个临时节点,我们判断一个服务是否可用,只需要判断这个节点是否在zookeeper集群中存在就可以了,不需要直接去连接和ping服务所在主机,减少系统的复杂度和对服务主机的压力。
    

    (5)Zookeeper优势

    ●源代码开放
    
    ●高性能,易用稳定,该优势已在众多分布式系统中得到验证
    
    ●有着广泛的应用,并且与众多大数据相关技术能实现良好的融合开发。
    

    二.Zookeeper安装以及配置

    1.Zookeeper下载
    下载ZooKeeper,地址:http://mirrors.hust.edu.cn/apache/zookeeper/
    注意:注意版本,启动报错可能找不到主类,可以下载源码版

    2.Zookeeper安装配置

    3.创建data、log文件夹目录

    **4.进入conf目录,创建一个zookeeper的配置文件zoo.cfg,可复制conf/zoo_sample.cfg作为配置文件

     2 # tickTime:CS通信心跳数
     3 # Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。tickTime以毫秒为单位。
     4 tickTime=2000
     5 
     6 # The number of ticks that the initial 
     7 # synchronization phase can take
     8 # initLimit:LF初始通信时限
     9 # 集群中的follower服务器(F)与leader服务器(L)之间初始连接时能容忍的最多心跳数(tickTime的数量)。
    10 initLimit=5
    11 
    12 # The number of ticks that can pass between 
    13 # sending a request and getting an acknowledgement
    14 # syncLimit:LF同步通信时限
    15 # 集群中的follower服务器与leader服务器之间请求和应答之间能容忍的最多心跳数(tickTime的数量)。
    16 syncLimit=2
    17 
    18 # the directory where the snapshot is stored.
    19 # do not use /tmp for storage, /tmp here is just 
    20 # example sakes.
    21 # dataDir:数据文件目录
    22 # Zookeeper保存数据的目录,默认情况下,Zookeeper将写数据的日志文件也保存在这个目录里。
    23 dataDir=/data/soft/zookeeper-3.4.12/data
    24 
    25 
    26 # dataLogDir:日志文件目录
    27 # Zookeeper保存日志文件的目录。
    28 dataLogDir=/data/soft/zookeeper-3.4.12/logs
    29 
    30 # the port at which the clients will connect
    31 # clientPort:客户端连接端口
    32 # 客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
    33 clientPort=2181
    34 
    35 # the maximum number of client connections.
    36 # increase this if you need to handle more clients
    37 #maxClientCnxns=60
    38 #
    39 # Be sure to read the maintenance section of the 
    40 # administrator guide before turning on autopurge.
    41 #
    42 # http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
    43 #
    44 # The number of snapshots to retain in dataDir 保留数量3
    45 autopurge.snapRetainCount=3
    46 # Purge task interval in hours
    47 # Set to "0" to disable auto purge feature 清理时间间隔1小时
    48 autopurge.purgeInterval=1
    49 
    50 
    51 # 服务器名称与地址:集群信息(服务器编号,服务器地址,LF通信端口,选举端口)
    52 # 这个配置项的书写格式比较特殊,规则如下:
    53 
    54 # server.N=YYY:A:B  
    55 
    56 # 其中N表示服务器编号,YYY表示服务器的IP地址,A为LF通信端口,表示该服务器与集群中的leader交换的信息的端口。B为选举端口,表示选举新leader时服务器间相互通信的端口(当leader挂掉时,其余服务器会相互通信,选择出新的leader)。一般来说,集群中每个服务器的A端口都是一样,每个服务器的B端口也是一样。但是当所采用的为伪集群时,IP地址都一样,只能时A端口和B端口不一样。 
    
    1 # The number of milliseconds of each tick
     2 # tickTime:CS通信心跳数
     3 # Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。tickTime以毫秒为单位。
     4 tickTime=2000
     5 
     6 # The number of ticks that the initial 
     7 # synchronization phase can take
     8 # initLimit:LF初始通信时限
     9 # 集群中的follower服务器(F)与leader服务器(L)之间初始连接时能容忍的最多心跳数(tickTime的数量)。
    10 initLimit=5
    11 
    12 # The number of ticks that can pass between 
    13 # sending a request and getting an acknowledgement
    14 # syncLimit:LF同步通信时限
    15 # 集群中的follower服务器与leader服务器之间请求和应答之间能容忍的最多心跳数(tickTime的数量)。
    16 syncLimit=2
    17 
    18 # the directory where the snapshot is stored.
    19 # do not use /tmp for storage, /tmp here is just 
    20 # example sakes.
    21 # dataDir:数据文件目录
    22 # Zookeeper保存数据的目录,默认情况下,Zookeeper将写数据的日志文件也保存在这个目录里。
    23 dataDir=/data/soft/zookeeper-3.4.12/data
    24 
    25 
    26 # dataLogDir:日志文件目录
    27 # Zookeeper保存日志文件的目录。
    28 dataLogDir=/data/soft/zookeeper-3.4.12/logs
    29 
    30 # the port at which the clients will connect
    31 # clientPort:客户端连接端口
    32 # 客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
    33 clientPort=2181
    34 
    35 # the maximum number of client connections.
    36 # increase this if you need to handle more clients
    37 #maxClientCnxns=60
    38 #
    39 # Be sure to read the maintenance section of the 
    40 # administrator guide before turning on autopurge.
    41 #
    42 # http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
    43 #
    44 # The number of snapshots to retain in dataDir 保留数量3
    45 autopurge.snapRetainCount=3
    46 # Purge task interval in hours
    47 # Set to "0" to disable auto purge feature 清理时间间隔1小时
    48 autopurge.purgeInterval=1
    49 
    50 
    51 # 服务器名称与地址:集群信息(服务器编号,服务器地址,LF通信端口,选举端口)
    52 # 这个配置项的书写格式比较特殊,规则如下:
    53 
    54 # server.N=YYY:A:B  
    55 
    56 # 其中N表示服务器编号,YYY表示服务器的IP地址,A为LF通信端口,表示该服务器与集群中的leader交换的信息的端口。B为选举端口,表示选举新leader时服务器间相互通信的端口(当leader挂掉时,其余服务器会相互通信,选择出新的leader)。一般来说,集群中每个服务器的A端口都是一样,每个服务器的B端口也是一样。但是当所采用的为伪集群时,IP地址都一样,只能时A端口和B端口不一样。 
    
    

    5.启动Zookeeper


    三.Zookeeper基本命令

    help 查看所有命令
    ls  查看根路径下的节点 ls / 
    create  创建普通的永久节点 create /hello "helloword"
    create -s 创建带序号的永久节点 create -s /app1 "app1 node"
    create -e 创建普通的临时节点 create -e /app2 "app2 node"
    create -e -s 创建带序号的临时节点 create -e -s /app3 "app3 node"
    get 查找节点数据 get /hello
    stat 查看节点状态 stat /hello
    set 修改节点数据 set /hello 'hello node'
    delete 删除节点 delete /hello(设hello节点下没子节点)
    deleteall 递归删除节点 deleteall /hello (设hello节点下有子节点)
    

    四.Zookeeper通过java实现的demo

    1.需要引入的pom依赖

     <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>3.4.7</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-framework</artifactId>
                <version>4.0.1</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-recipes</artifactId>
                <version>4.0.1</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>3.8.2</version>
                <scope>compile</scope>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>RELEASE</version>
                <scope>compile</scope>
            </dependency>
    

    2.创建测试类

    import org.apache.curator.RetryPolicy;
    import org.apache.curator.framework.CuratorFramework;
    import org.apache.curator.framework.CuratorFrameworkFactory;
    import org.apache.curator.retry.ExponentialBackoffRetry;
    import org.apache.zookeeper.CreateMode;
    import org.junit.Before;
    import org.junit.Test;
    
    public class ZookeeperApiTest {
    
        private  CuratorFramework client = null;
        /**
         * 创建客户端
         * 1.创建连接失败重试策略对象
         * 2.创建客户端对象
         */
        @Before
        public void before(){
    
            /**创建重试的连接对象
             *RetryPolicy接口 失败重试策略的公共接口;ExponentialBackoffRetry 实现类 是失败重试celue接口实现类
             * 参数1:两次重试之间等待的初始时间(单位:毫秒)
             * 参数2:最大重试次数
             */
            RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000,3);
            /**
             * 创建客户端对象
             * 参数1:连接zookeeper服务器IP地址和端口号
             * 参数2:会话超时时间(单位:毫秒)
             * 参数3:连接超时时间(单位:毫秒)
             * 参数4:失败失败重试策略
             */
            client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", 1000, 1000, retryPolicy);
        }
    
        /**
         * 创建节点
         * 1.开启客户端(会阻塞到会话连接成功为止)
         * 2.创建节点
         * 3.关闭节点
         */
        @Test
        public void createNode() throws Exception {
            //开启客户端
            client.start();
            // 方式一:创建一个空节点(只能创建一个节点)
            //client.create().forPath("/app1");
            //方式二:创建一个有内容的节点(只能创建一层节点)
            //client.create().forPath("/app2","app2 node".getBytes());
            //方式三:创建多层节点
            //client.create().creatingParentsIfNeeded().forPath("/app3/a","a node".getBytes());
            //创建持久性节点(CreateMode.PERSISTENT)
            //client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/app3/b","b node".getBytes());
            //创建带序号持久性节点(CreateMode.PERSISTENT)
            //client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath("/app3/c","c node".getBytes());
            //创建临时节点
            //client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath("/app3/d","d node".getBytes());
            // 创建带序号临时节点
            client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath("/app3/e","e node".getBytes());
    
    
            Thread.sleep(10000);
            // 关闭客户端
            client.close();
        }
    
        /**
         * 修改节点数据
         * 1.开启客户端
         * 2.修改节点
         * 3.关闭客户端
         */
        @Test
        public void updateNode() throws Exception {
            // 1.开启客户端
            client.start();
            //2.修改节点
            client.setData().forPath("/app1","app1 node".getBytes());
            //3.关闭客户端
            client.close();
        }
    
        /**
         * 获取节点数据
         * 1.开启客户端
         * 2.获取节点数据
         * 3.关闭客户端
         */
        @Test
        public void  findNode() throws Exception {
            // 1.开启客户端
            client.start();
            //2.获取节点数据
            byte[] bytes = client.getData().forPath("/app1");
            System.out.println("节点数据:"+new String(bytes));
            //3.关闭客户端
            client.close();
        }
    
        /**
         * 删除节点
         * 1.开启客户端
         * 2.删除节点
         * 3.关闭客户端
         */
        @Test
        public void deleteNode() throws Exception {
            // 1.开启客户端
            client.start();
            //方式1:删除一个子节点(此节点下面不能有子节点)
            //client.delete().forPath("/app1");
            //方式2:带有节点并递归删除其子节点
            //client.delete().deletingChildrenIfNeeded().forPath("/app3");
            //方式3:强制保证删除一个节点
            client.delete().guaranteed().forPath("/app2");
            //3.关闭客户端
            client.close();
        }
    
    }
    
    古今成大事者,不唯有超世之才,必有坚韧不拔之志!
  • 相关阅读:
    javascript中的光标
    jQuery插件使用大全
    marginCollapse之兄弟关系的DIV
    margin collapse 之父子关系的DIV
    选择符优先级-----:link伪类
    a标签包input引起的问题
    关于inline-block的间隙问题
    创意输入框
    Unity3D教程宝典之Shader篇:第十四讲Surface Shader
    Unity3D教程宝典之Shader篇:第十三讲 Alpha混合
  • 原文地址:https://www.cnblogs.com/songwp/p/15014753.html
Copyright © 2011-2022 走看看