Zookeeper

一、什么是Zookeeper、

zookeeper相当于是一个“数据库”,用来存放信息;是一个分布式协调的框架,实现HA的功能;是一个分布式锁的管理框架,实现秒杀。

二、提供的功能

1、选举功能
2、数据同步(端口:2888)、选举机制(通过投票的方式、端口:3888)
3、监听机制
4、分布式锁

其中,选举机制与数据同步,在集群中就能体现出来。

2888是集群之间信息同步用的
3888是自动选举用的
2181是给提供客户端服务用的

三、搭建单节点zookeeper(运行standalone)

1、解压:tar -zxvf zookeeper包名 解压到 /usr/local/zookeeper
2、设置环境变量 vi ~/.bash_profile (~/表示用户目录 ./ 当前目录 …/ 上级目录)

ZOOKEEPER_HOME=/usr/local/zookeeper/zookeeper-3.4.10
export ZOOKEEPER_HOME

PATH=$ZOOKEEPER_HOME/bin:$PATH
export PATH

#这一行不加可能会拒绝运行
export ZOO_LOG_DIR=/usr/local/zookeeper/zookeeper-3.4.10/log

3、生效环境变量:

source ~/.bash_profile

之后可以控制台 输入:zk 然后按两次tab键 ,进行测试环境变量是否弄好
在这里插入图片描述
4、核心配置文件:
usr/local/zookeeper/conf/zoo.cfg 默认是没有zoo.cfg,我们需要拷贝一下zoo_sample.cfg
执行命令 :

cp zoo_sample.cfg   zoo.cfg

在这里插入图片描述
5、配置zoo.cfg
5.1修改dataDir路径,默认是Linux的/temp目录,但是当Linux重新启动时,这个目录里的东西会清空的

dataDir=/usr/local/zookeeper/zookeeper-3.4.10/temp

5.2 指定zookeeper中的节点

server.1=IP地址:2888:3888

2888是集群之间信息同步用的
3888是自动选举用的
2181是给提供客户端服务用的

5.3 在dataDir=/usr/local/zookeeper/zookeeper-3.4.10/temp 创建一个文件 :myid
并且在第一行输入 1 , 这个1对应server.1=IP地址:2888:3888中的1
在这里插入图片描述

测试:

zkServer.sh start

在这里插入图片描述

zkServer.sh status

在这里插入图片描述
standalone 是单节点的模式

zkServer.sh stop   停止服务

四、搭建集群

1、配置环境变量,和单节点一样,只不过每个主机上都要配置
2、核心配置文件:
usr/local/zookeeper/conf/zoo.cfg 默认是没有zoo.cfg,我们需要拷贝一下zoo_sample.cfg
执行命令 :

cp zoo_sample.cfg   zoo.cfg

在这里插入图片描述
3、配置zoo.cfg
3.1修改dataDir路径,默认是Linux的/temp目录,但是当Linux重新启动时,这个目录里的东西会清空的

dataDir=/usr/local/zookeeper/zookeeper-3.4.10/temp

3.2 指定zookeeper中的节点

server.1=IP地址1:2888:3888
server.2=IP地址2:2888:3888
server.3=IP地址3:2888:3888

3.3 在dataDir=/usr/local/zookeeper/zookeeper-3.4.10/temp 创建一个文件 :myid
并且在第一行输入 1 , 这个1对应server.1=IP地址:2888:3888中的1
在这里插入图片描述
3.4、在安装好zookeeper目录后,复制到其他的节点

scp -r zookeeper-3.1.10/ root@IP地址2:/usr/local/zookeeper
scp -r zookeeper-3.1.10/ root@IP地址3:/usr/local/zookeeper

3.5、修改IP地址2余IP地址3上的myid文件。

五、操作ZooKeeper

1、JAVA API 操作zookeeper

创建节点主要分为三种情况(从字面意思理解):

  • 持久化节点Persistent
  • 顺序节点 SEQUENTIAL
  • 临时节点 ephemeral,当服务退出时,创建的节点就会自动删除。
public static void main(String[] args) throws Exception {

        //定义重试策略
        RetryPolicy policy = new  ExponentialBackoffRetry(1000 , 10);
        //创建节点
        CuratorFramework client = CuratorFrameworkFactory.builder()
                                    .connectString("192.168.92.111:2181")
                                    .retryPolicy(policy)
                                    .build();
        //启动client
        client.start();
        //进行操作,创建节点
        //  节点持久化节点
        client.create().forPath("/mynode1");
        //  持久化顺序节点
        client.create().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath("/nodePersist-");
        client.create().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath("/nodePersist-");
        client.create().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath("/nodePersist-");
        client.create().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath("/nodePersist-");
        //临时节点
        client.create().withMode(CreateMode.EPHEMERAL).forPath("/ephemeral");
        //  临时节点 順序节点 EPHEMERAL 汉语:瞬时的
        client.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath("/node-");
        client.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath("/node-");
        client.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath("/node-");
        client.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath("/node-");

        Thread.sleep(10000);
        //关闭client
        client.close();
    }

2、zookeeper监听机制

zookeeper的监听机制通俗的说就是,当监听的目录发生任何的变化,zookeeper就会启动对应的措施。Java代码实现如下:

	public static void main(String[] args) throws Exception {

        RetryPolicy policy = new ExponentialBackoffRetry(1000,10);
        //获得连接
        CuratorFramework client = CuratorFrameworkFactory.builder()
                                    .connectString("192.168.92.111:2181")
                                    .retryPolicy(policy).build();
        //启动连接
        client.start();
        //定义目录
        client.create().forPath("/parentNode");
        //要想监听这个目录,是不是首先拿到这个子目录的缓存目录
        PathChildrenCache pathChildrenCache = new PathChildrenCache(client,"/parentNode",true);
        //拿到缓存目录后,去监听器,添加监听器
        pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener(){

            public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
                switch (event.getType()){
                    case CHILD_ADDED:
                        System.out.println("添加子目录  "+ event.getData().getPath());
                        break;
                    case CHILD_UPDATED:
                        System.out.println("修改数据"+ event.getData().getPath());
                        break;
                    case CHILD_REMOVED:
                        System.out.println("删除数据"+ event.getData().getPath());
                        break;
                    default:
                        break;
                }
            }
        });
        //启动监听器
        pathChildrenCache.start();
        //添加子目录
        Thread.sleep(1000);
        client.create().forPath("/parentNode/children");
        //修改子目录
        Thread.sleep(1000);
        client.setData().forPath("/parentNode/children","hello world".getBytes());
        //删除子目录
        Thread.sleep(1000);
        client.delete().forPath("/parentNode/children");
        //关闭连接
        client.close();

    }

3、升入理解监听机制

在这里插入图片描述
目标:理解zookeeper 监听机制在主从架构中的作用。以Hbase进行举例。
为了解决单点故障问题,我们启动多台主节点进行启动,当启动集群的时候,主节点就会在zookeeper的对应目录下面创建一个临时节点。加入主节点进行荡机,是不是对应的临时节点就会删除,这时会触发zookeeper的监听机制,进而执行对应的操作,进行选举操作。

六、zookeeper的分布式锁

在这里插入图片描述
在请求资源的时候,我们先去zookeeper取一个锁,获得访问权限。请求锁的时候,用的临时节点!这一点要注意一下。

JAVA案例代码实现如下

public class TestZookeeperLock {

    //定义一个资源
    private static int NUMBER =10;

    //业务方法,进行取资源
    public static void doBussiness(){
        System.out.println("************开始执行业务方法!************");
        System.out.println("当前资源:"+ NUMBER);
        NUMBER--;
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("************结束调用!************");

    }

    public static void main(String[] args) {

        RetryPolicy policy = new ExponentialBackoffRetry(1000 ,10);
		//获得连接
        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString("192.168.92.111:2181")
                .retryPolicy(policy)
                .build();
        client.start();

        //定义锁 (节点、目录)
        final InterProcessMutex lock = new InterProcessMutex(client,"/mylock");

        for (int i = 0; i < 10; i++) {

            new Thread(new Runnable() {
                public void run() {
                    //获取锁
                    try {
                        lock.acquire();
                        doBussiness();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    //释放锁
                    try {
                        lock.release();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();

        }

    }

}

注意:当获取这把锁的时候,会在/mylock创建临时信息,释放锁的时候,/mylock下面的临时信息就会清空。也就是说,当/mylock下为空的时候,才可以去抢占这把锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值