为什么要学习zk?
分布式,dubbo、kafka
分布式系统是什么?
不同硬件、软件、网络、计算机,仅仅通过消息进行协调和通讯
分布性
一个项目拆分成多个服务
对等性
服务对等、数据对等
并发性
多线程、多JVM
缺乏全局时钟
每个节点都有自己的时间系统
故障随时发生
节点发生故障可能性大
分布式架构
应用层、服务层、基础设施、数据库层
zookeeper的作用,类比为交警,每个节点是路上的车,为了交通的可用性,zk需要知道每个节点的健康状态(如公交车出故障了,需要及时排出新的公交车(服务注册与发现),在很窄的路只允许单独一个方向的车通过(分布式锁)
分布式系统的方法论
问题
通讯异常:网络异常
网络分区:脑裂,比如一个交警接管一篇区域的交通,如果突然出现停电或者其他因素,导致某些道路接收不到交警的指令,需要一个临时工,片警来指挥交通。同一个区域产生两个互相冲突的负责人就会出现脑裂的现象。
三态:成功、失败、超时态
节点故障:集群节点的宕机
CAP方法论
一致性:Consistency,分布式环境中,节点之前的数据保持一致性,即一个数据改变,所有节点都能马上读取最新的值
可用性:Available,服务一直处于可用状态,在有限时间内,返回结果。有限时间:加缓存,负载;返回结果:出现宕机,马上有副节点顶替。
分区容错性:Partition Fault Tolerance,分布式系统遇到任何网络分区故障时,仍然需要保持一致性和可用性,不能出现脑裂的现象。
CAP理论不能同时满足,一般只能满足其中的两项。
AC:满足可用性和一致性,很简单,就把数据和服务放在一个节点上。
PC:满足分区容错性和一致性,当节点故障或网络故障时,受影响的服务需要等待一段时间,在等待的时间内,服务是不可用的。
AP:满足可用性和分区容错性,不能保证数据实时一致性,但能保证最终一致性。
很显然,我们一般不会抛弃P,所以只能在A和C之间寻找平衡
BASE玄学
基本可用:basically avaliable,当系统出现一些故障,允许损失部分可用性,保证系统基本可用,比如双十一淘宝页面卡顿。
软状态:soft state,允许不同节点之间的数据副本之间同步存在延时。12306买火车票,请求会进入排队队列。
最终一致性:eventually consistent 所有数据在一段时间的数据同步后,达到最终一致性。如金融产品中的余额短时间不一致。
Zookeeper前述
分布式协调服务coordination service
特性
简单数据结构:共享树形结构,类似文件系统
集群:避免单点故障,超过半数工作正常即可
顺序访问:每一个读请求,zk会分配一个全局唯一的递增编号
高性能:基于内存,使用读场景为主的业务场景
用途
数据发布订阅
负载均衡
命名服务
master选举
集群管理
分布式队列
分布式锁
需要学什么
应用场景
paxos和zk协议
选举算法
zk节点类型
zk的watch是永久的吗
zk的部署方式,集群的角色有哪些,需要多少节点
如果集群只有三态,挂掉其中一台能否正常工作?
集群支持动态加机器?
Zk基础
部署
win和linux的安装差不多,这里主要讲linux,创建data和log目录,把conf目录下的zoo_sample.cfg复制在当前目录,改名zoo.cfg。zk有三种安装模式:单机、集群和集群伪分布式。
- 单机
略
- 集群安装
install zookeeper cluster
修改zoo.cfg
dataDir=/develop/..../data
server.0=192.....134:2888:3888
server.1=192.....135:2888:3888
server.2=192.....136:2888:3888
创建服务器标识
cd /develop/..../data
echo 0 > myid
复制zookeeper文件夹到其他服务器节点
# 复制
scp -r /soft root@zk2:/
修改myid为1、2
启动zk
./zkServer.sh start
./zkServer.sh status
目录结构
bin 脚本:zkCli.sh、zkServer.sh
conf 配置文件:zoo.cfg,端口默认2181
contrib zk附加功能
dist-maven maven仓库文件
docs zk文档
lib 依赖的第三方库
recipes 经典场景代码
src zk源码
zk特性
会话
会话状态:connecting、connected、reconnecting、reconnected、close
创建zk对象后,connecting,然后尝试连接,连接成功后,connected,如果出现网络故障等原因而断开,就reconnecting,重新尝试连接,连接成功,reconnected,会话关闭,close
数据模型
数据节点,znode,每个znode必须有值,同时可以有子节点,这点和传统的文件夹结构不一样
节点类型
持久节点
临时节点
持久顺序节点
临时顺序节点
节点的状态属性
czxid:节点被创建的zxid值
mzxid:节点被修改的zxid值
pzxied:子节点最后一次被修改时的事务ID
ctime:节点被创建的时间
mtime:节点最后一次被修改的时间
version:节点被修改的版本号
cversion:节点所拥有的子节点被修改的版本号
aversion:节点的acl被修改的版本号
emphemeralOwner:如果该节点是临时节点,那么它的值为这个节点拥有者的会话ID;or,它的值为0
dataLength:节点数据域的长度
numChildren:节点拥有的子节点的个数
ACL保障数据安全
略
命令行
服务端常用命令
启动 bin/zkServer.sh start
查看状态 bin/zkServer.sh status
停止 bin/zkServer.sh stop
重启 bin/zkServer.sh restart
客户端常用命令
客户端连接服务 zkCli.sh -server 127.0.0.1:2181
# 显示zk的/目录下的内容
ls /
# 显示zk的/目录下的内容,并显示更新次数等数据
ls2 /
# 创建一个节点,并初始化,-e -s
create /zk "test"
# 获取节点的内容
get /zk
# 修改节点的内容
set /zk "zk"
# 删除节点
delete /zk
# 递归删除,同时会删除子节点
rmr /zk
# 退出客户端
quit
ACL常用命令
acl用来控制权限,分为三个维度:scheme、id、permission,通常用scheme:id:permission
表示权限
scheme:授权策略,可选world/auth/digest/ip
id:表示用户,当为world时,anyone;当为auth时,username/password,当为digest时,username/base64(sha1(password));当为ip时,为ip,如192.168.1.1/16,表示匹配前16个bit的ip段
其中auth需要使用该命令添加用户
addauth digest user:pwd
permission:表示权限,crwda
create 创建 delete 删除 read读取 write修改 admin设置子节点权限的权限
# world
# 获取权限
create /cbl xxx
getAcl /cbl
# 设置权限
setAcl /cbl world:anyone:crwa
getAcl /cbl
# 创建子节点并删除,由于没有d权限,所有无法删除
create /cbl/cbl xxx
delete /cbl/cbl
## auth
# 添加授权信息
add auth digest cbl:root
# 设置权限
setAcl /cbl auth:cbl:root:crwa
# 退出客户端,没有权限无法访问
ls /cbl
## digest
setAcl /cbl digest:cbl:sdfsdfsdfdsfdfs:crwa
# 加密算法
java -Djava.ext.dirs=/soft/zookeeper-3.4.12/lib -cp /soft/zookeeper-3.4.12/zookeeper-3.4.12.jar org.apache.zookeeper.server.auth.DigestAuthenticationProvider cbl:root
如果没有权限删除节点,可以启用super权限
// 获取密码
DigestAuthenticationProvider.generateDigest("super:admin")
在zkServer启动脚本添加
-Dzookeeper.DigestAuthenticationProvider.superDigest=super:xQJmxLMiHGwaqBvst5y6rkB6 HQs=
启用客户端用管理员登录
addauth digest super:admin
常用命令
# 首先安装nc
yum install nc
# 查看那个节点被作为follower或者leader
echo stat|nc 127.0.0.1 2181
# 测试是否启动了该server,若imok表示已经启动
echo ruok|nc 127.0.0.1 2181
# 列出未经处理的会话和临时节点
echo dump|nc 127.0.0.1 2181
# 关掉server
echo kill|nc 127.0.0.1 2181
# 输出相关服务配置的详细信息
echo conf|nc 127.0.0.1 2181
# 列出所有连接到服务器的客户端的完全的连接/会话的详细信息