尚硅谷大数据技术Zookeeper教程-笔记02【服务器动态上下线监听案例、ZooKeeper分布式锁案例、企业面试真题】

news2024/11/20 0:23:59

视频地址:【尚硅谷】大数据技术之Zookeeper 3.5.7版本教程_哔哩哔哩_bilibili

  1. 尚硅谷大数据技术Zookeeper教程-笔记01【Zookeeper(入门、本地安装、集群操作)】
  2. 尚硅谷大数据技术Zookeeper教程-笔记02【服务器动态上下线监听案例、ZooKeeper分布式锁案例、企业面试真题】
  3. 尚硅谷大数据技术Zookeeper教程-笔记03【源码解析-算法基础】
  4. 尚硅谷大数据技术Zookeeper教程-笔记04【源码解析-源码详解】

目录

第04章-服务器动态上下线监听案例

P020【020_尚硅谷_zk_案例_服务器动态上下线_需求分析】04:41

P021【021_尚硅谷_zk_案例_服务器动态上下线_服务器注册】10:44

P022【022_尚硅谷_zk_案例_服务器动态上下线_客户端监听】10:01

P023【023_尚硅谷_zk_案例_服务器动态上下线_测试】06:55

第05章-ZooKeeper分布式锁案例

P024【024_尚硅谷_zk_案例_分布式锁_需求分析】05:18

P025【025_尚硅谷_zk_案例_分布式锁_代码实现(上)】09:57

P026【026_尚硅谷_zk_案例_分布式锁_代码实现(下)】16:19

P027【027_尚硅谷_zk_案例_分布式锁_测试】05:39

P028【028_尚硅谷_zk_案例_分布式锁_成熟框架curator】09:44

第06章-企业面试真题(面试重点)

P029【029_尚硅谷_zk_企业面试真题】03:32


第04章-服务器动态上下线监听案例

P020【020_尚硅谷_zk_案例_服务器动态上下线_需求分析】04:41

第 4 章 服务器动态上下线监听案例

4.1 需求

某分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知到主节点服务器的上下线。

4.2 需求分析

P021【021_尚硅谷_zk_案例_服务器动态上下线_服务器注册】10:44

package com.atguigu.case1;

import org.apache.zookeeper.*;

import java.io.IOException;

public class DistributeServer {
    private String connectString = "node1:2181,node2:2181,node3:2181";
    private int sessionTimeout = 2000;
    private ZooKeeper zk;

    public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
        DistributeServer server = new DistributeServer();
        //1、获取zk连接
        server.getConnect();

        //2、注册服务器到zk集群
        server.regist(args[0]);

        //3、启动业务逻辑(睡觉)
        server.business();
    }

    //1、获取zk连接
    private void getConnect() throws IOException {
        zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
            }
        });
    }

    //2、注册服务器到zk集群
    private void regist(String hostname) throws KeeperException, InterruptedException {
        String create = zk.create("/servers/" + hostname, hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
        System.out.println(hostname + " is online");
    }

    //3、启动业务逻辑(睡觉)
    private void business() throws InterruptedException {
        Thread.sleep(Long.MAX_VALUE);
    }
}

P022【022_尚硅谷_zk_案例_服务器动态上下线_客户端监听】10:01

package com.atguigu.case1;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class DistributeClient {
    private String connectString = "node1:2181,node2:2181,node3:2181";
    private int sessionTimeout = 2000;
    private ZooKeeper zk;

    public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
        DistributeClient client = new DistributeClient();
        //1、获取zk连接
        client.getConnect();

        //2、监听/servers下面子节点的增加和删除
        client.getServerList();

        //3、业务逻辑(睡觉)
        client.business();
    }

    //1、获取zk连接
    private void getConnect() throws IOException {
        zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                try {
                    getServerList();
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    //2、监听/servers下面子节点的增加和删除
    private void getServerList() throws KeeperException, InterruptedException {
        List<String> children = zk.getChildren("/servers", true);
        ArrayList<String> servers = new ArrayList<>();
        for (String child : children) {
            byte[] data = zk.getData("/servers/" + child, false, null);
            servers.add(new String(data));
        }
        System.out.println(servers);//打印
    }

    //3、业务逻辑(睡觉)
    private void business() throws InterruptedException {
        Thread.sleep(Long.MAX_VALUE);
    }
}

P023【023_尚硅谷_zk_案例_服务器动态上下线_测试】06:55

第05章-ZooKeeper分布式锁案例

P024【024_尚硅谷_zk_案例_分布式锁_需求分析】05:18

第 5 章 ZooKeeper分布式锁案例

什么叫做分布式锁呢? 比如说"进程 1"在使用该资源的时候,会先去获得锁,"进程 1"获得锁以后会对该资源保持独占,这样其他进程就无法访问该资源,"进程 1"用完该资源以后就将锁释放掉,让其他进程来获得锁,那么通过这个锁机制,我们就能保证了分布式系统中多个进程能够有序的访问该临界资源。那么我们把这个分布式环境下的这个锁叫作分布式锁

分布式锁案例分析

P025【025_尚硅谷_zk_案例_分布式锁_代码实现(上)】09:57

5.1 原生Zookeeper实现分布式锁案例

package com.atguigu.case2;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;

public class DistributedLock {
    private final String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
    private final int sessionTimeout = 2000;
    private final ZooKeeper zk;

    private CountDownLatch connectLatch = new CountDownLatch(1);
    private CountDownLatch waitLatch = new CountDownLatch(1);

    private String waitPath;
    private String currentMode;

    public DistributedLock() throws IOException, InterruptedException, KeeperException {
        //获取连接
        zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //connectLatch,如果连接上zk,可以释放
                if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
                    connectLatch.countDown();
                }

                //waitLatch需要释放
                if (watchedEvent.getType() == Event.EventType.NodeDeleted && watchedEvent.getPath().equals(waitPath)) {
                    waitLatch.countDown();
                }
            }
        });

        //等待zk正常连接后,往下走程序
        connectLatch.await();

        //判断根节点/locks是否存在
        Stat stat = zk.exists("/locks", false);

        if (stat == null) {
            //创建一下根节点
            zk.create("/locks", "locks".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        }
    }

    //对zk加锁
    public void zklock() {
        //创建对应的临时带序号节点
        //判断创建的节点是否是最小的序号节点,如果是获取到锁;如果不是,监听他序号前一个节点
    }

    //解锁
    public void unZkLock() {
        //删除节点
    }
}

P026【026_尚硅谷_zk_案例_分布式锁_代码实现(下)】16:19

package com.atguigu.case2;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;

public class DistributedLock {
    private final String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
    private final int sessionTimeout = 2000;
    private final ZooKeeper zk;

    private CountDownLatch connectLatch = new CountDownLatch(1);
    private CountDownLatch waitLatch = new CountDownLatch(1);

    private String waitPath;
    private String currentMode;

    public DistributedLock() throws IOException, InterruptedException, KeeperException {
        //获取连接
        zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //connectLatch,如果连接上zk,可以释放
                if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
                    connectLatch.countDown();
                }

                //waitLatch需要释放
                if (watchedEvent.getType() == Event.EventType.NodeDeleted && watchedEvent.getPath().equals(waitPath)) {
                    waitLatch.countDown();
                }
            }
        });

        //等待zk正常连接后,往下走程序
        connectLatch.await();

        //判断根节点/locks是否存在
        Stat stat = zk.exists("/locks", false);

        if (stat == null) {
            //创建一下根节点
            zk.create("/locks", "locks".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        }
    }

    //对zk加锁
    public void zklock() {
        //创建对应的临时带序号节点
        try {
            currentMode = zk.create("/locks/" + "seq-", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);

            //wait一小会, 让结果更清晰一些
            Thread.sleep(10);

            //判断创建的节点是否是最小的序号节点,如果是获取到锁;如果不是,监听他序号前一个节点

            List<String> children = zk.getChildren("/locks", false);

            //如果children 只有一个值,那就直接获取锁;如果有多个节点,需要判断谁最小
            if (children.size() == 1) {
                return;
            } else {
                Collections.sort(children);
                //获取节点名称 seq-00000000
                String thisNode = currentMode.substring("/locks/".length());
                //通过seq-00000000获取该节点在children集合的位置
                int index = children.indexOf(thisNode);

                //判断
                if (index == -1) {
                    System.out.println("数据异常");
                } else if (index == 0) {
                    //就一个节点,可以获取锁了
                    return;
                } else {
                    //需要监听他前一个节点变化
                    waitPath = "/locks/" + children.get(index - 1);
                    zk.getData(waitPath, true, new Stat());
                    //等待监听
                    waitLatch.await();
                    return;
                }
            }
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //解锁
    public void unZkLock() {
        //删除节点
        try {
            zk.delete(this.currentMode, -1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (KeeperException e) {
            e.printStackTrace();
        }
    }
}

P027【027_尚硅谷_zk_案例_分布式锁_测试】05:39

package com.atguigu.case2;

import org.apache.zookeeper.KeeperException;

import java.io.IOException;

public class DistributedLockTest {
    public static void main(String[] args) throws InterruptedException, IOException, KeeperException {
        final DistributedLock lock1 = new DistributedLock();

        final DistributedLock lock2 = new DistributedLock();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    lock1.zklock();
                    System.out.println("线程1 启动,获取到锁");
                    Thread.sleep(5 * 1000);

                    lock1.unZkLock();
                    System.out.println("线程1 释放锁");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    lock2.zklock();
                    System.out.println("线程2 启动,获取到锁");
                    Thread.sleep(5 * 1000);

                    lock2.unZkLock();
                    System.out.println("线程2 释放锁");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

P028【028_尚硅谷_zk_案例_分布式锁_成熟框架curator】09:44

5.2 Curator框架实现分布式锁案例

1)原生的 Java API 开发存在的问题

(1)会话连接是异步的,需要自己去处理。比如使用CountDownLatch

(2)Watch 需要重复注册,不然就不能生效

(3)开发的复杂性还是比较高的

(4)不支持多节点删除和创建。需要自己去递归

2)Curator 是一个专门解决分布式锁的框架,解决了原生 JavaAPI 开发分布式遇到的问题。

详情请查看官方文档:https://curator.apache.org/index.html

3)Curator 案例实操

package com.atguigu.case3;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;

public class CuratorLockTest {
    public static void main(String[] args) {
        //创建分布式锁1
        InterProcessMutex lock1 = new InterProcessMutex(getCuratorFramework(), "/locks");

        //创建分布式锁2
        InterProcessMutex lock2 = new InterProcessMutex(getCuratorFramework(), "/locks");

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    lock1.acquire();
                    System.out.println("线程1,获取到锁。");

                    lock1.acquire();
                    System.out.println("线程1,再次获取到锁。");

                    Thread.sleep(5 * 1000);

                    lock1.release();
                    System.out.println("线程1,释放锁。");

                    lock1.release();
                    System.out.println("线程1,再次释放锁。");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    lock2.acquire();
                    System.out.println("线程2,获取到锁。");

                    lock2.acquire();
                    System.out.println("线程2,再次获取到锁。");

                    Thread.sleep(5 * 1000);

                    lock2.release();
                    System.out.println("线程2,释放锁。");

                    lock2.release();
                    System.out.println("线程2,再次释放锁。");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private static CuratorFramework getCuratorFramework() {
        ExponentialBackoffRetry policy = new ExponentialBackoffRetry(3000, 3);

        CuratorFramework client = CuratorFrameworkFactory.builder().connectString("node1:2181,node2:2181,node3:2181")
                .connectionTimeoutMs(2000)
                .sessionTimeoutMs(2000)
                .retryPolicy(policy).build();

        client.start();//启动客户端

        System.out.println("zookeeper启动成功。");
        return client;
    }
}

第06章-企业面试真题(面试重点)

P029【029_尚硅谷_zk_企业面试真题】03:32

6.1 选举机制

半数机制,超过半数的投票通过,即通过。

(1)第一次启动选举规则:投票过半数时,服务器 id 大的胜出

(2)第二次启动选举规则:①EPOCH 大的直接胜出、②EPOCH 相同,事务 id 大的胜出、③事务 id 相同,服务器 id 大的胜出

6.2 生产集群安装多少zk合适?

安装奇数台。

生产经验:10 台服务器:3 台 zk;20 台服务器:5 台 zk;100 台服务器:11 台 zk;200 台服务器:11 台 zk。

服务器台数多:好处,提高可靠性;坏处:提高通信延时

6.3 常用命令

ls、get、create、delete

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/418850.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3 关于setup与自定义指令

setup语法糖 最大好处就是所有声明部分皆可直接使用&#xff0c;无需return出去 注意&#xff1a;部分功能还不完善&#xff0c;如&#xff1a;name、render还需要单独加入script标签按compositionAPI方式编写 // setup 下还可以附加<script> setup语法糖独有 &…

【CocosCreator入门】CocosCreator组件 | Graphics(绘制)组件

Cocos Creator 是一款流行的游戏开发引擎&#xff0c;具有丰富的组件和工具&#xff0c;其中Graphics组件允许您在游戏中绘制2D图形和几何形状&#xff0c;并通过编写脚本来控制其外观和行为。 目录 一、组件属性 二、组件方法 三、脚本示例 一、组件属性 属性功能说明lineW…

MySQL删除数据1093错误

现象&#xff1a;在进行更新和删除操作的时候&#xff0c;条件语句里面有子查询语句&#xff0c;此时会报1093错误&#xff01; 错误日志&#xff1a;1093 - You can’t specify target table ‘t_suer_study_video’ for update in FROM clause 首先根据条件来查询 SELECT * …

动手学深度学习V2的笔记小记

自动求导 两种方式&#xff1a;正向&#xff0c;反向 内存复杂度&#xff1a;O(n) 计算复杂度&#xff1a;O(n) 线性回归 梯度下降通过不断沿着反梯度方向更新参数求解 两个重要的超参数是批量大小和学习率 小批量随机梯度下降是深度学习默认的求解算法 训练误差和泛化误差 训练…

Matlab论文插图绘制模板第85期—模值赋色的箭头图

在之前的文章中&#xff0c;分享了Matlab箭头图的绘制模板&#xff1a; 进一步&#xff0c;如果我们想对每一个箭头赋上颜色&#xff0c;以更加直观地表示其模值的大小&#xff0c;该怎么操作呢&#xff1f; 那么&#xff0c;来看一下模值赋色的箭头图的绘制模板。 先来看一下…

微短剧的春天里,抖音、快手各有所思

2023年&#xff0c;微短剧将延续爆发之势。 从今年热播的《二十九》《二见钟情》《步步为陷》《倾世小狂医》《开局一座山》《都市至尊赘婿》等作品上&#xff0c;我们看到了微短剧题材的扩展和剧情的张力。相比刚刚兴起时&#xff0c;微短剧脑洞更大、质量更优&#xff0c;还…

CC2642的GGS使用笔记

一、前言 我们了解BLE的GATT之前需要了解一些基本的概念&#xff1a; &#xff08;1&#xff09;Profile,字面意思简介、概述、形象印象、轮廓、配置文件&#xff0c;在BLE中&#xff0c;我们可能把它理解成配置文件较好&#xff0c;Profile有一些是BLE SIG规定的&#xff0c;有…

从Vue2到Vue3的差别学习升级

目录 1 从data,methods到setup 超级NB的写法 2 使用props、emit和context 使用props 使用emit 3 路由变化 4 变量初始化的变化 1 从data,methods到setup <script> export default {components:{NPagination:NPagination,},name: "MyPaging",setup(){//…

Python实现哈里斯鹰优化算法(HHO)优化BP神经网络分类模型(BP神经网络分类算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 2019年Heidari等人提出哈里斯鹰优化算法(Harris Hawk Optimization, HHO)&#xff0c;该算法有较强的全…

Unix、UTC、GPS时间戳及转换

UTC时间 UTC时间的英文全称&#xff1a;Universal Time Coordinated&#xff0c;中文名称&#xff1a;协调世界时。俗的理解为&#xff0c;这个时间是全世界通用的&#xff0c;即全世界都公用的一个时间。可以认为格林威治时间就是时间协调时间&#xff08;GMTUTC&#xff09;&…

聚焦元宇宙赋能产业,打造数字世界,“OFweek2023广州元宇宙产业发展高峰论坛”圆满落幕!

2023年4月12日下午&#xff0c;由广东潮域科技有限公司、OFweek维科网共同主办&#xff0c;OFweek人工智能网承办的“OFweek 2023 广州元宇宙产业发展高峰论坛”在广州保利世贸博览馆1号馆盛大举办。 元宇宙产业相关技术及设备&#xff0c;包括VR&#xff0f;AR、虚拟现实、物联…

PHP 调用百度人脸检测

本文章主要介绍人脸检测API能力、应用场景、请求实例、参数说明。 接口能力 人脸检测&#xff1a;检测图片中的人脸并标记出位置信息。 人脸关键点&#xff1a;展示人脸的核心关键点信息&#xff0c;及150个关键点信息。 人脸属性值&#xff1a;展示人脸属性信息&#xff0c;如…

[MAUI 项目实战] 手势控制音乐播放器(四):圆形进度条

文章目录关于图形绘制创建自定义控件使用控件创建专辑封面项目地址我们将绘制一个圆形的音乐播放控件&#xff0c;它包含一个圆形的进度条、专辑页面和播放按钮。关于图形绘制 使用MAUI的绘制功能&#xff0c;需要Microsoft.Maui.Graphics库。 Microsoft.Maui.Graphics 是一个…

【技术】《Netty》从零开始学netty源码(三十七)之ByteBufAllocator

ByteBufAllocator 在channel的配置类中有一个属性allocator&#xff0c;我们知道netty有自己的缓冲区&#xff0c;可以使用该缓存分配器来分配所需的缓存。在config类中默认使用ByteBufAllocator.DEFAULT&#xff0c;它的初始化过程如下&#xff1a; 在开始分析PooledByteBufA…

基于 QT 开发 FLIPPED :简易且漂亮的跨平台截图贴图软件

文章目录FLIPPED运行预览视频演示截图演示特性快捷键架构思路思路细节打磨实际问题解决方案编译依赖WindowsMacOS / Linux运行效果作者贡献者反馈下载安装包系列地址简 述: 新开发的一款跨平台的截图贴图的软件作品&#xff0c; FLIPPED&#xff1a;Simple and beautiful cross…

基于Web的智慧LNG加气站2D组态控制系统

LNG(Liquefied Natural Gas)&#xff0c;即液化天然气的英文缩写。LNG是通过在常压下气态的天然气&#xff0c;经过预处理&#xff0c;脱除重烃、硫化物、二氧化碳和水等杂质后&#xff0c;冷却至-162℃&#xff0c;使之凝结成液体。LNG无色无毒无味&#xff0c;是天然气经净化…

算法分析与设计—分治法

分治者&#xff0c;分而治之也。概述分治法也称为分解法、分治策略等。分治法算法思想如下&#xff1a;(1) 将一个问题划分为同一类型的若干子问题&#xff0c;子问题最好规模相同。(2) 对这些子问题求解&#xff08;一般使用递归方法&#xff0c;但在问题规模足够小时&#xf…

fileinclude(通过cookie赋值的文件包含)

打开链接&#xff0c;提示flag在flag.php里 内容里还有一个路径/var/www/html/index.php&#xff0c;猜测flag.php应该也是在这个路径下 Ctrlu查看网页源码 代码中发现 include($lan.".php"); 可知这里存在文件包 且包含与lan的值有关 由代码 $lan $_COOKIE[lang…

安装kafka及一些命令

1&#xff0c;先把压缩包放到/opt/install目录下 2&#xff0c;解压&#xff0c;更名 解压&#xff1a;[rootsiwen install]# tar -zxf kafka_2.12-2.8.0.tgz -C ../soft 更名&#xff1a;[rootsiwen soft]# mv kafka_2.12-2.8.0/ kafka212 3&#xff0c;配置文件 cd opt/so…

讯飞 语音唤醒 Android SDK

语音唤醒 Android SDK 文档 | 讯飞开放平台文档中心https://www.xfyun.cn/doc/asr/awaken/Android-SDK.html前往控制台&#xff0c;设置唤醒关键词&#xff1a; 控制台-讯飞开放平台https://console.xfyun.cn/services/awaken注意&#xff0c;可以对唤醒词进行评估&#xff0c…