Zookeeper系列(一)——Zookeeper基础之数据模型

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
云原生网关 MSE Higress,422元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: Zookeeper系列(一)——Zookeeper基础之数据模型

概述


Zookeeper是一个分布式协调服务,提供了分布式数据一致性的解决方案。目前很多开源框架技术背后都有ZooKeeper的身影,比如kafka, hbase等。

Zookeeper基础知识主要分为三大块,数据结构, Watch监控,ACL权限控制。 基于这些特点可以实现数据的发布/订阅,软负载均衡,命名服务,统一配置管理,分布式锁,集群管理等等。

系列文章见Zookeeper系列笔记,带你入门到精通


数据模型


什么是数据模型呢?就是指Zookeeper创建和处理数据存储的逻辑结构。

Zookeeper创建的数据模型是树状结构,类似Unix的文件系统,类似下图。

1671111265869.jpg

  • 有一个固定的根节点(/)
  • 根节点下可以创建子节点,子节点下可以继续创建下一级节点
  • 每一层级用斜杆(/)分隔
  • 查找某个节点只能用绝对路径方式查询(/app1/p_1),不能用相对路径


Znode节点分类


上面数据中的每一个节点叫Znode, 默认情况下最大存储1M的数据,Znode根据特性分为下面三类:


持久节点


特点: 一旦将节点创建为持久系欸但,该数据节点一直会存储在Zookeeper服务器上,即使创建该节点的客户端和服务端会话关闭了,该节点也不会删除。如果想要删除持久节点,就要显示调用delete函数删除。

命令:create /persistent_node


临时节点


特点: 如果创建的是临时节点是,当创建该临时节点的客户端会话因超时或发生异常而关闭时,该节点也相应在 ZooKeeper 服务器上被删除,也可以调用delete主动删除临时节点。

命令:create -e /ephemeral_node mydata


有序节点


特点: 我们在创建有序节点时,ZooKeeper 服务器会自动使用一个单调递增的数字作为后缀,追加到我们创建节点的后边。这个序号对于父 znode 是唯一的。计数器的格式为 %010d - 即 10 位数字和 0(零)填充(计数器以这种方式格式化以简化排序),即“0000000001"。

例如一个客户端创建了一个路径为 works/task- 的有序节点,那么 ZooKeeper 将会生成一个序号并追加到该节点的路径后,最后该节点的路径为 works/task-0000000001。

有序节点属性可以和持久或者临时节点共存,意味着有持久有序节点,临时有序节点。

命令: 创建持久有序节点create -s /persistent_sequential_node mydata,

创建临时有序节点create -s -e /ephemeral_sequential_node mydata


容器节点


3.6.0版本新加

特点: 服务端会定期扫描这些节点,当该节点下面没有子节点时(或其他条件时)服务端会自动删除节点

命令:create -c /container_node mydata


TTL节点


3.6.0版本新加

特点: 需要额外配置才能启用,基本和容器相同,当超过 TTL 时间节点下面都没有再创建子节点时会被删除,但是当创建子节点会重置该超时时间。

命令:create -t 3000 /ttl_node mydata


Znode节点属性


每个Znode节点都有属于自己的状态属性,通过执行stat /zk_test查看节点的状态信息。

1671111307317.jpg

属性名 说明
czxid 表示该数据节点被创建时的事务ID
mzxid 表示该节点最后一次被更新时的事务ID
pzxid 表示该节点的子节点列表最后一次被修改时的事务ID
ctime 表示该节点的创建时间
mtime 表示该节点最后一次被更新的时间
version 数据节点的版本号
cversion 子节点的版本号
aversion 节点的ACL版本号
ephemeralOwner 创建该临时节点的会话SessionId, 如果该节点时持久节点,那么这个属性时0
dataLength 数据内容的长度
numChildren 当前节点子节点的个数


安装使用


单机版安装


  1. 官网下载最新的安装包,zookeeper.apache.org/releases.ht…
  2. 创建配置conf/zoo.cfg
tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
  • tickTime:ZooKeeper 使用的基本时间单位,以毫秒为单位。它用于做心跳,最小会话超时将是 tickTime 的两倍。
  • dataDir:存储内存数据库快照的位置。
  • clientPort:监听客户端连接的端口。
  1. 启动
bin/zkServer.sh start
  1. 查看日志 tail logs/zookeeper-root-server-template.out是否启动成功

1671111334157.jpg


连接使用


  1. 连接 bin/zkCli.sh -server 127.0.0.1:2181

1671111342071.jpg

  1. 在 shell 中,键入help以获取可以从客户端执行的命令列表

1671111347735.jpg

  1. 创建持久化节点zk_test, 值为alvin

1671111355116.jpg

  1. 查看目录

1671111361403.jpg

  1. 获取节点数据信息

1671111367554.jpg

  1. 查看节点属性信息

1671111373127.jpg

  1. 删除节点

1671111378043.jpg

全量的命令参考:

zookeeper.apache.org/doc/current…


实战案例


我们现在利用上面学到的数据模型和节点的特性,用一个案例来加深我们的理解。


场景


一个购物网站,只剩下一部IPhone13, 周杰伦搜索到了准备下单购买,这时候王力宏也查询到了并且提交购买,如果不做任何处理,那么一件商品会被卖两次,出现超卖的情况。那么利用Zookeeper学的知识该如何解决呢?


方案


我们可以通过加锁的方式,比如周杰伦进行操作的时候,对这个商品锁定。实现加锁的方式有两种,悲观锁和乐观锁。


悲观锁


悲观锁认为进程对临界区的竞争总是会出现,为了保证进程在操作数据时,该条数据不被其他进程修改。数据会一直处于被锁定的状态。

我们假设一个具有 n 个进程的应用,同时访问临界区资源,我们通过进程创建 ZooKeeper 节点 /locks 的方式获取锁。

线程 a 通过成功创建 ZooKeeper 节点“/locks”的方式获取锁后继续执行,如下图所示:

1671111391168.jpg

这时进程 b 也要访问临界区资源,于是进程 b 也尝试创建“/locks”节点来获取锁,因为之前进程 a 已经创建该节点,所以进程 b 创建节点失败无法获得锁。

1671111398638.jpg

这样就实现了一个简单的悲观锁,不过这也有一个隐含的问题,就是当进程 a 因为异常中断导致 /locks 节点始终存在,其他线程因为无法再次创建节点而无法获取锁,这就产生了一个死锁问题。针对这种情况我们可以通过将节点设置为临时节点的方式避免。并通过在服务器端添加监听事件来通知其他进程重新获取锁。


乐观锁


乐观锁认为,进程对临界区资源的竞争不会总是出现,所以相对悲观锁而言。加锁方式没有那么激烈,不会全程的锁定资源,而是在数据进行提交更新的时候,对数据的冲突与否进行检测,如果发现冲突了,则拒绝操作。

在 ZooKeeper 中的 version 属性就是用来实现乐观锁机制中的“校验”的,ZooKeeper 每个节点都有数据版本的概念,在调用更新操作的时候,假如有一个客户端试图进行更新操作,它会携带上次获取到的 version 值进行更新。而如果在这段时间内,ZooKeeper 服务器上该节点的数值恰好已经被其他客户端更新了,那么其数据版本一定也会发生变化,因此肯定与客户端携带的 version 无法匹配,便无法成功更新,因此可以有效地避免一些分布式更新的并发问题。

悲观锁和乐观锁具体的代码实现在后面的文章中一一和大家展示。

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
目录
相关文章
|
1月前
|
分布式计算 Java Hadoop
Hadoop-30 ZooKeeper集群 JavaAPI 客户端 POM Java操作ZK 监听节点 监听数据变化 创建节点 删除节点
Hadoop-30 ZooKeeper集群 JavaAPI 客户端 POM Java操作ZK 监听节点 监听数据变化 创建节点 删除节点
62 1
|
4月前
|
消息中间件 存储 Kafka
kafka 在 zookeeper 中保存的数据内容
kafka 在 zookeeper 中保存的数据内容
50 3
|
6月前
|
Java Unix 程序员
ZooKeeper数据模型你懂吗?
ZooKeeper数据节点你懂吗?那数据节点有什么类型?数据节点的版本呢?听说ZooKeeper还有事务ID,你知不知道啊?还有Watcher机制呢?ZooKeeper作为一个典型的分布式数据一致性的解决方案,ZooKeeper的技能点是Java程序员进阶所必须掌握。如果上面的问题你还不懂的话,不妨看看下文对这些概念的解析~
ZooKeeper数据模型你懂吗?
|
Java
分布式系列教程(24) -Zookeeper数据查看工具ZooInspector
分布式系列教程(24) -Zookeeper数据查看工具ZooInspector
110 0
Zookeeper学习---2、客户端API操作、客户端向服务端写数据流程
Zookeeper学习---2、客户端API操作、客户端向服务端写数据流程
Zookeeper学习---2、客户端API操作、客户端向服务端写数据流程
|
6月前
|
存储 Java API
ZooKeeper【客户端的API操作、写数据流程】
ZooKeeper【客户端的API操作、写数据流程】
|
算法 Java 大数据
ZooKeeper 如何保证数据的一致性?【重要】
ZooKeeper 如何保证数据的一致性?【重要】
163 0
|
算法
Zookeeper 的读写机制、保证机制、Watcher(数据变更的通知)
Zookeeper 的读写机制、保证机制、Watcher(数据变更的通知)
153 0
|
存储
Zookeeper 数据模型和节点特性
Zookeeper 数据模型和节点特性
71 0
|
存储 监控 Apache
Apache ZooKeeper - ZK的数据和文件
Apache ZooKeeper - ZK的数据和文件
157 0