ZooKeeper(分布式协调服务)使用介绍

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: ZooKeeper 是一个开源的分布式协调服务,目前由 Apache 进行维护。ZooKeeper 可以用于实现分布式系统中常见的发布/订阅、负载均衡、命令服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。

ZooKeeper(分布式协调服务)使用介绍



一、ZooKeeper 简介


1.ZooKeeper 设计目标

2.核心概念

1)Session 会话

2)数据节点

3)Watcher

4)ACL

3.Zab 协议介绍


二、ZooKeeper Cluster 安装


1.安装 ZooKeeper

2.使用 Golang 连接 ZooKeeper 的 API 接口

3.配置 ZooKeeper Cluster


一、ZooKeeper 简介



ZooKeeper 是一个开源的分布式协调服务,目前由 Apache 进行维护。ZooKeeper 可以用于实现分布式系统中常见的发布/订阅、负载均衡、命令服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。 它具有以下特性:


  • 顺序一致性: 来自客户端的更新操作将会按照顺序被应用;
  • 原子性: 即要么全部更新成功,要么要不更新失败,没有部分的结果;
  • 统一的系统镜像: 即不管客户端连接的是哪台服务器,都能看到同样的服务视图(也就是无状态的)
  • 可靠性: 一旦写入操作被执行,那么这个状态将会被持久化,直到其它客户端的修改生效。
  • 实时性: 一旦一个事务被成功应用,ZooKeeper 可以保证客户端立即读取到这个事务变更后的最新状态的数据。


1.ZooKeeper 设计目标


  • ZooKeeper 致力于为那些高吞吐的大型分布式系统提供一个高性能、高可用、且具有严格顺序访问控制能力的分布式协调服务。


1)简单的数据模型:


  • ZooKeeper 通过树形结构来存储数据,它由一系列被称为 ZNode 的数据节点组成,类似于常见的文件系统;
  • 不过和常见的文件系统不同,ZooKeeper 将数据全量存储在内存中,以此来实现高吞吐,减少访问延迟。


2)可配置 Cluster:


  • 为了保证高可用,最好是以集群形态部署 ZooKeeper,这样只要集群中大部分机器是可用的,那么 ZooKeeper 本身仍然可用。


image.png


上图中每一个 Server 代表一个安装 ZooKeeper 服务的服务器,组成 ZooKeeper 服务的服务器都会在内存中维护当前的服务器状态,并且每台服务器间都保持着通信。并通过 Zab 协议来保持数据的一致性。


3)顺序访问:


  • 对于来自客户端的每个更新请求,ZooKeeper 都会分配一个全局唯一的递增 ID,这个 ID 决定了所有事务操作的先后顺序。


4)高性能高可用


  • ZooKeeper 将数据全量存储在内存中以保持高性能,并通过服务集群来实现高可用;
  • 由于 ZooKeeper 的所有更新和删除都是基于事务的,所以其在读多写少的应用场景中有着很高的性能表现。


2.核心概念


Cluster 角色:


image.png


1)Session 会话


当 Client 通过 TCP 长连接 连接到 ZooKeeper 服务器时,Session 便开始建立连接,并通过 tickTime(心跳检测)机制来保持有效的会话状态。通过这个连接,Client 可以发送请求并接收响应,同时也可以接收到 Watch 事件的通知。


另外,当由于网络故障或者 Client 主动断开等原因,导致连接断开,此时只要在会话超时时间之内重新建立连接,则之间创建的会话依然有效。(这个取决于 tickTime 配置)


2)数据节点


ZooKeeper 数据模型是由一系列基本数据单元 ZNode(数据节点)组成的节点树,其中根节点为 /(每个节点上都会保存自己的数据和节点信息);ZooKeeper 中的节点可以分为两大类:


  • 持久节点: 节点一旦创建,除非被主动删除,否则一直存在。
  • 临时节点: 一旦创建该节点的客户端会话(Session)失效,则所有该客户端创建的临时节点都会被删除。


3)Watcher


ZooKeeper 中一个常用的功能是 Watcher(事件监听器),它允许用户在指定节点上针对感兴趣的事件注册监听,当事件发生时,监听器会被触发,并将事件推送到客户端。该机制是 ZooKeeper 实现分布式协调服务的重要特性。


4)ACL


ZooKeeper 采用 ACL(Access Control Lists)策略来进行权限控制,类似于 Unix 文件系统的控制权限:


image.png


3.Zab 协议介绍


  • Zab(ZooKeeper Atomic Broadcast 原子广播)协议是为分布式协调服务 ZooKeeper 专门设计的一种 支持崩溃恢复的原子广播协议;
  • 在 ZooKeeper 中,主要依赖 Zab 协议来实现分布式数据一致性;
  • 基于 Zab 协议,ZooKeeper 实现了一种主备模式的系统架构来保持集群中各个副本间的数据一致性。


二、ZooKeeper Cluster 安装



准备工作:


 image.png


[root@ZooKeeper ~]# ls
anaconda-ks.cfg  jdk-8u181-linux-x64.tar.gz
[root@ZooKeeper ~]# tar zxf jdk-8u181-linux-x64.tar.gz 
[root@ZooKeeper ~]# ls
anaconda-ks.cfg  jdk1.8.0_181  jdk-8u181-linux-x64.tar.gz
[root@ZooKeeper ~]# mv jdk1.8.0_181 /usr/local/java
[root@ZooKeeper ~]# cat <<"END" >> /etc/profile
export JAVA_HOME=/usr/local/java
export PATH=$PATH:$JAVA_HOME/bin
END
[root@ZooKeeper ~]# source /etc/profile
[root@ZooKeeper ~]# java -version


image.png


1.安装 ZooKeeper


[root@ZooKeeper ~]# wget http://dlcdn.apache.org/zookeeper/zookeeper-3.6.3/apache-zookeeper-3.6.3-bin.tar.gz
[root@ZooKeeper ~]# ls
anaconda-ks.cfg  apache-zookeeper-3.6.3-bin.tar.gz  jdk-8u181-linux-x64.tar.gz
[root@ZooKeeper ~]# tar zxf apache-zookeeper-3.6.3-bin.tar.gz
[root@ZooKeeper ~]# mv apache-zookeeper-3.6.3-bin /usr/local/zookeeper
[root@ZooKeeper ~]# mkdir /usr/local/zookeeper/data
[root@ZooKeeper ~]# cat <<END >> /usr/local/zookeeper/conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/usr/local/zookeeper/data
clientPort=2181
END


注解:


  • tickTime:Client 和服务器间的通信会话限制(相当于健康检查,tickTime 的时间为 ms (1s = 1000ms))
  • initLimit:Leader 和 Follower 间初始通信限制。
  • syncLimit:Leader 和 Follower 间同步通信限制(当响应时间超于 syncLimit * tickTime 时,Leader 便会将 Follower 进行移除)
  • dataDir:此目录用于存放保存在内存数据库中的快照信息(当未配置 dataLogDir 参数时,日志信息也会存放到此目录)
  • clientPort:ZooKeeper 监听的端口,用于客户端连接使用。


启动 ZooKeeper


[root@ZooKeeper ~]# /usr/local/zookeeper/bin/zkServer.sh start            # 启动
[root@ZooKeeper ~]# /usr/local/zookeeper/bin/zkServer.sh status           # 查看状态


image.png


连接到 ZooKeeper


[root@ZooKeeper ~]# /usr/local/zookeeper/bin/zkCli.sh -server 127.0.0.1:2181
Welcome to ZooKeeper!
JLine support is enabled
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
[zk: 127.0.0.1:2181(CONNECTED) 0] 


  • 当连接成功后,系统会输出 ZooKeeper 的相关配置信息和相关环境,并在屏幕上输出 Welcome to ZooKeeper! 等信息。


2.使用 Golang 连接 ZooKeeper 的 API 接口


  • 安装 Golang:安装


package main
import (
    "fmt"
    "time"
    "go-zookeeper/zk"
)
func main() {
    Hosts := []string{"192.168.1.1:2181"}
    conn, _, err := zk.Connect(Hosts,time.Second * 5)
    defer conn.Close()
    if err != nil {
        fmt.Println(err)
        return
    }
}


image.png


通过 Golang 实现对 ZooKeeper 的增删改查:


package main
import (
    "fmt"
    "time"
    "go-zookeeper/zk"
)
var (
    path = "/Zzz"
)
//增
func add(conn *zk.Conn) {
    var data = []byte("Hello ZooKeeper")
    // flags 的四种取值方式:
    // 0 (永久.除非手动删除)
    // zk.FlagEphemeral = 1 (短暂. session 断开则该节点也被删除)
    // zk.FlagSequence = 2 (会自动在节点后面添加序号)
    // 3 (Ephemeral 和 Sequence. 即短暂且自动添加序号)
  var flags int32 = 0
  // 获取访问控制权限
  acls := zk.WorldACL(zk.PermAll)
  create, err := conn.Create(path,data,flags,acls)
  if err != nil {
      fmt.Printf("创建失败: %v\n",err)
    return
    }
  fmt.Printf("创建: %v 成功\n",create)
}
// 查
func get(conn *zk.Conn) {
    data, _, err := conn.Get(path)
  if err != nil {
      fmt.Printf("查询 %s 失败,err: %v\n",path,err)
      return
  }
  fmt.Printf("%s 的值为 %s\n",path,string(data))
}
// 删除与增加不同在于其函数中的 Version 参数. 其中 Version 使用 CAS 支持 (可以通过此种方式保证原子性)
// 改
func modify(conn *zk.Conn) {
    new_data := []byte("This is ZooKeeper")
    _, sate, _ := conn.Get(path)
    _, err := conn.Set(path,new_data,sate.Version)
    if err != nil {
      fmt.Printf("数据修改失败: %v\n",err)
      return
    }
    fmt.Println("数据修改成功")
}
// 删
func del(conn *zk.Conn) {
    _, sate, _ := conn.Get(path)
    err := conn.Delete(path,sate.Version)
    if err != nil {
        fmt.Printf("数据删除失败: %v\n",err)
      return
    }
    fmt.Println("数据删除成功")
}
func main() {
    hosts := []string{"192.168.1.1:2181"}
    conn, _, err := zk.Connect(hosts,time.Second * 5)
    defer conn.Close()
    if err != nil {
        fmt.Println(err)
      return
    }
    /* 增删改查 */
    add(conn)
    get(conn)
    modify(conn)
    get(conn)
    del(conn)
}


3.配置 ZooKeeper Cluster


  • 在原来的基础上,在增加两台服务器:


image.png


1)将 Java 和 ZooKeeper 传给新的服务器:  


[root@ZooKeeper ~]# scp -r /usr/local/java root@192.168.1.2:/usr/local/
[root@ZooKeeper ~]# scp -r /usr/local/zookeeper root@192.168.1.2:/usr/local/


2)在新的服务器上启动 ZooKeeper:


[root@ZooKeeper ~]# cat <<END >> /etc/profile
export JAVA_HOME=/usr/local/java
export PATH=$PATH:$JAVA_HOME/bin
END
[root@ZooKeeper ~]# source /etc/profile
[root@ZooKeeper ~]# /usr/local/zookeeper/bin/zkServer.sh start


3)配置 Cluster 集群(三台服务器上操作一样)


[root@ZooKeeper ~]# cat <<END >> /usr/local/zookeeper/conf/zoo.cfg
server.1=192.168.1.1:2888:3888
server.2=192.168.1.2:2889:3889
server.3=192.168.1.3:2890:3890
END


4)创建 myid 文件


[root@ZooKeeper ~]# echo "1" > /usr/local/zookeeper/data/myid
[root@ZooKeeper-2 ~]# echo "2" > /usr/local/zookeeper/data/myid
[root@ZooKeeper-2 ~]# echo "3" > /usr/local/zookeeper/data/myid


  • 需要确保每台服务器的 myid 文件中数字不同,并且和自己所在机器的 zoo.cfg 中 server.id=host:port:port 的 id 值一样。
  • 另外,id 的范围是 1 ~ 255。


5)重启 ZooKeeper 服务


[root@ZooKeeper ~]# /usr/local/zookeeper/bin/zkServer.sh restart      # 三台服务器都要重启


查看 ZooKeeper 状态:


image.png


验证:


image.png

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
相关文章
|
1月前
|
存储 缓存 算法
分布式锁服务深度解析:以Apache Flink的Checkpointing机制为例
【10月更文挑战第7天】在分布式系统中,多个进程或节点可能需要同时访问和操作共享资源。为了确保数据的一致性和系统的稳定性,我们需要一种机制来协调这些进程或节点的访问,避免并发冲突和竞态条件。分布式锁服务正是为此而生的一种解决方案。它通过在网络环境中实现锁机制,确保同一时间只有一个进程或节点能够访问和操作共享资源。
69 3
|
1月前
|
消息中间件 监控 Ubuntu
大数据-54 Kafka 安装配置 环境变量配置 启动服务 Ubuntu配置 ZooKeeper
大数据-54 Kafka 安装配置 环境变量配置 启动服务 Ubuntu配置 ZooKeeper
77 3
大数据-54 Kafka 安装配置 环境变量配置 启动服务 Ubuntu配置 ZooKeeper
|
1月前
|
监控 Dubbo Java
dubbo学习三:springboot整合dubbo+zookeeper,并使用dubbo管理界面监控服务是否注册到zookeeper上。
这篇文章详细介绍了如何将Spring Boot与Dubbo和Zookeeper整合,并通过Dubbo管理界面监控服务注册情况。
84 0
dubbo学习三:springboot整合dubbo+zookeeper,并使用dubbo管理界面监控服务是否注册到zookeeper上。
|
1月前
|
分布式计算 NoSQL Java
Hadoop-32 ZooKeeper 分布式锁问题 分布式锁Java实现 附带案例和实现思路代码
Hadoop-32 ZooKeeper 分布式锁问题 分布式锁Java实现 附带案例和实现思路代码
43 2
|
1月前
|
分布式计算 Hadoop
Hadoop-27 ZooKeeper集群 集群配置启动 3台云服务器 myid集群 zoo.cfg多节点配置 分布式协调框架 Leader Follower Observer
Hadoop-27 ZooKeeper集群 集群配置启动 3台云服务器 myid集群 zoo.cfg多节点配置 分布式协调框架 Leader Follower Observer
47 1
|
2月前
|
数据采集 分布式计算 MaxCompute
MaxCompute 分布式计算框架 MaxFrame 服务正式商业化公告
MaxCompute 分布式计算框架 MaxFrame 服务于北京时间2024年09月27日正式商业化!
89 3
|
1月前
|
存储 SQL 消息中间件
Hadoop-26 ZooKeeper集群 3台云服务器 基础概念简介与环境的配置使用 架构组成 分布式协调框架 Leader Follower Observer
Hadoop-26 ZooKeeper集群 3台云服务器 基础概念简介与环境的配置使用 架构组成 分布式协调框架 Leader Follower Observer
47 0
|
1月前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
|
3月前
|
NoSQL Redis
基于Redis的高可用分布式锁——RedLock
这篇文章介绍了基于Redis的高可用分布式锁RedLock的概念、工作流程、获取和释放锁的方法,以及RedLock相比单机锁在高可用性上的优势,同时指出了其在某些特殊场景下的不足,并提到了ZooKeeper作为另一种实现分布式锁的方案。
112 2
基于Redis的高可用分布式锁——RedLock
|
11天前
|
NoSQL Redis
Redis分布式锁如何实现 ?
Redis分布式锁通过SETNX指令实现,确保仅在键不存在时设置值。此机制用于控制多个线程对共享资源的访问,避免并发冲突。然而,实际应用中需解决死锁、锁超时、归一化、可重入及阻塞等问题,以确保系统的稳定性和可靠性。解决方案包括设置锁超时、引入Watch Dog机制、使用ThreadLocal绑定加解锁操作、实现计数器支持可重入锁以及采用自旋锁思想处理阻塞请求。
47 16

热门文章

最新文章

下一篇
无影云桌面