zk深入

一.适用场景
小数据量存储元数据,能够保证相对的数据的高可用及数据的一致性,如果zk leader挂了,可由其它结点充当leader,实现服务的高可用。
典型应用,配置数据存储,分布式锁,服务注册中心,作为主/从高可用组件。

二.基本结构

2.1.结点
结点分为:
持久结点,临时结点,持久有序结点,临时有序结点。
持久结点一定创建就不会自动消失,适合用于存储元数据类应用。
临时结点,当创建它的session超时时,会自动清除,并且如果存在watch,则还会触发这个watch。典型的应用是服务注册。
有序结点,只是在某个父结点下,创建子结点,每次都会递增唯一序号给当前子结点。典型的应用是分布式锁。

存储采用类似linux文件结构,每个zNode都有相应data数据。
单个zNode结点存储信息如下:
null //数据
cZxid = 0x1816 //创建这个结点的事务id
ctime = Tue Apr 07 22:33:17 CST 2015 //创建时间
mZxid = 0x1816 //最后修改的事务id
mtime = Tue Apr 07 22:33:17 CST 2015 //最后修改时间
pZxid = 0x1867 //子结点变化的事务id
cversion = 4 //子结点变化version
dataVersion = 0 //数据版本号
aclVersion = 0 //权限控制变化版本
ephemeralOwner = 0x0 //如果不是0x0,则代表是临时结点
dataLength = 0 //数据长度
numChildren = 4 //子结点个数

2.2.ZXID
64位,高32位为选举届数,低32位为当前事务id。
客户端所能连接的zk,必定是客户端保存的zxid大于等于要连接的zk的zxid。
作用是标识唯一的一个操作,并且在之后用于防止客户端连接到比较旧的leader上。

三.服务端启动
/Users/zhao/Documents/installed/zookeeper-3.4.6/bin/zkServer.sh start /Users/zhao/Documents/installed/zookeeper-3.4.6/conf/zoo_sample.cfg

四.客户端连接服务
./zkCli.sh -server localhost:2181

五.基本配置说明
tickTime=2000, // 基本zk结点间的通信时间单位,毫秒,可以约定是a结点到b结点一个往返时间rt
initLimit=10,// fowller新加入时,需要从leader那同步数据过来,数据包括leader上的存储数据,zxid等.
syncLimit=5, // leader和fowller通信时,超时时间,如果在5*2000秒内未收到leader的心跳,这时会进行重新选举
dataDir=/Users/zhao/Documents/zk/data // zk的数据映像文件,
dataLogDir=/Users/zhao/Documents/zk/log // zk的事务日志文件,建议独立,提升性能

六.问题
1.client是否一直与zk master长连接?
可以与集群中任何一台zk保持长连接。

2.zk存储客户端流程是?
客户端与其中一台zk连接,然后将要操作指令发往这台zk。这台zk如果不是leader则会将操作指令转发到leader。由leader将操作指令发往其它zk,只要发送成功的zk数量大于等于合法数即认为成功。

3.客户端请求写入一个值,有3台服务器,如果master写入自己的结点,然后写入另一个结点时发生超时,这时返回客户端的是什么值?


4.zk主结点超时时间设置
tickTime=2000, // 基本zk结点间的通信时间单位,毫秒
syncLimit=5, // leader和fowller通信时,超时时间,如果在5*2000秒内未收到leader的心跳,这时会进行重新选举

另外客户端与zk的session超时时间设置是在客户端设置:
ZooKeeper zooKeeper = new ZooKeeper(hostport, 300000, null); 
//这里设置了这个客户端与服务端的超时时间为:300000毫秒

5.zk交互序列化是什么?
使用的是jute序列化,没有什么压缩优化,只是简单的将要序列化的对象转成字节数组。
优点是序列化时间比protobuf要高,缺点是序列化出来的数据空间比较大。
不过zk本身不建议存储大数据。默认每个结点Znode大小不能超过1M。

6.zk是否保证写入的顺序性,如何保证?
这里指单个客户端发送的操作指令是有序的。
这是由于zk同一时刻只有一个有序的leader。
操作指令有序就由leader去保证,底层实现可能对每个session唯护一个操作指令队列。

7.zk适用场景,最大结点值是多少?
默认每个结点Znode大小不能超过1M。

8.zk snapshot怎么做?
快照由另外一个独立后台线程去做。
默认在100000次事务操作后会触发一次,由 snapCount变量控制。

9.zk事务日志
dataLogDir=/Users/zhao/Documents/zk/log // zk的事务日志文件,建议独立,提升性能

10.zk树状结构目的?
树状结构,可以减少存储量,有些重复的前缀值可能不用存储,节省存储空间。
这个设计也可以用在地址设计上。

11.watch的特性
有序性指: 某个结点发生的事件,在客户端看来一定是有顺序的。
什么时候会丢失watch?
c1当前已经关注了:/providers结点的child事件。
c2在/provides下增加了子结点:a,然后c1收到了这个watch通知。
这时c3在/providers下增加子结点:b,由于c1还没来得及设置新的watch监听,因此这个事件将丢失。

12.zk的几个特性
1.有序性,客户端更新的有序性
指当个客户端的session操作是有序的。
2.原子性,一个更新操作是原子的,不会存在部分更新
3.可靠性,一旦返回客户端更新成功,则这个值就算某台zk挂了也不会丢失
4.客户端看到的变量值一致,无论这个客户端连的是哪个zk

13.zk客户端连接zk服务器过程
1.创建Zookeeper对象
2.创建两个thread,一个是io线程,一个是事件event线程
io线程处理同步相关请求,event线程处理异步及watch相关消息。
3.实际的网络连接在第一次与zk服务器交互时才会发生

这里可以定义一个T超时时间,在超过T这个时间后,zk服务器会关闭对应的session,此时session从connected状态转到closed状态。
对于客户端如果T/3未收到zk服务器的响应,则会发送一个心跳过去,如果在2/3T还未收到响应,则尝试在剩下的T/3寻找另外的zk服务器。

14.zxid
64位,高32位为选举届数,低32位为当前事务id。
客户端所能连接的zk,必定是客户端保存的zxid大于等于要连接的zk的zxid。

15.dubbo应用zk详解
dubbo用zk存在两种类型结点,一种是持久结点,一种是临时结点。
一个服务com.test.cartservice.service.SkuStockInMemService,注册到zk后,存储结构如下:

ls /dubbo/com.test.cartservice.service.CartService                                                                                              [consumers, routers, providers, configurators]   
这里dubbo,    com.test.cartservice.service.CartService,以及这个目录下consumers等都是持久结点。
而providers下具体某个服务提供方及consumers具体服务消费方都是临时结点。
服务消费方需要监控providers结点的变化,主要包括其子结点的变化。
这里在本地启动了一个CartService的服务提供方,信息如下:
[dubbo%3A%2F%2F192.168.124.118%3A20880%2Fcom.test.cartservice.service.CartService%3FaddCartItem.retries%3D0%26anyhost%3Dtrue%26application%3Dcart-app%26deleteCartItem.retries%3D0%26descreaseSkuNumForCartOfUser.retries%3D0%26dubbo%3D2.0.0%26generic%3Dfalse%26increaseSkuNumForCartOfUser.retries%3D0%26interface%3Dcom.test.cartservice.service.CartService%26methods%3DgetCartVoByUserId%2CdeleteCartItem%2CgetCartCountByUserId%2CincreaseSkuNumForCartOfUser%2CdescreaseSkuNumForCartOfUser%2CaddCartItem%26pid%3D1069%26side%3Dprovider%26timeout%3D7000%26timestamp%3D1505371986137]
这个结点就是一个临时结点。  

七.优化
保证数据目录与事务日志目录是不同磁盘。
其次session超时时间需要客户端与zk的网络情况,默认情况session超时时间最小为2倍的tickTime,最大为20倍的tickTime。







猜你喜欢

转载自blog.csdn.net/zhaozhenzuo/article/details/77980789
zk3
zk