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

    一、集群部署:

    zookeeper集群部署建议为奇数台机器(比如3台,5台),这样做是为了方便Parxos算法选举出leader节点和follower节点;

    现在假设有三台centerOS7的机器,IP分别为:10.103.16.207, 10.103.16.208, 10.103.16.209,现在分别在这三台机器上部署上zookeeper环境,步骤如下:

    1、配置JDK环境:这个就不用多说了;

    2、下载zookeeper包:

    https://archive.apache.org/dist/zookeeper/ 下载zookeeper的包文件,我这里下载的是3.4.10版本;

    3、解压文件:

    tar -zxvf zookeeper-3.4.10.tar.gz -C /usr/local/zookeeper

    4、修改配置;

    cd /usr/local/zookeeper/conf

    cp zoo_sample.cfg zoo.cfg

    vim zoo.cfg

    在其中增加下面内容(如果项目已经存在则替换就行):

    dataDir=/usr/local/zookeeper/data

    dataLogDir=/usr/local/zookeeper/logs

    server.1=10.103.16.207:2888:3888

    server.2=10.103.16.208:2888:3888

    server.3=10.103.16.209:2888:3888

    在zookeeper下建立目录:

    mkdir data

    mkdir logs

    切换到data目录下,生成myid文件:

    echo “1” >> /usr/local/zookeeper/data/myid

    三台机器分别指定对应的ID,如果10.103.16.207上的ID110.103.16.208上的ID210.103.16.209上的ID3

    5、启动zookeeper;

    cd /usr/local/zookeeper/bin

    ./zkServer.sh start

    启动后通过命令 ./zkServer.sh status能查看启动是否成功,该节点是leader还是follower;

    通过jps命令,如果能看到一个QuorumPeerMain的进程,说明zookeeper进程启动起来了;

    6、使用工具操作zookeeper;

    cd /usr/local/zookeeper/bin

    连接zookeeper:./zkCli.sh 或者 ./zkCli.sh 10.103.16.208:2181;连接成功后就可以进行下面的操作;

    查看节点信息:ls /  或者  ls /zookeeper(/zookeeper必须为已经存在的节点);

    创建节点:create /zookeeper/subnode “this is sub node data”

    查看节点内容:get /zookeeper/subnode

    设置节点内容:set /zookeeper/subnode “change node data”

    删除节点:delete /zookeeper/subnode

    查看命令行帮助:help

    退出cli工具:quit

    二、Zookeeper API 使用:

    1、导入jar包;

    <dependency>
      <groupId>org.apache.zookeeper</groupId>
      <artifactId>zookeeper</artifactId>
      <version>3.4.5</version>
    </dependency>

    2、编写服务端:

     1 public class Server {
     2     private static final String connectString = "10.103.16.207:2181";
     3     private static final int sessionTimeout = 2000;
     4     private static final String parentNode = "/zookeeper";
     5     private ZooKeeper zk = null;
     6     private static final String hostname = "10.103.16.214";
     7 
     8     /**
     9      * 创建到zk的客户端连接
    10      */
    11     public void getConnect() throws Exception {
    12         zk = new ZooKeeper(connectString, sessionTimeout, null);
    13     }
    14 
    15     /**
    16      * 向zk集群注册服务器信息
    17      */
    18     public void registerServer(String hostname) throws Exception {
    19         String create = zk.create(parentNode + "/server", hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
    20         System.out.println(hostname + "  is online.." + create);
    21     }
    22 
    23     /**
    24      * 业务功能
    25      *
    26      * @throws InterruptedException
    27      */
    28     public void handleBussiness(String hostname) throws InterruptedException {
    29         System.out.println(hostname + "  start working.....");
    30         Thread.sleep(Long.MAX_VALUE);
    31     }
    32 
    33     public static void main(String[] args) throws Exception {
    34         // 获取zk连接
    35         Server server = new Server();
    36         server.getConnect();
    37         // 利用zk连接注册服务器信息
    38         server.registerServer(hostname);
    39         // 启动业务功能
    40         server.handleBussiness(hostname);
    41     }
    42 }

    3、编写客户端:

     1 public class Client implements Watcher {
     2     private static final String connectString = "10.103.16.207:2181";
     3     private static final int sessionTimeout = 2000;
     4     private static final String parentNode = "/zookeeper";
     5     private volatile List<String> serverList;
     6     private ZooKeeper zk = null;
     7 
     8     @Override
     9     public void process(WatchedEvent event) {
    10         System.out.println(event.getType() + "-------->"  + event.getPath());
    11 
    12         try {
    13             getServerList();
    14         } catch (Exception e) {
    15             e.printStackTrace();
    16         }
    17     }
    18 
    19     /**
    20      * 创建到zk的客户端连接
    21      */
    22     public void getConnect() throws Exception {
    23         zk = new ZooKeeper(connectString, sessionTimeout, this);
    24     }
    25 
    26     /**
    27      * 获取服务器信息列表
    28      */
    29     public void getServerList() throws Exception {
    30         // 获取服务器子节点信息,并且对父节点进行监听
    31         List<String> children = zk.getChildren(parentNode, true);
    32         System.out.println(children);
    33     }
    34 
    35     /**
    36      * 业务功能
    37      */
    38     public void handleBussiness() throws InterruptedException {
    39         System.out.println("client start working.....");
    40         Thread.sleep(Long.MAX_VALUE);
    41     }
    42 
    43     public static void main(String[] args) throws Exception {
    44         // 获取zk连接
    45         Client client = new Client();
    46         client.getConnect();
    47         // 业务线程启动
    48         client.handleBussiness();
    49     }
    50

    需要注意的是zookeeper API这里有个Bug,每次watcher执行后就自动失效了,需要重新绑定watcher一次,而在这个demo中,通过调用zk.getChildren时watch参数传入true来再次绑定(或者调用其他需要传入boolean watch参数的方法来绑定watcher);

    三、zkClient使用:

    • 导入jar包;
    1 <dependency>
    2   <groupId>com.github.sgroschupf</groupId>
    3   <artifactId>zkclient</artifactId>
    4   <version>0.1</version>
    5 </dependency>
    • 编写服务端:
     1 public class Server {
     2     private static final String connectString = "10.103.16.207:2181,10.103.16.208:2181,10.103.16.209:2181";
     3     private static final int sessionTimeout = 2000;
     4     private static final String parentNode = "/zookeeper";
     5     private ZkClient zkClient = null;
     6 
     7     private static final String hostname = "10.103.16.214";
     8 
     9     public void getConnect() {
    10         zkClient = new ZkClient(connectString);
    11     }
    12 
    13     public void registerServer(String hostname) {
    14         String create = zkClient.create(parentNode + "/child", "hello, child node", CreateMode.EPHEMERAL_SEQUENTIAL);
    15         System.out.println(hostname + "  is online.." + create);
    16     }
    17 
    18     public void handleBusiness(String hostname) throws InterruptedException {
    19         System.out.println(hostname + "  start working.....");
    20         Thread.sleep(Long.MAX_VALUE);
    21     }
    22 
    23     public static void main(String[] args) throws InterruptedException {
    24         // 获取zk连接
    25         Server server = new Server();
    26         server.getConnect();
    27         // 利用zk连接注册服务器信息
    28         server.registerServer(hostname);
    29         // 启动业务功能
    30         server.handleBusiness(hostname);
    31     }
    32 }
    • 编写客户端:
     1 public class Client implements IZkChildListener, IZkDataListener, IZkStateListener {
     2     private static final String connectString = "10.103.16.207:2181,10.103.16.208:2181,10.103.16.209:2181";
     3     private static final int sessionTimeout = 2000;
     4     private static final String parentNode = "/zookeeper";
     5     private volatile List<String> serverList;
     6 
     7     private static ZkClient zkClient = null;
     8 
     9     @Override
    10     public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
    11         System.out.println("-----------child change: " + parentPath + "         " + currentChilds);
    12     }
    13 
    14     @Override
    15     public void handleDataChange(String dataPath, Object data) throws Exception {
    16         System.out.println("-----------data change: " + dataPath + "           " + data);
    17     }
    18 
    19     @Override
    20     public void handleDataDeleted(String dataPath) throws Exception {
    21         System.out.println("-----------data delete: " + dataPath);
    22     }
    23 
    24     @Override
    25     public void handleStateChanged(Watcher.Event.KeeperState state) throws Exception {
    26         System.out.println("-----------state change: " + state);
    27     }
    28 
    29     @Override
    30     public void handleNewSession() throws Exception {
    31         System.out.println("-----------new session***********");
    32     }
    33 
    34     public void getConnect() {
    35         zkClient = new ZkClient(connectString);
    36 
    37         zkClient.subscribeChildChanges(parentNode, this);
    38         zkClient.subscribeDataChanges(parentNode, this);
    39         zkClient.subscribeStateChanges(this);
    40 
    41     }
    42 
    43     public void handleBussiness() throws InterruptedException {
    44         System.out.println("client start working.....");
    45         Thread.sleep(Long.MAX_VALUE);
    46     }
    47 
    48     public static void main(String[] args) throws InterruptedException {
    49         // 获取zk连接
    50         Client client = new Client();
    51         client.getConnect();
    52         // 业务线程启动
    53         client.handleBussiness();
    54     }
    55 }

    四、Curator使用:

    • 导入jar包;
      1 <dependency>
      2   <groupId>org.apache.curator</groupId>
      3   <artifactId>curator-recipes</artifactId>
      4   <version>2.7.0</version>
      5 </dependency>
    • 编写服务端:
       1 public class Server1 {
       2     private static final String connectString = "10.103.16.207:2181,10.103.16.208:2181,10.103.16.209:2181";
       3     private static final int sessionTimeout = 2000;
       4     private static final String parentNode = "/zookeeper";
       5     private CuratorFramework client = null;
       6 
       7     private static final String hostname = "10.103.16.214";
       8 
       9     public void getConnect() {
      10         client = CuratorFrameworkFactory.newClient(
      11                 connectString,
      12                 new RetryNTimes(10, 5000)
      13         );
      14         client.start();
      15     }
      16 
      17     public void registerServer(String hostname) throws Exception {
      18         PersistentEphemeralNode node = new PersistentEphemeralNode(client, PersistentEphemeralNode.Mode.EPHEMERAL,
      19                 parentNode + "/" + hostname, "临时节点".getBytes());
      20         node.start();
      21     }
      22 
      23     public void handleBusiness(String hostname) throws InterruptedException {
      24         System.out.println(hostname + "  start working.....");
      25         Thread.sleep(Long.MAX_VALUE);
      26     }
      27 
      28     public static void main(String[] args) throws Exception {
      29         // 获取zk连接
      30         Server1 server = new Server1();
      31         server.getConnect();
      32         // 利用zk连接注册服务器信息
      33         server.registerServer(hostname);
      34         // 启动业务功能
      35         server.handleBusiness(hostname);
      36     }
      37 }
    • 编写客户端:
       1 public class Client1 {
       2     private static final String connectString = "10.103.16.207:2181,10.103.16.208:2181,10.103.16.209:2181";
       3     private static final int sessionTimeout = 2000;
       4     private static final String parentNode = "/zookeeper";
       5     private CuratorFramework client = null;
       6 
       7     private static final String hostname = "10.103.16.214";
       8 
       9     public void getConnect() {
      10         client = CuratorFrameworkFactory.newClient(
      11                 connectString,
      12                 new RetryNTimes(10, 5000)
      13         );
      14         client.start();
      15     }
      16 
      17     public void registerServer(String hostname) throws Exception {
      18         TreeCache watcher = new TreeCache(client,  parentNode + "/" + hostname);
      19         watcher.getListenable().addListener((client1, event) -> {
      20             ChildData data = event.getData();
      21             if (data == null) {
      22                 System.out.println("No data in event[" + event + "]");
      23             } else {
      24                 System.out.println("Receive event: "
      25                         + "type=[" + event.getType() + "]"
      26                         + ", path=[" + data.getPath() + "]"
      27                         + ", data=[" + new String(data.getData()) + "]"
      28                         + ", stat=[" + data.getStat() + "]");
      29             }
      30         });
      31         watcher.start();
      32     }
      33 
      34     public void handleBusiness(String hostname) throws InterruptedException {
      35         System.out.println(hostname + "  start working.....");
      36         Thread.sleep(Long.MAX_VALUE);
      37     }
      38 
      39     public static void main(String[] args) throws Exception {
      40         // 获取zk连接
      41         Client1 client = new Client1();
      42         client.getConnect();
      43         // 利用zk连接注册服务器信息
      44         client.registerServer(hostname);
      45         // 启动业务功能
      46         client.handleBusiness(hostname);
      47     }
      48 }

    五、常见问题:

    1、集群部署时,配置好各节点参数后,启动zookeeper总是失败:

    BIN目录下有一个zookeeper.out文件记录了zookeeper启动中的日志,通过查看这个日志可以看到在连接其他节点时失败导致的报错,在确定网络没有问题的情况下,就应该是防火墙的原因导致的,只需要关闭掉防火墙就可以了;

    在centerOS7下关闭防火墙:

    systemctl stop firewalld.service

    在centerOS7下禁止掉防火墙(下次重启系统时也不再启动防火墙):

    systemctl disable firewalld.service

    2、连接zookeeper太久的问题:启动ZK后查看启动状态需要好久才能看到是leader还是follwer,java中使用API连接时卡住比较长时间或者有时经常连接失败的问题:

    这个应该是系统的host解析问题导致的,在centerOS7系统中,编辑hosts文件(vim /etc/hosts),删掉127.0.0.1的那一行,重启网卡(/etc/rc.d/init.d/network restart),再次启动zookeeper即可发现连接快了很多;

    六、参考资料:

    • 书籍:《从PAXOSZOOKEEPER分布式一致性原理与实践》;
    • https://blog.csdn.net/shuxing520/article/details/79988167

        https://blog.csdn.net/u012152619/article/category/6470028

        https://blog.csdn.net/u012152619/article/details/53053634

        https://www.cnblogs.com/leesf456/p/6036548.html

        https://www.jianshu.com/p/24dbc4e7cc0d

        https://blog.csdn.net/Regan_Hoo/article/details/78773817

        https://blog.csdn.net/gs80140/article/details/51496925

    • Curator资料:    

        https://www.cnblogs.com/seaspring/p/5536338.html
        https://blog.csdn.net/qq_15370821/article/details/73692288
        https://www.cnblogs.com/sigm/p/6749228.html

  • 相关阅读:
    各种排序算法时间复杂度和空间复杂度表
    where 1=1和 0=1 的作用
    scala map操作 简单总结
    Scala详解---------数组、元组、映射
    Scala之String
    scala object 转Class Scala强制 类型转换
    Scala中的None,Nothing,Null,Nil
    mysql如何更新一个表中的某个字段值等于另一个表的某个字段值
    java.lang.String cannot be cast to scala.runtime.Nothing Scala中的Nothing类型
    mybatis 于 hibernate区别
  • 原文地址:https://www.cnblogs.com/laoxia/p/9585886.html
Copyright © 2011-2022 走看看