zookeeper的安装及使用详解应用

一、部署与常规配置

zookeeper 基于JAVA开发,下载后只要有对应JVM环境即可运行。其默认的端口号是2181运行前得保证其不冲突。

想要安装zookeeper,必须先在linux中安装好jdk。安装步骤见:
https://blog.csdn.net/qq_41843246/article/details/104811867

二、下载并解压zookeeper压缩包

  1. 先进入/usr/local/目录,也可以是其他的目录:

  2. [root@localhost /]# cd /usr/local

  3. zookeeper安装包可以在官网下载,也可以在后面这个地址下载

  4. http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.13/zookeeper-3.4.13.tar.gz
    如果链接打不开,就先打开 http://mirror.bit.edu.cn/apache/zookeeper 再选择版本,在此目录下载zookeeper安装包
    5、或者是在本地先下载好zookeeper安装包,然后通过rz命令上传至服务器
    6、 解压:

[root@localhost local]# tar -zxvf zookeeper-3.4.13.tar.gz

三、编辑配置文件

1.进入conf目录:
[root@localhost local]# cd zookeeper-3.4.13/conf
2. 将zoo_sample.cfg这个文件复制为zoo.cfg (必须是这个文件名)
[root@localhost conf]# cp zoo_sample.cfg zoo.cfg
3. 进入zoo.cfg文件进行编辑
[root@localhost conf]# vim zoo.cfg
4. 按 i 进入编辑模式,修改以下内容:

dataDir=/tmp/zookeeper/data
dataLogDir=/tmp/zookeeper/log

注意:如果想配置集群的话,请在clientPort下面添加服务器的ip。如

server.1=192.168.180.132:2888:3888
server.2=192.168.180.133:2888:3888
server.3=192.168.180.134:2888:3888

如果电脑内存比较小,zookeeper还可以设置成伪集群。也就是全部服务器采用同一个ip,但是使用不同的端口。
5. 在tmp目录创建目录。

[root@localhost conf]# mkdir /tmp/zookeeper
[root@localhost conf]# mkdir /tmp/zookeeper/data
[root@localhost conf]# mkdir /tmp/zookeeper/log

6.如果是配置集群,还需要在前面配置过的dataDir路径下新增myid文件

[root@localhost conf]# cd /tmp/zookeeper/data
[root@localhost data]# touch myid
[root@localhost data]# vim myid

在data目录下创建文件,文件名为“myid”, 编辑该“myid”文件,并在对应的IP的机器上输入对应的编号。
如在192.168.180.132上,“myid”文件内容就是1。在192.168.180.133上,内容就是2。

7、常规配置文件说明

#zookeeper时间配置中的基本单位 (毫秒)
tickTime=2000
#允许follower初始化连接到leader最大时长,它表示tickTime时间倍数 即:initLimit*tickTime
initLimit=10
#允许follower与leader数据同步最大时长,它表示tickTime时间倍数 
syncLimit=5
zookeper 数据存储目录
dataDir=/tmp/zookeeper
#对客户端提供的端口号
clientPort=2181
#单个客户端与zookeeper最大并发连接数
maxClientCnxns=60
#保存的数据快照数量,之外的将会被清除
autopurge.snapRetainCount=3
#自动触发清除任务时间间隔,小时为单位。默认为0,表示不自动清除。
autopurge.purgeInterval=1

四、zookpeer详解应用

1、znode 节点
zookeeper 中数据基本单元叫节点,节点之下可包含子节点,最后以树级方式程现。每个节点拥有唯一的路径path。客户端基于PATH上传节点数据,zookeeper 收到后会实时通知对该路径进行监听的客户端。

2、客户端命令:

基本命令列表

 close 
 #关闭当前会话
connect host:port 
#重新连接指定Zookeeper服务
create [-s] [-e] [-c] [-t ttl] path [data] [acl]
#创建节点
delete [-v version] path
#删除节点,(不能存在子节点)
deleteall path
 #删除路径及所有子节点
setquota -n|-b val path
#设置节点限额 -n 子节点数 -b 字节数
 listquota path
#查看节点限额
delquota [-n|-b] path
#删除节点限额
 get [-s] [-w] path
#查看节点数据 -s 包含节点状态 -w 添加监听 
getAcl [-s] path
ls [-s] [-w] [-R] path
#列出子节点 -s状态 -R 递归查看所有子节点 -w 添加监听
printwatches on|off
#是否打印监听事件
quit 
#退出客户端
 history 
#查看执行的历史记录
redo cmdno
#重复 执行命令,history 中命令编号确定
removewatches path [-c|-d|-a] [-l]
#删除指定监听
set [-s] [-v version] path data
#设置值
setAcl [-s] [-v version] [-R] path acl
#为节点设置ACL权限
stat [-w] path
#查看节点状态 -w 添加监听
sync path
#强制同步节点

node数据的增删改查
#列出子节点 
ls /
#创建节点
create /luban "luban is good man"
#查看节点
get /luban
#创建子节点 
create /luban/sex "man"
#删除节点
delete /luban/sex
#删除所有节点 包括子节点
deleteall /luban

3、Zookeeper节点介绍
1.节点类型
2.节点的监听(watch)
3.节点属性说明(stat)
4.权限设置(acl)
zookeeper 中节点叫znode存储结构上跟文件系统类似,以树级结构进行存储。不同之外在于znode没有目录的概念,不能执行类似cd之类的命令。znode结构包含如下:

  • path:唯一路径
  • childNode:子节点
  • stat:状态属性
  • type:节点类型

5.节点类型
zookeeper的安装及使用详解应用_第1张图片

  • PERSISTENT(持久节点)
    持久化保存的节点,也是默认创建的
    #默认创建的就是持久节点
    create /test

  • PERSISTENT_SEQUENTIAL(持久序号节点)
    创建时zookeeper 会在路径上加上序号作为后缀,。非常适合用于分布式锁、分布式选举等场景。创建时添加 -s 参数即可。
    #创建序号节点
    create -s /test
    #返回创建的实际路径
    Created /test0000000001
    create -s /test
    #返回创建的实际路径2
    Created /test0000000002

  • EPHEMERAL(临时节点)
    临时节点会在客户端会话断开后自动删除。适用于心跳,服务发现等场景。创建时添加参数-e 即可。
    #创建临时节点, 断开会话 在连接将会自动删除
    create -e /temp

  • EPHEMERAL_SEQUENTIAL(临时序号节点)
    与持久序号节点类似,不同之处在于EPHEMERAL_SEQUENTIAL是临时的会在会话断开后删除。创建时添加 -e -s
    create -e -s /temp/seq

6.节点属性

查看节点属性

stat /luban
其属性说明如下表:
#创建节点的事物ID
cZxid = 0x385
#创建时间
ctime = Tue Sep 24 17:26:28 CST 2019
#修改节点的事物ID
mZxid = 0x385
#最后修改时间
mtime = Tue Sep 24 17:26:28 CST 2019
#子节点变更的事物ID
pZxid = 0x385
#这表示对此znode的子节点进行的更改次数(不包括子节点)
cversion = 0
#数据版本,变更次数
dataVersion = 0
#权限版本,变更次数
aclVersion = 0
#临时节点所属会话ID
ephemeralOwner = 0x0
#数据长度
dataLength = 17
#子节点数(不包括子子节点)
numChildren = 0

7.节点的监听:

客户添加 -w 参数可实时监听节点与子节点的变化,并且实时收到通知。非常适用保障分布式情况下的数据一至性。其使用方式如下:
zookeeper的安装及使用详解应用_第2张图片
8.acl权限设置

ACL全称为Access Control List(访问控制列表),用于控制资源的访问权限。ZooKeeper使用ACL来控制对其znode的防问。基于scheme : id : permission的方式进行权限控制。scheme表示授权模式、id模式对应值、permission即具体的增删改权限位。

scheme:认证模型
zookeeper的安装及使用详解应用_第3张图片
permission权限位
zookeeper的安装及使用详解应用_第4张图片
acl 相关命令:
zookeeper的安装及使用详解应用_第5张图片
world权限示例
语法: setAcl world:anyone:<权限位>

1.查看默认节点权限:
#创建一个节点
create -e /testAcl
#查看节点权限
getAcl /testAcl
#返回的默认权限表示 ,所有人拥有所有权限。
'world,'anyone: cdrwa

2.修改默认权限为 读写
#设置为rw权限 
setAcl /testAcl world:anyone:rw
# 可以正常读
get /testAcl
# 无法正常创建子节点
create -e /testAcl/t "hi"
# 返回没有权限的异常
Authentication is not valid : /testAcl/t

IP权限示例:
语法: setAcl ip::<权限位>

auth模式示例:
语法:
1.setAcl auth:<用户名>:<密码>:<权限位>
2.addauth digest <用户名>:<密码>
digest 权限示例:
语法:
1.setAcl digest :<用户名>:<密钥>:<权限位>
2.addauth digest <用户名>:<密码>

五.集群部署

1、配置语法:
server.<节点ID>=:<数据同步端口>:<选举端口>

  • 节点ID:服务id手动指定1至125之间的数字,并写到对应服务节点的 {dataDir}/myid 文件中。
  • IP地址:节点的远程IP地址,可以相同。但生产环境就不能这么做了,因为在同一台机器就无法达到容错的目的。所以这种称作为伪集群。
  • 数据同步端口:主从同时数据复制端口,(做伪集群时端口号不能重复)。
  • 远举端口:主从节点选举端口,(做伪集群时端口号不能重复)。
    配置文件示例:
tickTime=2000
dataDir=/var/lib/zookeeper/
clientPort=2181
initLimit=5
syncLimit=2
#以下为集群配置,必须配置在所有节点的zoo.cfg文件中
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888

1、集群配置流程:

1.分别创建3个data目录用于存储各节点数据
mkdir data
mkdir data/1
mkdir data/3
mkdir data/3
2.编写myid文件
echo 1 > data/1/myid
echo 3 > data/3/myid
echo 2 > data/2/myid
3、编写配置文件
conf/zoo1.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=data/1
clientPort=2181
#集群配置
server.1=127.0.0.1:2887:3887
server.2=127.0.0.1:2888:3888
server.3=127.0.0.1:2889:3889

conf/zoo2.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=data/2
clientPort=2182
#集群配置
server.1=127.0.0.1:2887:3887
server.2=127.0.0.1:2888:3888
server.3=127.0.0.1:2889:3889

conf/zoo3.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=data/3
clientPort=2183
#集群配置
server.1=127.0.0.1:2887:3887
server.2=127.0.0.1:2888:3888
server.3=127.0.0.1:2889:3889

4.分别启动
./bin/zkServer.sh start conf/zoo1.cfg
./bin/zkServer.sh start conf/zoo2.cfg
./bin/zkServer.sh start conf/zoo3.cfg

5.分别查看状态
./bin/zkServer.sh status conf/zoo1.cfg
Mode: follower
./bin/zkServer.sh status conf/zoo2.cfg
Mode: leader
./bin/zkServer.sh status conf/zoo3.cfg
Mode: follower

2.集群角色说明
zookeeper 集群中总共有三种角色,分别是leader(主节点)follower(子节点) observer(次级子节点)

zookeeper的安装及使用详解应用_第6张图片
observer配置:
只要在集群配置中加上observer后缀即可,示例如下:
server.3=127.0.0.1:2889:3889:observer

3.选举机制
zookeeper的安装及使用详解应用_第7张图片
投票机制说明:
第一轮投票全部投给自己
第二轮投票给myid比自己大的相邻节点
如果得票超过半数,选举结束。

选举触发:
当集群中的服务器出现已下两种情况时会进行Leader的选举
1.服务节点初始化启动
2.半数以上的节点无法和Leader建立连接
当节点初始起动时会在集群中寻找Leader节点,如果找到则与Leader建立连接,其自身状态变化follower或observer。如果没有找到Leader,当前节点状态将变化LOOKING,进入选举流程。
在集群运行其间如果有follower或observer节点宕机只要不超过半数并不会影响整个集群服务的正常运行。但如果leader宕机,将暂停对外服务,所有follower将进入LOOKING 状态,进入选举流程。

4.数据同步机制

zookeeper 的数据同步是为了保证各节点中数据的一至性,同步时涉及两个流程,一个是正常的客户端数据提交,另一个是集群某个节点宕机在恢复后的数据同步。

zookeeper的安装及使用详解应用_第8张图片
但实际情况要复杂的多,比如client 它并不知道哪个节点是leader 有可能写的请求会发给follower ,由follower在转发给leader进行同步处理

zookeeper的安装及使用详解应用_第9张图片

客户端写入流程说明:

1.client向zk中的server发送写请求,如果该server不是leader,则会将该写请求转发给leader server,leader将请求事务以proposal形式分发给follower;
2.当follower收到收到leader的proposal时,根据接收的先后顺序处理proposal;
3.当Leader收到follower针对某个proposal过半的ack后,则发起事务提交,重新发起一个commit的proposal
4.Follower收到commit的proposal后,记录事务提交,并把数据更新到内存数据库;
5.当写成功后,反馈给client。

服务节点初始化同步:

在集群运行过程当中如果有一个follower节点宕机,由于宕机节点没过半,集群仍然能正常服务。当leader 收到新的客户端请求,此时无法同步给宕机的节点。造成数据不一至。为了解决这个问题,当节点启动时,第一件事情就是找当前的Leader,比对数据是否一至。不一至则开始同步,同步完成之后在进行对外提供服务。
如何比对Leader的数据版本呢,这里通过ZXID事物ID来确认。比Leader就需要同步。

ZXID说明:

ZXID是一个长度64位的数字,其中低32位是按照数字递增,任何数据的变更都会导致,低32位的数字简单加1。高32位是leader周期编号,每当选举出一个新的leader时,新的leader就从本地事物日志中取出ZXID,然后解析出高32位的周期编号,进行加1,再将低32位的全部设置为0。这样就保证了每次新选举的leader后,保证了ZXID的唯一性而且是保证递增的。

五、分布式注册中心

在单体式服务中,通常是由多个客户端去调用一个服务,只要在客户端中配置唯一服务节点地址即可,当升级到分布式后,服务节点变多,像阿里一线大厂服务节点更是上万之多,这么多节点不可能手动配置在客户端,这里就需要一个中间服务,专门用于帮助客户端发现服务节点,即许多技术书籍经常提到的服务发现

zookeeper的安装及使用详解应用_第10张图片
一个完整的注册中心涵盖以下功能特性:

  • 服务注册:提供者上线时将自提供的服务提交给注册中心。
  • 服务注销:通知注册心提供者下线。
  • 服务订阅:动态实时接收服务变更消息。
  • 可靠:注册服务本身是集群的,数据冗余存储。避免单点故障,及数据丢失。
  • 容错:当服务提供者出现宕机,断电等极情况时,注册中心能够动态感知并通知客户端服务提供者的状态。

Dubbo 对zookeeper的使用

zookeeper的安装及使用详解应用_第11张图片
Dubbo Zookeeper注册中心存储结构:

zookeeper的安装及使用详解应用_第12张图片
节点说明:
zookeeper的安装及使用详解应用_第13张图片
流程说明:

1.服务提供者启动时: 向 /dubbo/com.foo.BarService/providers 目录下写入自己的 URL 地址
2.服务消费者启动时: 订阅 /dubbo/com.foo.BarService/providers 目录下的提供者 URL 地址。并向 /dubbo/com.foo.BarService/consumers 目录下写入自己的 URL 地址
3.监控中心启动时: 订阅 /dubbo/com.foo.BarService 目录下的所有提供者和消费者 URL 地址。

六、分布式JOB

分布式JOB需求:
1.多个服务节点只允许其中一个主节点运行JOB任务。
2.当主节点挂掉后能自动切换主节点,继续执行JOB任务。

架构设计:
zookeeper的安装及使用详解应用_第14张图片

选举流程:
服务启动:
1.在tuling-maste下创建server子节点,值为slave
2.获取所有tuling-master 下所有子节点
3.判断是否存在master 节点
4.如果没有设置自己为master节点
子节点删除事件触发:
1.获取所有tuling-master 下所有子节点
2.判断是否存在master 节点
3.如果没有设置最小值序号为master 节点

七、分布式锁

锁的的基本概念:
开发中锁的概念并不陌生,通过锁可以实现在多个线程或多个进程间在争抢资源时,能够合理的分配置资源的所有权。在单体应用中我们可以通过 synchronized 或ReentrantLock 来实现锁。但在分布式系统中,仅仅是加synchronized 是不够的,需要借助第三组件来实现。比如一些简单的做法是使用 关系型数据行级锁来实现不同进程之间的互斥,但大型分布式系统的性能瓶颈往往集中在数据库操作上。为了提高性能得采用如Redis、Zookeeper之内的组件实现分布式锁。

共享锁也称作只读锁,当一方获得共享锁之后,其它方也可以获得共享锁。但其只允许读取。在共享锁全部释放之前,其它方不能获得写锁。
排它锁也称作读写锁,获得排它锁后,可以进行数据的读写。在其释放之前,其它方不能获得任何锁。

锁的获取
zookeeper的安装及使用详解应用_第15张图片
1、基于资源ID创建临时序号读锁节点
/lock/888.R0000000002 Read
2、获取 /lock 下所有子节点,判断其最小的节点是否为读锁,如果是则获锁成功
3、最小节点不是读锁,则阻塞等待。添加lock/ 子节点变更监听。
4、当节点变更监听触发,执行第2步

数据结构:

zookeeper的安装及使用详解应用_第16张图片

获得写锁:
1、基于资源ID创建临时序号写锁节点
/lock/888.R0000000002 Write
2、获取 /lock 下所有子节点,判断其最小的节点是否为自己,如果是则获锁成功
3、最小节点不是自己,则阻塞等待。添加lock/ 子节点变更监听。
4、当节点变更监听触发,执行第2步
释放锁:
读取完毕后,手动删除临时节点,如果获锁期间宕机,则会在会话失效后自动删除。

关于羊群效应:
在等待锁获得期间,所有等待节点都在监听 Lock节点,一但lock 节点变更所有等待节点都会被触发,然后在同时反查Lock 子节点。如果等待对例过大会使用Zookeeper承受非常大的流量压力。

zookeeper的安装及使用详解应用_第17张图片

为了改善这种情况,可以采用监听链表的方式,每个等待对列只监听前一个节点,如果前一个节点释放锁的时候,才会被触发通知。这样就形成了一个监听链表

zookeeper的安装及使用详解应用_第18张图片

你可能感兴趣的:(分布式,集群,zookeeper,分布式,java)