zookeeper专题:zookeeper集群搭建和客户端连接

1. Zookeeper 集群模式介绍

Zookeeper 集群模式一共有三种类型的角色:

①:Leader: 处理所有的事务请求(写请求),可以处理读请求,集群中只能有一个Leader

②:Follower: 只能处理读请求,同时作为 Leader的候选节点,即如果Leader宕机,Follower节点 要参与到新的Leader选举中,有可能成为新的Leader节点。

③:Observer: 只能处理读请求。不能参与选举

在这里插入图片描述


2. zookeeper 集群搭建

        本例搭建的是伪集群模式,即一台机器上启动四个zookeeper实例组成集群,真正的集群模式无非就是实例IP地址不同,搭建方法没有区别,步骤如下:

1. 下载并解压zookeeper

wget https://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.5.8/apache-zookeeper-3.5.8-bin.tar.gz
tar -zxvf apache-zookeeper-3.5.8-bin.tar.gz
cd  apache-zookeeper-3.5.8-bin

2. 集群准备工作

# 创建存放集群节点的文件夹
mkdir zkCluster

# 在zkCluster内部分别创建每一个集群节点
cd zkCluster
mkdir zk1 zk2 zk3 zk4

# 为每一个集群节点的myid文件中,写入一个唯一id,用来标识节点身份
echo 1 >  /zk1/myid
echo 2 >  /zk2/myid
echo 3 >  /zk3/myid
echo 4 >  /zk4/myid

3. 编辑集群配置文件

# 为每一个集群节点建立配置文件
 cp conf/zoo_sample.cfg conf/zoo1.cfg
 
# 配置zoo1.cfg的文件存储位置
vim zoo1.cfg
dataDir=/tuling/apache-zookeeper-3.5.8-bin/zkCluster/zk1

# 配置zoo1.cfg节点的端口号
clientPort=2191

# 在zoo1.cfg尾部添加以下集群配置,代表集群节点有哪些,详解见下文
server.1=192.168.100.100:2001:3001
server.2=192.168.100.100:2002:3002
server.3=192.168.100.100:2003:3003
server.4=192.168.100.100:2004:3004:observer  //observer节点


# 其他三个节点可以复制zoo1.cfg中的配置,只需修改端口号和数据存储位置即可!
 cp conf/zoo1.cfg conf/zoo2.cfg
 。。。此处省略

其中集群配置server.1=192.168.100.100:2001:3001:observer 命令解析如下:

命令含义
server.1其中.1代表的是第几号服务器,取值是在zk1中的myid中配置好的
192.168.100.100这个服务器的 ip 地址
2001这个服务器与集群中的 Leader 服务器交换信息的端口
3001用来执行选举时服务器相互通信的端口。如果是伪集群的配置方式,由于 服务器的 ip 地址都一样,为了防止端口冲突,所以要给它们分配不同的端口号
observer如果需要通过添加不参与集群选举以及事务请求的过半机制的 Observer节点,可以在此位置,添加observer标识

4. 启动集群服务器

bin/zkServer.sh  start conf/zoo1.cfg 
bin/zkServer.sh  start conf/zoo2.cfg 
bin/zkServer.sh  start conf/zoo3.cfg 
bin/zkServer.sh  start conf/zoo4.cfg 

通过状态查看启动是否成功,也可查看当前节点是master、follower、observe哪一种节点类型

bin/zkServer.sh  status conf/zoo2.cfg 

zoo2.cfg 节点属于leader节点
在这里插入图片描述

5. 连接集群客户端

①:连接集群所有客户端

./bin/zkCli.sh -server 192.168.100.100:2191,192.168.100.100:2192,192.168.100.100:2193,192.168.100.100:2194

连接成功如下图:
在这里插入图片描述

②:连接集群单个客户端

./bin/zkCli.sh -server 192.168.100.100:2191

连接成功如下图:
在这里插入图片描述

以上两种方式的区别在于:

  1. 如果只连接单个客户端,如果当前连接的服务器挂掉,当前客户端连接也会挂掉,连接失败
  2. 如果是连接所有客户端的形式,则允许集群中半数以下的服务挂掉!当半数以上服务挂掉才会停止服务,可用性更高一点!

注意:集群中的节点信息被存放在每一个节点/zookeeper/config/目录下!
在这里插入图片描述

测试:在2191服务器上创建一个test节点,检测节点是否被同步到别的服务器上

2191服务器:
在这里插入图片描述
2193服务器:
在这里插入图片描述
从结果上可以看到,数据已经同步!此时zookeeper集群搭建成功!


3. 使用curate客户端连接zookeeper集群

3.1 创建连接

@Slf4j
public abstract  class CuratorStandaloneBase {

    //zookeeper连接
    private final static  String CLUSTER_CONNECT_STR="192.168.100.100:2191,192.168.100.100:2192,192.168.100.100:2193,192.168.100.100:2194";

    //session超时时间
    private static final int sessionTimeoutMs = 60*1000;
    
    //连接超时时间
    private static final int connectionTimeoutMs = 5000;
    
    private static CuratorFramework curatorFramework;

    @Before
    public void init() {
        //重试策略
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(5000, 30);

        //流式编程,创建zookeeper连接
        curatorFramework = CuratorFrameworkFactory.builder().connectString(getConnectStr())
                .retryPolicy(retryPolicy)
                .sessionTimeoutMs(sessionTimeoutMs) // 会话超时时间
                .connectionTimeoutMs(connectionTimeoutMs) // 连接超时时间
                .canBeReadOnly(true)
                .build();
        
        //添加监听器
        curatorFramework.getConnectionStateListenable().addListener((client, newState) -> {
            if (newState == ConnectionState.CONNECTED) {
                log.info("连接成功!");
            }

        });
        log.info("连接中......");
        curatorFramework.start();
    }

    public void createIfNeed(String path) throws Exception {
        Stat stat = curatorFramework.checkExists().forPath(path);
        if (stat==null){
            String s = curatorFramework.create().forPath(path);
            log.info("path {} created! ",s);
        }
    }

    public static CuratorFramework getCuratorFramework() {
        return curatorFramework;
    }

    @After
    public void   test(){
        try {
        	//主线程持续监听
            TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


//获取客户端方法
    protected   String getConnectStr(){
        return CONNECT_STR;
    }
}

测试连接:从zookeeper集群中获取数据

    @Test
    public void testCluster() throws Exception {
        CuratorFramework curatorFramework = getCuratorFramework();
        String pathWithParent = "/test";
        byte[] bytes = curatorFramework.getData().forPath(pathWithParent);
        System.out.println(new String(bytes));
        //每个一段时间获取一次数据
        while (true) {

            try {
                byte[] bytes2 = curatorFramework.getData().forPath(pathWithParent);
                System.out.println(new String(bytes2));

                TimeUnit.SECONDS.sleep(5);
            } catch (Exception e) {
                e.printStackTrace();
                testCluster();
            }
        }
    }

在集群任一服务器节点上为test节点设置数据hahaha

set /test  hahaha

在这里插入图片描述
接下来运行测试代码,运行结果如下:

在这里插入图片描述
接下来就可以使用Cutate来操作zookeeper了!

        另外,Zookeeper 3.5.0 以前,Zookeeper集群角色要发生改变的话,只能通过停掉所有的Zookeeper服务,修改集群配置,重启服务来完成,这样集群服务将有一段不可用的状态。
        为了应对高可用需求,Zookeeper 3.5.0 提供了支持动态扩容/缩容的新特性。但是通过客户端API可以变更服务端集群状态是件很危险的事情,所以在zookeeper 3.5.3 版本要用动态配置,需要开启超级管理员身份验证模式 ACLs。如果是在一个安全的环境也可以通过配置 系统参数 -Dzookeeper.skipACL=yes 来避免配置维护acl 权限配置。具体步骤点此查看!!

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值