首页 > 其他分享 >Zookeeper 介绍

Zookeeper 介绍

时间:2023-06-28 23:44:39浏览次数:42  
标签:zookeeper zk Zookeeper curator 介绍 2181 节点

一、Zookeeper 介绍 1.什么是 Zookeeper Zookeeper 是一种分布式协调服务用于管理大型主机,分布式环境中协调管理服务是一个复杂的过程,Zookeeper 通过其简单的架构和 API 解决这个问题。Zookeeper 允许开发人员专注于核心应用程序逻辑,而不必担心应用程序的分布特性。 2.Zookeeper 的应用场景

  • 分布式协调组件
0 在分布式系统中,需要有 Zookeeper 作为分布式协调组件,协调分布系统中的状态。
  • 分布式锁
Zookeeper 在实现分布式锁上,可以做到强一致性,CP(一致性,分区容错性)
  • 无状态化的实现
0 二、搭建 Zookeeper 服务器 1.配置文件说明 # The number of milliseconds of each tick # 每次心跳时间 tickTime=2000 # The number of ticks that the initial # synchronization phase can take # 允许 follower 链接初始化连接到 leader 最大时间 它表示 tickTime 的时间倍数 initLimit=10 # The number of ticks that can pass between # sending a request and getting an acknowledgement # 允许 follower 与 leader 数据同步最大时间 它表示 tickTime 的时间倍数 syncLimit=5 # the directory where the snapshot is stored. # do not use /tmp for storage, /tmp here is just # example sakes. # 数据保存目录,(如果没有指定dataLogDir也保存到这个目录) dataDir=/opt/homebrew/var/run/zookeeper/data # the port at which the clients will connect # 对客户端提供的端口号 clientPort=2181 # the maximum number of client connections. # increase this if you need to handle more clients # 单个客户端 zookeeper 允许连接端最大数量 #maxClientCnxns=60 # # Be sure to read the maintenance section of the # administrator guide before turning on autopurge. # # http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance # # The number of snapshots to retain in dataDir # 保存数据的快照数量,超过会被删除 #autopurge.snapRetainCount=3 # Purge task interval in hours # Set to "0" to disable auto purge feature # 自动触发清除任务的时间间隔(单位小时),0为不清理 #autopurge.purgeInterval=1 ​ ## Metrics Providers # # https://prometheus.io Metrics Exporter #metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider #metricsProvider.httpPort=7000 #metricsProvider.exportJvmInfo=true 2.相关命令 # 启动 zookeeper 服务 zkServer start ​ # 查看 zookeeper 状态 zkServer status ​ # 停止 zookeeper 服务 zkServer stop 3.docker 搭建单机 zookeeeper # 获取镜像 docker pull zookeeper # 安装 zookeeper docker run --name zookeeper-1 --restart always -d zookeeper # 进入 zk 命令窗口 docker exec -it 镜像ID zkCli.sh 三、Zookeeper 内部数据模型 1.zk 是如何保存数据的 zk 中的数据是保存在节点上的,节点就是 znode,多个 zonde 之间构成一颗树的目录结构。 0 树是由节点组成,Zookeeper 的数据存储也同样是基于节点,这种节叫做 Znode。但是,不同于树的节点,Znode 的引用方式是 路径引用,类似文件路径。 命令: # 查看节点 ls ​ # 创建根节点 test create /test1 ​ # 创建节点并设置 值 create /test1/sub1 abc ​ # 获取节点值 get /test1/sub1 abc 这样的层次结构,让每一个 Znode 节点拥有唯一的路径,就像命名空间一样对不同信息作出清晰的隔离。 2.zk 中的 znode 结构 zk 中的 znode,包含了四个部分:
  • data:保存数据
  • acl:权限
    • c:create 创建权限,允许在该节点下创建子节点
    • w:write 更新权限,允许更新该节点的数据
    • r:read 读取权限,允许读取节点的内容以及子节点的列表信
    • d:delete 删除权限,允许删除该节点的子节点
    • a:admin 管理者权限,允许对该节点进行 acl 权限设置
  • stat:描述当前 znode 的元数据
  • child:当前节点的子节点
3.zk 中节点 znode 类型
  • 持久节点:创建出的节点,在会话结束后依然存在。保存数据
create /test
  • 持久有序节点:创建出的节点根据先后顺序,会在节点子后带上一个数值,越后执行数值越大,适用于分布式锁的应用场景——单调递增
create -s /test
  • 临时节点:临时节点是在会话结束后,自动被删除的,通过这个特性,zk 可以实现服务注册与发现效果。那么临时节点如何维持心跳呢?
0   create -e /test
  • 临时序号节点:跟持久序号节点相同,适用于临时的分布式锁。
create -e -s /test
  • Container 节点(3.5.3版本新增):Container 容器节点,当容器中没有任何子节点,该容器节点会被 zk 定期删除(60s)。
create -c /test
  • TTL 节点:可以指定节点到期时间,到期后被 zk 定时删除。只通过系统配置 zookeeper.extendedTypesEnabled = true 开启。
4.zk 的数据持久化 zk 的数据是运行在内存中,zk 提供了两种持久化机制:
  • 事物日志
zk 把执行的命令以日志的方式保存在 dataLogDir 指定的路径中的文件中(如果没有指定 dataLogDir,则按 dataDir 指定的路径)。
  • 数据快照
zk 会在一定的时间间隔内做一次内存数据的快照,把该时刻的内存数据保存在文件中。 zk 通过两种形式的持久化,在恢复时先恢复快照文件中的数据到内存中,再用日志文件中的数据做增量恢复,这样恢复速度更快。 四、Zookeeper 客户端(zkCli)的使用 1.多节点类型创建
  • 创建持久节点
  • 创建持久序列号节点
  • 创建临时节点
  • 创建临时序号节点
  • 创建容器节点
2.查询节点
  • 普通查询
  • 查询节点相信信息
    • cZxid:创建节点的事物 ID
    • mZxid:修改节点的事物 ID
    • pZxid:添加和删除节点的事物 ID
    • ctime:节点的创建时间
    • mtime:节点最近修改的时间
    • dataVersion:节点内数据的版本,每更新一次数据,版本就会+1
    • aclVersion:此节点的权限版本
    • ephemeOwner:如果当前节点是临时节点,该值是当前节点所有者的 session id。如果节点不是临时节点,则该值为零。
    • dataLength:节点内数据的数据长度
    • numChildren:该节点的子节点个数据
3.删除节点
  • 普通删除
  • 乐观锁删除
4.权限设置
  • 注册当前会话的账号和密码:
addauth digest xiaowang:123456
  • 创建节点并设置权限:
create /test abcd auth:xiaowang:123456:cdwra
  • 在另一会话中必须使用账户密码,才能拥有操作该节点的权限
五、Curator 客户端的使用 1.Curator 介绍 Curator 是 Netfix 公司开源的一套 zookeeper 客户端框架,Curator 是对 Zookeeper 支持最好的客户端框架。Curator 封装了大部分 Zookeeper 的功能,比如 Leader 选举,分布式锁,减少了技术人员在使用 Zookeeper 时底层细节开发工作。 2.引入 Curator
  • 引入依赖
<!-- Curator --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.12.0</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>2.12.0</version> </dependency> <!-- zookeeper --> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.7.0</version> </dependency>
  • application.properties 配置文件
curator.retryCont = 5 curator.elapsedTimeMs = 5000 curator.connectString = 127.0.0.1:2181 curator.sessionTimeoutMs = 60000 curator.connectionTimeoutMs = 5000
  • 注入配置 Bean
WrapperZk.class package com.qf.bootzkclient.config; ​ import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; ​ @Data @Component @ConfigurationProperties(prefix = "curator") public class WrapperZk { private int retryCount; ​ private int elapsedTimeMs; ​ private String connectString; ​ private int sessionTimeoutMs; ​ private int connectionTimeoutMs; } ​ CuratorConfig.class package com.qf.bootzkclient.config; ​ import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.retry.RetryNTimes; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; ​ @Configuration public class CuratorConfig { @Autowired WrapperZk wrapperZk; ​ @Bean(initMethod = "start") public CuratorFramework curatorFramework() { return CuratorFrameworkFactory.newClient( wrapperZk.getConnectString(), wrapperZk.getSessionTimeoutMs(), wrapperZk.getConnectionTimeoutMs(), new RetryNTimes(wrapperZk.getRetryCount(), wrapperZk.getElapsedTimeMs()) ); } } 3.创建节点 @Slf4j @SpringBootTest class BootZkClientApplicationTest { ​ @Autowired private CuratorFramework curatorFramework; ​ @Test public void create() throws Exception { // 添加持久节点 String path = curatorFramework.create().forPath("/curator-node2"); // 添加临时序号节点 // String s = curatorFramework.create().withProtection(CreateMode.EPHEMERAL_SEQUENTIAL). // forPath("/curator-node", "some-date".getBytes()); System.out.println("curator create node " + path + " successfully"); } } 六、zk 实现分布式锁 1.zk 中锁的种类
  • 读锁:大家都可以读取,要想上读锁前提:之前没有写锁。
  • 写锁:只有得到写锁的才能写,要想上写锁的前提是,之前没有任何锁。
2.zk 中如何上锁
  • 创建一个临时序号节点,节点的数据是 read,表示读锁
  • 获取当前 zk 中序号比自己小的所有节点
  • 判断最小节点是否是读锁:
    • 如果不是读锁,则上锁失败,为最小节点设置监听。阻塞等待,zk 的 watch 机制会当最小节点发生变化时通知当前节点,于是在执行第二步的流程
    • 如果是读锁的话,则上锁成功
0 3.zk 如何上写锁
  • 创建一个临时序号节点,节点的数据是 wirte,表示是写锁
  • 获取 zk 中所有的子节点
  • 判断自己是否是最小节点:
    • 如果是,则写锁成功
    • 如果不是,说明前面还有锁,则上锁失败,监听最小的节点,如果最小节点发生变化,则回到第二步。
0 4.羊群效应 如果用上述的上锁方式,只要有节点发生变化,就会触发其他节点的监听事件,这样的话对 zk 的压力非常大——羊群效应。可以调整成链式监听,就可以解决这个问题。 0 5.Curator 实现读写锁
  1. 获取读锁
@Test void testGetReadLock() throws Exception { // 读写锁 InterProcessReadWriteLock interProcessReadWriteLock = new InterProcessReadWriteLock(curatorFramework, "/lock1"); // 获取读锁对象 InterProcessLock interProcessLock = interProcessReadWriteLock.readLock(); System.out.println("等待获取读锁对象"); // 获取锁 interProcessLock.acquire(); for (int i = 0; i <= 100; i++) { Thread.sleep(3000); System.out.println(i); } // 释放锁 interProcessLock.release(); System.out.println("等待释放锁"); }
  1. 获取写锁
@Test void testGetWriteLock() throws Exception { // 读写锁 InterProcessReadWriteLock interProcessReadWriteLock = new InterProcessReadWriteLock(curatorFramework, "/lock1"); // 获取读锁对象 InterProcessLock interProcessLock = interProcessReadWriteLock.writeLock(); System.out.println("等待获取写锁对象"); // 获取锁 interProcessLock.acquire(); for (int i = 0; i <= 100; i++) { Thread.sleep(3000); System.out.println(i); } // 释放锁 interProcessLock.release(); System.out.println("等待释放锁"); } 七 、zk的 watch 机制 1.watch 机制介绍 我们可以吧 Watch 理解成是注册在特定 Znode 上的触发器,当这个 Znode 发生改变,也就是调用了 create, delete, setData 方法的时候,将会触发 Znode 上注册的对应时间,请求 Watch 的客户端会接受到异步通知。 具体交互过程如下:
  • 客户端调用
getDate 方法,watch 是 true 。服务端接到请求,返回节点数据,并且在对应的哈希表插入被 Watch 的 Znode 路径。 0  
  • 当被 Watch 的 Znode 已删除,服务器会查找哈希表,找到该 Znode 对应的所有 Watcher,异步通知客户端,并删除花溪表中对应的 Key-Value。
    0 客户端使用了 NIO 通信模式监听服务端的调用。 2.zkCli 客户端使用 watch create /test xxx # 一次性监听 get -w /test # 监听目录,创建和删除子节点会收到通知。子节点中新增节点不会收到通知 ls -w /test # 对于子节点的变化,但内容的变化不会收到通知 ls -R -w /test 3.curator 客户端使用 watch @Test public void addNodeListener() throws Exception { NodeCache nodeCache = new NodeCache(curatorFramework, "/curator-node"); nodeCache.getListenable().addListener(new NodeCacheListener() { @Override public void nodeChanged() throws Exception { log.info("{} path nodeChange:","/curator-node"); printNodeDate(); } }); nodeCache.start(); // 让这个线程阻塞在这里避免监控线程关闭 System.in.read(); } ​ ​ public void printNodeDate() throws Exception { byte[] bytes = curatorFramework.getData().forPath("/curator-node"); log.info("data: {}",new String(bytes)); } 八、zookeeper 集群 1.Zookeepr 集群角色 zookeeper 集群中的节点三种角色
  • Leader:处理集群的所有事务请求,集群中只有一个 Leader
 
  • Follower:只能处理请求,参与 Leader 选举
 
  • Obeserver:只能处理请求,提升集群读的性能,但不能参与 Leader 选举
  2.docker 安装 zookdeeper 集群
  1. 创建一个
docker-compose.yml version: '3.7' services: zoo1: image: zookeeper restart: always container_name: zoo1 ports: - "2181:2181" environment: ZOO_MY_ID: 1 ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181 server.4=zoo4:2888:3888;2181:observer zoo2: image: zookeeper restart: always container_name: zoo2 ports: - "2182:2181" environment: ZOO_MY_ID: 2 ZZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181 server.4=zoo4:2888:3888;2181:observer zoo3: image: zookeeper restart: always container_name: zoo3 ports: - "2183:2181" environment: ZOO_MY_ID: 3 ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181 server.4=zoo4:2888:3888;2181:observer zoo4: image: zookeeper restart: always container_name: zoo4 ports: - "2184:2181" environment: ZOO_MY_ID: 4 ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181 server.4=zoo4:2888:3888;2181:observer ​
  1. 后台运行
  COMPOSE_PROJECT_NAME=zk_test docker-compose up
  1. 连接
  zkClis.sh
  1. 查看配置
  zkServer.sh status # 查询结果 ZooKeeper JMX enabled by default Using config: /conf/zoo.cfg Client port found: 2181. Client address: localhost. Client SSL: false. Mode: leader 九、ZAB 协议 1.什么是 ZAB 协议 zookeeper 作为非常重要的分布式协调组件,需要进行集群部署,集群中会以一株多从多形式进行部署。zookeeper 为了保证数据的一致性,使用了 ZAB(Zookeeper Atomic Broadcas)协议,这个协议解决了 Zookeeper 的崩溃恢复和主从数据同步的问题。 0 2.ZAB 协议定义的四种节点状态
  • Looking:选举状态。
 
  • Following:Follower 节点(从节点)所处状态。
 
  • Leading:Leader 节点(主节点)所处状态。
 
  • Observing:观察者绩点所处状态
  3.集群上线时的 Leader 选举过程 Zookeeper 集群中的节点在上线时,将会进入 Looking 状态,也就是选举 Leader的状态,这个状态具体会发生什么? 0 myid: zXid:事物 ID,描述数据变化 数据如何变化 0 4.Zookeeper 中的 NIO 与 BIO 的应用
  • NIO
    • 用与被客户端连接的2181 端口,使用的是 NIO 模式与客户端建立连接
    • 客户端开启 Watch 时,也使用 NIO,等待 Zookeeper 服务等回调
  • BIO
    • 集群在选举时,多个节点之间等投票通信,使用 BIO 进行通信。
十、CAP 原理
  • 一致性(Consistency)
  • 可用性(Availability)
  • 分区容错性(Partition tolerance)
       

标签:zookeeper,zk,Zookeeper,curator,介绍,2181,节点
From: https://www.cnblogs.com/SolitaryHua/p/17512846.html

相关文章

  • 10redis列表操作,其他操作,redis管道,django中使用redis,django缓存,序列化json和pickle,cel
    字符串和字节转换的两种方式#字符串和字节转换的两种方式 -decode,encode-直接类型转换-bytes格式的16进制,2进制,10进制的显示#字符串需要用encode,bytes格式需要用decode,但是有时候忘了#可以直接进行强转b1=bytes(s,encoding='utf-8') print(......
  • 免费体验Stable Diffusion deforum文转视频插件,还有deforum API 接口部署介绍!
    如何使用ServerlessDevs和函数计算快速体验部署StableDiffusion,这个是小白也能简单体验安装部署的教程.有电脑就能操作,依托阿里云原生服务.不用考虑硬件问题本篇主要讲解怎么安装跟部署自定义安装插件跟模型.以deforum文转视频插件举例.deforumapi接口自定义开发镜像定......
  • jwt介绍
    适用场景前后端分离时,登陆后,用户标识保存到客户端,后续请求时,带着用户标识,以此来区分是否登录。用户标识可以是用户id、也可以包含其他字段,通常还得加密或者加签名,提交到服务器端时还要验证签名,这块信息没有约定格式,jwt就是一个格式,它规定了签名、加密、内容等等。简介jwt=jsonweb......
  • 1、Apache Kudu介绍及架构、工作原理、两种部署方式、使用限制详解
    ApacheKudu系列文章1、ApacheKudu介绍及架构、工作原理、两种部署方式、使用限制详解2、ApacheKudu-javaapi操作kudu详细示例以及kudu的三种实现示例3、ApacheKudu集成impala(shell和java操作)的详细操作(文章目录)本文简单的介绍了kudu的基本情况、架构、部署、原理......
  • 浅谈智能照明控制管理系统的功能介绍
    罗轩志安科瑞电气股份有限公司上海嘉定201801摘要:智能照明控制系统较好地实现了智能控制、人性化照明和节能降耗的功能,使其在楼宇控制领域变得越来越重要,越来越受到人们的重视。本文介绍了智能照明控制系统的概念、特点、优势、发展方向等内容,并着重对智能照明控制系统的结构......
  • Kubernetes编程——client-go基础—— Go语言中的 Kubernetes 对象介绍
    Go语言中的Kubernetes对象介绍 我们接下来更详细了解在Go语言的语境下的Pod(或者其他任何Kubernetes资源)是什么样的? Kubernetes中的资源(或者更准确说是对象)都是某种类型的实例。我理解意思是说:在Kubernetes中,资源或对象是指由Kubernetes控......
  • TOF方案在DW1000上的实现(五):官方套件介绍
    TREK1000介绍在前面TWR测距技术的基础上,DW1000的厂商推出了一套RTLS(realtimelocationsystem,实时定位系统)开发套件TREK1000。该套件包括多块基于STM32+DW1000的开发板,配套的嵌入式软件、PC端上位机及源码。可以实现如下应用演示:TOA定位电子围栏室内导航套件开箱打开......
  • Haproxy介绍及安装
    Haproxy是一个使用C语言编写的自由及开放源代码软件,其提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。参考网址......
  • 介绍Hibernate使用UserType - 51CTO.COM
     介绍Hibernate使用UserType这里介绍Hibernate使用UserType,UserType就是用户自定义类型,这里的类型指的是除了Hibernate定义的那些类型之外的用户自己定义的。AD: Hibernate有很多值得学习的地方,这里我们主要介绍Hibernate使用UserType,包括介绍UserType就是用户自定义类型......
  • JMS - ActiveMQ - 介绍 、使用场景、优点和不足
    ActiveMQj简介ActiveMQ是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ是一个完全支持JMS1.1和J2EE1.4规范的JMSProvider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。开源的JMSProvider大部分都已经停止发展。  Active......