ZooKeeper集群搭建与连接

目录

1 集群搭建

2 Java连接


本文将演示ZooKeeper的伪集群搭建过程,用一台虚拟机来模拟搭建三个节点的集群效果。我虚拟机的ip是192.168.253.129,ZooKeeper的版本是3.4.14(我一开始安装的是ZooKeeper3.5.5,但是配置完了之后启动一直是失败的。所以如果你也有如此问题出现,可以尝试换成3.4.14版本来搭建)。


1 集群搭建

我的ZooKeeper安装目录在/usr/zookeeper/zookeeper-3.4.14/这个路径下,首先将该路径下的conf目录下的zoo_sample.cfg文件改名为zoo.cfg:

mv zoo_sample.cfg zoo.cfg

接着退回上一级,在zookeeper-3.4.14目录下创建一个zookeeper-cluster的目录并在其下分别创建2181、2182和2183三个子目录:

mkdir zookeeper-cluster
cd zookeeper-cluster
mkdir 2181
mkdir 2182
mkdir 2183

将之前改过名的zoo.cfg文件分别放进这三个子目录下,其中需要更改和添加的内容如下所示:

2181/zoo.cfg:

dataDir=/usr/zookeeper/zookeeper-3.4.14/zookeeper-cluster/2181/data
dataLogDir=/usr/zookeeper/zookeeper-3.4.14/zookeeper-cluster/2181/logs
clientPort=2181
server.1=192.168.253.129:2287:3387
server.2=192.168.253.129:2288:3388
server.3=192.168.253.129:2289:3389

2182/zoo.cfg:

dataDir=/usr/zookeeper/zookeeper-3.4.14/zookeeper-cluster/2182/data
dataLogDir=/usr/zookeeper/zookeeper-3.4.14/zookeeper-cluster/2182/logs
clientPort=2182
server.1=192.168.253.129:2287:3387
server.2=192.168.253.129:2288:3388
server.3=192.168.253.129:2289:3389

2183/zoo.cfg:

dataDir=/usr/zookeeper/zookeeper-3.4.14/zookeeper-cluster/2183/data
dataLogDir=/usr/zookeeper/zookeeper-3.4.14/zookeeper-cluster/2183/logs
clientPort=2183
server.1=192.168.253.129:2287:3387
server.2=192.168.253.129:2288:3388
server.3=192.168.253.129:2289:3389

然后在每个子目录下分别创建data和logs目录,用于上面的相关配置。

mkdir data
mkdir logs

在对三个子节点的目录下都创建了data和logs目录之后,紧接着在每个data目录下创建一个myid的文件:

vim myid

其中的内容存放的是当前节点的myid:

2181/data/myid:

1

2182/data/myid:

2

2183/data/myid:

3

至此我们算是配置好了相关的内容。最后是启动ZooKeeper,跳到zookeeper-3.4.14/bin目录下,使用下面的命令来分别启动三个节点:

zkServer.sh start /usr/zookeeper/zookeeper-3.4.14/zookeeper-cluster/2181/zoo.cfg
zkServer.sh start /usr/zookeeper/zookeeper-3.4.14/zookeeper-cluster/2182/zoo.cfg
zkServer.sh start /usr/zookeeper/zookeeper-3.4.14/zookeeper-cluster/2183/zoo.cfg

运行效果如下:

随后我们可以通过下面的命令来查看三个节点的运行状态:

zkServer.sh status /usr/zookeeper/zookeeper-3.4.14/zookeeper-cluster/2181/zoo.cfg
zkServer.sh status /usr/zookeeper/zookeeper-3.4.14/zookeeper-cluster/2182/zoo.cfg
zkServer.sh status /usr/zookeeper/zookeeper-3.4.14/zookeeper-cluster/2183/zoo.cfg

运行效果如下:

可以看到,在我的ZooKeeper集群里,2182节点是主节点,而2181和2183节点是从节点。最后我们就可以用zkCli来连接客户端了,随便在一个节点上执行下面的命令(我是在2181节点上操作的):

zkCli.sh -server 192.168.253.129:2181

运行结果如下:

之后我们就可以使用ZooKeeper的命令了。


2 Java连接

这里我是通过Curator来对ZooKeeper进行连接的,pom依赖如下所示(注:因为我使用的Zookeeper版本是3.4.14,所以这里使用的Curator版本不能是高版本):

        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>2.13.0</version>
        </dependency>

简单的测试代码如下所示:

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.apache.zookeeper.data.Stat;

import java.util.List;
import java.util.concurrent.*;

public class CuratorBase {

    /**
     * ZooKeeper地址
     */
    private static final String CONNECT_ADDR = "192.168.253.129:2181,192.168.253.129:2182,192.168.253.129:2183";
    /**
     * session超时时间
     */
    private static final int SESSION_OUTTIME = 10000;

    public static void main(String[] args) throws Exception {
        //重试策略,初试时间为1s,重试10次
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 10);
        //创建连接
        CuratorFramework cf = CuratorFrameworkFactory.builder().connectString(CONNECT_ADDR).sessionTimeoutMs(SESSION_OUTTIME).retryPolicy(retryPolicy).build();
        cf.start();
        //创建节点
        cf.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/super/c1", "c1内容".getBytes());
        cf.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/super/c2", "c2内容".getBytes());
        //读取节点
        String c1 = new String(cf.getData().forPath("/super/c1"));
        System.out.println(c1);
        //修改节点
        cf.setData().forPath("/super/c1", "修改c1内容".getBytes());
        String c2 = new String(cf.getData().forPath("/super/c1"));
        System.out.println(c2);
        //读取子节点
        List<String> list = cf.getChildren().forPath("/super");
        for (String p : list) {
            System.out.println(p);
        }
        //判断节点是否存在
        Stat stat = cf.checkExists().forPath("/super/c2");
        System.out.println(stat);
        //删除节点
        cf.delete().guaranteed().deletingChildrenIfNeeded().forPath("/super");
        //绑定回调函数
        ExecutorService pool = new ThreadPoolExecutor(10, 20, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(1024), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
        cf.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).inBackground((curatorFramework, curatorEvent) -> {
            System.out.println("code:" + curatorEvent.getResultCode());
            System.out.println("type:" + curatorEvent.getType());
            System.out.println("线程为:" + Thread.currentThread().getName());
        }, pool).forPath("/super/c3", "c3内容".getBytes());
        System.out.println("主线程:" + Thread.currentThread().getName());
        Thread.sleep(Integer.MAX_VALUE);
        cf.close();
    }
}

 

发布了62 篇原创文章 · 获赞 80 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/weixin_30342639/article/details/100179153