zk理论知识
zk介绍
ZooKeeper 由雅虎研究院开发,后来捐赠给了 Apache。ZooKeeper 是一个开源的分布式应用程序协调服务器,其为分布式系统提供一致性服务。其一致性是通过基于 Paxos 算法的ZAB 协议完成的。其主要功能包括:配置维护、域名服务、分布式同步、集群管理等。zookeeper 的官网: zookeeper.apache.org
zk中的三个角色
为了避免 Zookeeper 的单点问题,zk 也是以集群的形式出现的。zk 集群中的角色主要有以下三类:
Leader:事务请求(写请求)的唯一处理者,也可以处理读请求
Follower:可以直接处理客户端的读请求,并向客户端响应;但其不会处理事务请求,其只会将客户端事务请求转发给Leader来处理;对Leader发起的事务提案具有表决权;同步 Leader 中的事务处理结果;Leader 选举过程的参与者,具有选举权与被选举权。(就好像正式工)
Observer:可以理解为不参与 Leader 选举的 Follower,在 Leader 选举过程中没有选举权与被选举权;同时,对于 Leader 的提案没有表决权。用于协助 Follower 处理更多的客户端读请求。Observer 的增加,会提高集群读请求处理的吞吐量,但不会增加事务请求的通过压力,不会增加 Leader 选举的压力。(就好像临时工)
集群中的 Leader 选举
集群中的zk主机首先都会选择自己成为Leader(不包含Observer)每个zk主机将自己主机的myid和zxid发送给其他的zk主机,其中myid为主机的编号,zxid则为epoch(年号可以理解为每一个leader都会有的唯一标示,集群重启阶段是没有这个ID的)+xid(事务id每次进行写请求,集群中递增的ID)。每一台zk主机收到其他zk主机发来的消息后,对比所有主机的zxid包括自己,选择zxid最大的为leader,若zxid相同则选择myid最大的为leader。
CAP定理
CAP 定理指的是在一个分布式系统中,Consistency(数据一致性)、 Availability(集群可用性)、Partition tolerance(分区容错性),三者不可兼得。
一致性(C):分布式系统中多个主机之间是否能够保持数据一致的特性。即,当系统数据发生更新操作后,各个主机中的数据仍然处于一致的状态。
可用性(A):系统提供的服务必须一直处于可用的状态,即对于用户的每一个请求,系统总是可以在有限的时间内对用户做出响应。
分区容错性(P):分布式系统在遇到任何网络分区故障时,仍能够保证对外提供满足一致性和可用性的服务。
zookeeper满足的CP一致性+分区容错性,而eureka则是满足AP可用性+分区容错性
数据同步
当集群中有新的写请求,Leader将该请求封装为Proposal,发送给Follower,Follower接受消息后返回ACK,若Leader收到的ACK超过半数,则通知所有Follower执行commit更新事务,并向所有的observer发送proposal,observer更新事务。Follower和observer同步后向Leader发送ACK,Leader收到ACK后会将follower和observer分别添加到可用的queues中,只有在Queues队列中的Follower和observer才可以对外提供服务,也就是说在ZK同步数据时,不对外提供服务,同步失败的主机也不会对外提供服务,这也就是ZK保持一致性的方法。同样这样做也失去了可用性,因为用户可能在极短的时间内无法得到ZK集群的响应。\
zk集群搭建
1 我这里使用的是VMware虚拟机,创建虚拟机后先关闭防火墙否则zk之间无法通讯。
2 在 zookeeper.apache.org 官网下载压缩包,然后解压。请注意zk需要jdk的支持所以请保证虚拟机上有jdk。接下来配置环境变量,记得配置完成后执行命令 source /etc/profile 刷新环境变量。
3 以上两个步骤四个虚拟机的操作完全相同。配置myid就是选举leader时所需要的myid,四台虚拟机中都要配置,注意目录,文件名相同,内容不同。
4 将配置文件zoo_sample.cfg复制,或者重命名为zoo.cfg
修改配置文件,前三个的配置文件完全相同。里边的配置都备注的有。
# The number of milliseconds of each tick
#一个时间单位是两秒
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
#初始化同步最多10个单位
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
#更新同步最多的时间单位
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
#快照存储的目录
dataDir=/home/zk/zookeeper-3.4.14/data
# the port at which the clients will connect
#端口
clientPort=2181
#集群ip 第一个端口为集群通信端口,第二个为选举端口
server.1=192.168.31.51:2888:3888
server.2=192.168.31.39:2888:3888
server.3=192.168.31.148:2888:3888
server.4=192.168.31.27:2888:3888:observer
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
View Code
第四个observer的配置文件如下,其实只是多了一行配置。
# The number of milliseconds of each tick
#一个时间单位是两秒
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
#初始化同步最多10个单位
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
#更新同步最多的时间单位
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
#快照存储的目录
dataDir=/home/zk/zookeeper-3.4.14/data
# the port at which the clients will connect
#端口
clientPort=2181
#集群ip 第一个端口为集群通信端口,第二个为选举端口
server.1=192.168.31.51:2888:3888
server.2=192.168.31.39:2888:3888
server.3=192.168.31.148:2888:3888
server.4=192.168.31.27:2888:3888:observer
#这个节点为observer
peerType=observer
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
View Code
在以上四台主机中,主机2为leader,我们关闭主机2,看看集群是否会自己选择leader,主机4位observer所以不参与选举,1 3中3的myid最大所以选择3位leader
zk基本命令
进入客户端
zkCli.sh进入本地客户端,注意虽然连接的是本地zk但是数据内容还是连接的集群。
查看节点
ls /path/path
zk的节点类似于我们的文件目录一级一级往下迭代。当前这个zookeeper节点是zk自带的。
创建节点
永久节点
create /path value
创建永久节点,并且设置节点信息
临时节点
create -e /path value
创建临时节点,并且设置节点信息
临时节点和永久节点的区别
临时节点绑定客户端,客户端一旦关闭,该节点就会被自动删除,临时节点也不能创建子节点
顺序节点
create -s /path value
创建的节点会会自动带有编号,这意味着,我们可以使用zk获取唯一的编号,并且在分布式环境下也是唯一的。
临时顺序节点
create -e -s /path value
查看节点内容
get /path/path/...
获取节点的内容以及节点的详细描述
节点信息描述
删除节点
delete /path/path...
注意如果节点下包含的有子节点,无法删除,必须将子节点全部删除后,才可以删除。
修改节点内容
set /path/path... value
锁定某一个节点然后修改节点内容