资料总结 资料总结
首页
go
java
云原生
  • mysql
  • redis
  • MongoDB
  • 设计模式详解
  • 数据结构与算法
  • 前端
  • 项目
  • 理论基础
  • 运营
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

linghui Wu

一只努力学飞的鱼
首页
go
java
云原生
  • mysql
  • redis
  • MongoDB
  • 设计模式详解
  • 数据结构与算法
  • 前端
  • 项目
  • 理论基础
  • 运营
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • java-se

  • jvm

  • mybatis

  • Netty

  • 爬虫 webmagic

  • spring

  • spring-cloud

  • 中间件

    • RabbitMQ

    • Kafka

    • RocketMQ

    • Zookeeper

      • Zookeeper快速使用
        • 文件系统数据结构
          • 持久化目录节点 PERSISTENT
          • 持久化顺序编号目录节点 PERSISTENT_SEQUENTIAL
          • 临时目录节点EPHEMERAL­
          • 临时顺序编号目录节点EPHEMERAL_SEQUENTIAL­
          • Container
          • TTL 节点
        • 监听通知机制
          • 事件类型
          • 命令行
        • 安装
        • 命令行操作
          • 创建zookeeper 节点命令
          • 查看节点
          • 修改节点数据
          • 查看节点状态信息
          • 查看子节点信息
          • 事件监听机制
        • ACL 权限控制
          • 内存数据和持久化
        • 事务日志
        • 数据快照
          • Java 客户端
          • Curator 工具包
        • API
        • protection模式
        • Caches
          • 集群模式
        • 介绍
        • 安装
        • 集群动态配置
          • 应用场景
        • 分布式配置中心
        • 分布式锁
          • 非公平锁
          • 公平锁
          • 共享锁
        • 分布式注册中心
        • 集群选举
        • 发布/订阅
        • 分布式队列
        • 分布式屏障
        • 计数器
        • 缓存
        • 节点/手表
          • 参考资料
      • Zookeeper原理和源码
    • ElasticStatic

  • flowable

  • idea工具

  • maven

  • ms

  • java部署

  • 原生安卓

  • java
  • 中间件
  • Zookeeper
wulinghui
2022-04-02
目录

Zookeeper快速使用

# 简介

它是一个分布式协调框架,主要是用来解决分布式应用中经常遇到的一些数据管理问题。如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。也可以看做是一个用于存储少量数据的基于内存 的数据库

# 核心概念

# 文件系统数据结构

# 持久化目录节点 PERSISTENT

客户端与zookeeper断开连接后,该节点依旧存在,只要不手动删除该节点,他将永远存在

# 持久化顺序编号目录节点 PERSISTENT_SEQUENTIAL

客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号

# 临时目录节点EPHEMERAL­

客户端与zookeeper断开连接后,或者session超时,该节点被删除。

临时节点不能创建子节点。

# 临时顺序编号目录节点EPHEMERAL_SEQUENTIAL­

客户端与zookeeper断开连接后,或者session超时,该节点被删除,只是Zookeeper给该节点名称进行顺序编号

# Container

如果Container节点下面没有子节点,则Container节点 在未来会被Zookeeper自动清除,定时任务默认60s 检查一次

# TTL 节点

过了TTL指定的时间,被服务器删除。默认禁用,只能通过系统配置 zookeeper.extendedTypesEnabled=true 开启,有bug不稳定

# 监听通知机制

客户端注册监听以下三种节点:

  1. 如果注册的是对某个节点的监听,则当这个节点被删除,或者被修改时,对应的客户端将被通知
  2. 如果注册的是对某个目录的监听,则当这个目录有子节点被创建,或者有子节点被删除,对应的客户端将被通知
  3. 如果注册的是对某个目录的递归子节点进行监听,则当这个目录下面的任意子节点有目录结构 的变化(有子节点被创建,或被删除)或者根节点有数据变化时,对应的客户端将被通知。

注意 : 所有的通知都是一次性的

# 事件类型

  • None: 连接建立事件
  • NodeCreated: 节点创建
  • NodeDeleted: 节点删除
  • NodeDataChanged:节点数据变化
  • NodeChildrenChanged:子节点列表变化
  • DataWatchRemoved:节点监听被移除
  • ChildWatchRemoved:子节点监听被移除

# 命令行

# 安装

  • 配置JAVA环境
  • 下载解压 zookeeper
  • 重命名配置文件 zoo_sample.cfg
  • 启动zookeeper

# 命令行操作

# 创建zookeeper 节点命令

create [‐s] [‐e] [‐c] [‐t ttl] path [data] [acl]

-s: 顺序节点 -e: 临时节点 -c: 容器节点 -t: 可以给节点添加过期时间,默认禁用,需要通过系统参数启用 。没有则默认创建持久化节点

注意: 没有相对路径这么一说,所以,所 有的节点一定是以 / 开头

# 查看节点

get [‐s] [‐w] path

-s 详细信息 -w 监听

# 修改节点数据

set [‐s] [‐v version] path data

-v 版本 : 乐观锁控制并发,-1代表最新版本。

# 查看节点状态信息

stat [‐w] path

  • cZxid:创建znode的事务ID(Zxid的值)。
  • mZxid:最后修改znode的事务ID。
  • pZxid:最后添加或删除子节点的事务ID(子节点列表发生变化才会发生改变)。
  • ctime:znode创建时间。
  • mtime:znode最近修改时间。
  • dataVersion:znode的当前数据版本。
  • cversion:znode的子节点结果集版本(一个节点的子节点增加、删除都会影响这个 版本)。
  • aclVersion:表示对此znode的acl版本。
  • ephemeralOwner:znode是临时znode时,表示znode所有者的 session ID。 如果 znode不是临时znode,则该字段设置为零。
  • dataLength:znode数据字段的长度。
  • numChildren:znode的子znode的数量。

# 查看子节点信息

ls [‐s] [‐w] [‐R] path

-R 递归查看子节点列表

# 事件监听机制

get ‐w /path // 注册监听的同时获取数据

stat ‐w /path // 对节点进行监听,且获取元数据信息

ls ‐R ‐w /path // 针对递归子目录的监听

# ACL 权限控制

权限模式(Scheme)、授权对象(ID)、权限信息 (Permission)

getAcl 获取某个节点的acl权限信息

setAcl 设置某个节点的acl权限信息

addauth 输入认证授权信息

# 内存数据和持久化

DataTree、DataNode

# 事务日志

针对每一次客户端的事务操作,也就是说对数据/权限的操作。

为了提升磁盘IO的效率, Zookeeper在创建事务日志文件的时候就进行文件空间的预分配- 即在创建文件的时候,就向操 作系统申请一块大一点的磁盘块。

事务日志文件名为: log.<当时最大事务ID>

内容有 :

同时做了压缩(可以用org.apache.zookeeper.server.LogFormatter 格式化日志)

客户端会话ID,CXID,ZXID,操作类型,节点路径,节点数据,节点版本。

# 数据快照

数据快照用于记录Zookeeper服务器上某一时刻的全量数据,并将其写入到指定的磁盘文件中。

快照事务日志文件名为: snapshot.<当时最大事务ID>

快照数据是反应当时内存数据的状态。事务日志是 更全面的数据,所以恢复数据的时候,可以先恢复快照数据,再通过增量恢复事务日志中的数据 即可。 好多中间件都是这样实现的,如redis混合化持久性。

# Java 客户端

zookeeper 官方的客户端没有和服务端代码分离,他们为同一个jar 文件。所以客户端的版本请保持与服务端版本一致。

new ZooKeeper()的过程是异步的。需要用到CountDownLatch+回调做同步。

监听机制,可以再代码中用this传入做无限监听。

# Curator 工具包

Curator 把我们平时常用的很多 ZooKeeper 服务开发功能做了封装,例如 客户端Leader 选举、 分布式计数器、分布式锁、会话重新连接、Watch 反复注册、多种异常处理、Cache 事件监听、分布式Barrier(栅栏)

  • pom包: curator-framework简单的封装,curator-recipes高级功能特性

# API

  • CuratorFramework#start() 方法代表启动。
  • CuratorFramework#getData() 获取数据
  • CuratorFramework#setData() 更新数据
  • CuratorFramework#delete() 删除节点
  • 异步接口 : 默认使用EventThread线程池,可以自定义线程池。
  • 监听器 : CuratorListener类

# protection模式

防止僵尸(幽灵)节点(由于异常原因导致出现下面的问题。)

Curator 的幂等性保证(再写成功以后返回时出错,同时再sessoin超时前恢复,那么会触发重试...就出现了重复数据), withProtection() 生成uuid,重试时再去查询这个客户端的uuid是否存在,来保证幂等性。

# Caches

Curator 引入了 Cache 来实现对 Zookeeper 服务端事件监听,来实现反复注册的功能。

分为两类注册类型:节点监听和子节点监听。

Cache 事件监听可以理解为一 个本地缓存视图与远程 Zookeeper 视图的对比过程

  • node cache 对当前节点数据变化的处理
  • path cache 会对子节点进行监听,但是不会对二级子节点进行监听
  • tree cache 对当前节点的子节点,及递归子节点数据变化的处理

# 集群模式

# 介绍

Leader: 处理所有的事务请求(写请求),可以处理读请求,集群中只能有一个Leader

Follower:只能处理读请求,同时作为 Leader的候选节点,即如果Leader宕机,Follower节点要参与到新的Leader选举中,有可能成为新的Leader节点。

Observer:只能处理读请求。不能参与选举

Follower/Observer : 接到写请求则转发到 Leader节点上。

# 安装

  • 前3步同单机安装。

  • 修改配置文件zoo.cfg

dataDir=/usr/local/data/zookeeper-1
clientPort=2181
# server.A=B:C:D:E  
# 每个节点2个端口,其中一个为选举端口,一个为提供服务端口。
# A 是一个数字,表示这个是第几号服务器;
# B 是这个服务器的 ip 地址;
# C 表示的是这个服务器与集群中的 Leader 服务器交换信息的端# 口;
# D 表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。如果是伪集群的配置方式,由于 B 都是一样,所以不同的 Zookeeper 实例通信端口号不能一样,所以要给它们分配不同的端口号。
# 如果需要通过添加不参与集群选举以及事务请求的过半机制的 Observer节点,可以在E的位置,添加observer标识。
server.1=127.0.0.1:2001:3001:participant// participant 可以不用写,默认就是participant
server.2=127.0.0.1:2002:3002:participant
server.3=127.0.0.1:2003:3003:participant
server.4=127.0.0.1:2004:3004:observer 
1
2
3
4
5
6
7
8
9
10
11
12
13
  • 标识myid文件的Server ID

echo "1">>myid

  • 启动实例
  • 检测集群状态 zkServer.sh status conf/zoo1.cfg

# 集群动态配置

3.5.0 的新特性 :

  • 需要开启超级管理员身份验证模式 ACLs
  • 配置动态文件 : dynamicConfigFile -> 指定动态配置文件的路径 ,reconfigEnabled : 设置为true 开启动态配置
  • 创建文件 zoo_replicated.cfg.dynamic
  • 指令扩缩容
reconfig -remove 3  // 移除serverId为 3 的机器
reconfig -add server.3=**** // 把对应的机器加进来
1
2
  • 客户端可以通过监听 /zookeeper/confg 节点,来感知集群的变化。从而实现集群的动态变更
  • Curator 也自带了动态配置的监听,不需要额外的配置和代码实现监听更新;

# 应用场景

所有的应用场景可以看curator的官网 (opens new window)

# 分布式配置中心

Spring Cloud Zookeeper Config

原理 : 获得持久化节点数据、并且监听数据变更。

# 分布式锁

# 非公平锁

通过 create -e /lock , get -w /lock , delete /lock 简单实现。

羊群效应 :所有的连接都在对同一个节点进行监听,当服务器检测到删除事件时,要通知所有的连接,所有的连接同时收到事件,再次并发竞争。

# 公平锁

源码:

  • 防止幽灵节点 : protection模式
  • 利用父容器节点的特性,减少父节点的数量。
  • 避免羊群效应: 临时顺序节点,且只针对上个节点做监听。
  • 再客户端获得所有节点且排序,防止 : 某个节点挂了导致顺序中断需要重建监听;网络IO获得的是无序的。
  • 可重入锁,再jvm本地有个atomicInt 来做的,防止了网络IO。
  • 内部是使用的syncs / wait / notiyall 实现的等待唤醒机制。
  • 一进来就先创建临时节点,之后再排序判断是不是最小的节点,再做监听等待唤醒机制。

思考:

  • 获得最小节点??? 获得所有节点,获得10位数字,并且排序(从网络中获得的列表返回值也是无序的,必须要的)就行了。
  • 如果中间一个节点挂了,哪有怎么处理??? 他后面那个节点监听到了之后,再去判断能不能获得锁,不能就继续排队组成新的监听链表。
  • 防止幽灵节点 : protection模式
  • 为何用父容器节点 ??? 减少父节点的数量。
  • 临时顺序节点的目的 ??? 直接创建并保证他的排序。

非公平锁的羊群效应问题。 可以改进成AQS的第一次非公平,之后就排队的实现,也用公平锁的实现。

# 共享锁

读写锁的实现: 名称前缀为读写标识,用来判断获得锁成功与否。

细节: 读的监听上个写的,写的监听上个读或写的。 读读锁没有关联。

# 分布式注册中心

spring cloud zookpeer

Rabbion动态更新ip注册表。

zookpeer 没有实现分片。

实现原理 : 临时节点 + 监听机制。

# 集群选举 (opens new window)

客户端领导选举,功能源码实现:

他会执行完回调代码后,再进行选举。

实现同一个周期时间只有一个人做事,同时每个人都有可能做事。

也是基于分布式的公平锁去实现的。

# 发布/订阅

# 分布式队列

# 分布式屏障

# 计数器

# 缓存

# 节点/手表

# 参考资料

集群安装配置 (opens new window)

那2个端口可以随便配置。

Apache ZooKeeper - 使用ZK实现分布式锁(非公平锁/公平锁/共享锁 ) (opens new window)

非公平锁方案、羊群效应、公平锁方案、共享锁方案的原理。建议看看。

Zookeeper + Curator实现分布式锁 (opens new window)

curator笔记-分布式锁的实现与原理 (opens new window)

详细的源码解析。

用Zookeeper作为Spring cloud的配置中心 (opens new window)

客户端使用 spring-cloud-starter-zookeeper-config

让客户端自动更新zookeeper变更的配置 : 使用spring-boot-starter-actuator 模块,并开启watcher

编辑 (opens new window)
上次更新: 2023/01/24, 15:21:15
生产问题总结及性能优化
Zookeeper原理和源码

← 生产问题总结及性能优化 Zookeeper原理和源码→

最近更新
01
架构升级踩坑之路
02-27
02
总结
02-27
03
语法学习
02-27
更多文章>
| Copyright © 2021-2025 Wu lingui |
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式