目录
基本概念
ZooKeeper是一个分布式开源框架,提供了协调分布式应用的基本服务,它向外部应用暴露一组通用服务——分布式同步(Distributed Synchronization)、命名服务(Naming Service)、集群维护(Group Maintenance)等,简化分布式应用协调及其管理的难度,提供高性能的分布式服务。ZooKeeper本身可以以Standalone模式安装运行,不过它的长处在于通过分布式ZooKeeper集群(一个Leader,多个Follower),基于一定的策略来保证ZooKeeper集群的稳定性和可用性,从而实现分布式应用的可靠性。
分布式环境特点
1)分布性 异地多活
2)并发性 程序运行过程中,并发性操作是很常见的,同一个分布式系统中的多个节点,同时访问一个共享资源,如数据库或者分布式存储。 分布式并发是基于多进程
3)无序性 进程之间的消息通信会出现顺序不一致问题
分布式环境下面临的问题
1)网络通信 网络本身的不可靠性 光缆被挖断火灾等等
2) 网络分区 (脑裂)
当网络发生异常,导致分布式系统中部分节点之间的网络遗憾吃不断增大,最终导致分布式架构的所有节点,只有部分节点能够正常通行。
3) 三态
在分布式架构中,除了成功,失败还有一种状态叫超时
4)分布式事务 同时成功同时失败,事务回滚
CAP理论
1)CAP理论
C 一致性 (Consistency) 所有节点上数据,时刻保持一致
A 可用性(Availability) 每个请求都能够收到一个响应,无论响应成功或者失败
P 分区容错 (Partition-tolerance)表示系统出现脑裂以后,可能导致某些server与集群中的其他机器失去联系。
CP / AP
仅仅适用于原子读写的Nosql场景,不适用于数据库系统
BASE理论
基于CAP理论,CAP理论并不适用与数据库事务(更新一些错误的数据导致数据紊乱,无论怎样的数据库高可用都是徒劳)XA事务虽然可以保证数据库在分布式系统下的ACID特性,但是会带来性能上的影响。
eBay尝试了一种完全不同的方式:放宽了对事务ACID的要求,提出了BASE理论:
Basically availbale 基本可用 数据库采用分片模式,把100万用户数分布在5个实例上,破坏其中一个实例。仍然可以保证80%的用户可用。
soft-state 软状态 在基于client-server模式的系统中,server端是否有状态,决定了系统是否具备良好的水平扩展,负载均衡,故障恢复等特性。
server端承诺会维护client端状态数据,这个状态仅仅维持一小段时间,这段时间以后,server端就会丢弃这个状态,恢复正常状态。
Eventually consistent 数据的最终一致性
zookeeper能做什么?
数据的发布/订阅 (配置中心:disconf,watcher机制)
负载均衡(dubbo利用zookeeper机制实现负载均衡)
命名服务
master选举(kafka,hadoop,hbase)
分布式队列
分布式锁
zookeeper特性
1)顺序一致性
从同一个客户端发起的事务请求。最终会严格按照顺序被应用到zookeeper中
2)原子性
所有的事务请求的处理结果在整个集群中的所有机器的应用情况是一致的,也就是说,要么整个集群的所有机器都成功地应用了某个事务,要么就都不应用。
3)可靠性
一旦服务器成功应用了某一个事务数据,并且对客户端做了响应,那么这个数据在整个集群中一定是同步并且保留下来。
4)实时性
一单一个事务被成功应用,客户端能够立即从服务器读取到事务变更后的最新数据状态。(zookeeper仅仅保证在一定时间内,接近实时)
环境搭建
环境准备:centos7.2
zookeeper的安装【单机环境】
步骤一:下载zookeeper的安装包
apache.fayea.com/zookeeper/
我这边使用的是比较老的一个版本
zookeeper-3.4.10.tar.gz
步骤二:解压zookeeper
tar -zxvf zookeeper-3.4.10.tar.gz
步骤三:cd 到Z_HOME/conf目录下 copy一份zoo.cfg
进入到conf目录里面有一个zoo_sample.cfg 的示例文件
cp zoo_sample.cfg zoo.cfg
步骤四:启动Zk
sh zkServer.sh start
start|start-foreground|stop|restart|status|upgrade|print-cmd
步骤五:连接zk
2181是zookeeper默认的端口号,我们连一下
sh zkcli.sh -server localhost:2181
如下代表连接成功
zookeeper的安装【集群环境】
zookeeper集群,包含三种角色:leader/follower/observer
leader:接受所有follower的提案请求并且统一协调发提案的投票,负责与所有的follower进行内部的数据交换(同步)
follower:直接为客户端服务并且参与提案的投票,同事与leader进行数据交换(同步)
observer:直接为客户端服务但是不参与提案的投标,只是也与leader进行数据交换(同步)
弄个三台服务器 一个master 俩个follower 一台observer
192.168.48.128
192.168.48.130
192.168.48.131
192.168.48.132 observer
首先现在三台服务器上都部署zookeeper,安装步骤如单机的操作
步骤一:修改配置文件 zoo.cfg
在配置文件的尾部加上如下内容
在集群环境下每个机器都必须要感知到其他服务
server.id=host:port:port
id的取值范围:1~255 用id来标志该机器在集群中的机器序号
2181是zookeeper的端口号 follower节点跟leader节点交换信息的端口号 不能使用2181 这是客户端访问zookeeper的端口号
3181是leader选举的端口号
步骤二: 创建myid
在每一个服务器的dataDir目录下创建一个myid的文件,文件内容就一行数据,内容是每台机器对应的serverID的数字
步骤三:启动zookeeper【防火墙先关掉】
observer,不影响写性能情况下去扩展zookeeper
observer是一种特殊的zookeeper节点,可以帮助解决zookeeper的扩展性
大量客户端访问zookeeper集群,需要增加zookeeper集群机器数量,从而增加zookeeper集群性能,导致zookeeper写性能下降。zookeeper的数据变更需要半数以上服务器投票通过,造成网络消耗,增加投票成本。
1)observer不参与投票,只接受投票结果
2)不属于zookeeper的关键部位
如何配置一个observer
1)在zoo.cfg里面增加一行
peerType=observer
2)配置文件尾部增加
server.1=192.168.48.128:2181:3181:observer
leader:
follower:
observer:
客户端使用
zoo.cfg配置文件参数分析
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
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=/tmp/zookeeper
# the port at which the clients will connect
clientPort=2181
# 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
tickTime= 2000 zookeeper最小时间单位长度(ms)
initLimit=10 结果是10tickTime follower节点启动之后与leader节点完成数据同步的时间
syncLimit=5 5tickTime follower节点与leader节点进行心跳检测的最大延迟时间
dataDir=/tmp/zookeeper 表示zookeeper服务器存储快照文件的目录
dataLogDir 表示配置zookeeper事务日志的存储日志 默认指定在dataDir目录下
clientport 表示客户端和服务器建立连接的端口号:2181【默认】
数据节点
在 ZooKeeper中,每个数据节点都是有生命周期的,其生命周期的长短取决于数据节点的节点类型。在 ZooKeeper中,节点类型可以分为持久节点(PERSISTENT)、临时节点(EPHEMERAL)和顺序节点(SEQUENTIAL)三大类,具体在节点创建过程中,通过组合使用,可以生成以下四种组合型节点类型:
1) 持久节点(PERSISTENT):持久节点是 ZooKeeper中最常见的一种节点类型。所谓持久节点,是指该数据节点被创建后,就会一直存在于 ZooKeeper服务器上,直到有删除操作来主动清除这个节点。
2)持久顺序节点(PERSISTENT SEQUENTIAL):持久顺序节点的基本特性和持久节点是一致的,额外的特性表现在顺序性上。在ZooKeeper中,每个父节点都会为它的第一级子节点维护一份顺序,用于记录下每个子节点创建的先后顺序。基于这个顺序特性,在创建子节点的时候,可以设置这个标记,那么在创建节点过程中, ZooKeeper会自动为给定节点名加上一个数字后缀,作为一个新的、完整的节点名。另外需要注意的是,这个数字后缀的上限是整型的最大值。
3)临时节点(EPHEMERAL):和持久节点不同的是,临时节点的生命周期和客户端的会话绑定在一起,也就是说,如果客户端会话失效,那么这个节点就会被自动清理掉。注意,这里提到的是客户端会话失效,而非TCP连接断开。另外, ZooKeeper规定了不能基于临时节点来创建子节点,即临时节点只能作为叶子节点。
4)临时顺序节点(EPHEMERAL SEQUENTIAL):临时顺序节点的基本特性和临时节点也是一致的,同样是在临时节点的基础上,添加了顺序的特性。
会话状态
NOT CONNECTED 未连接
CONNECTING 连接中
CONNECTED 已连接
CLOSED 关闭
节点配置信息
cZxid = 0x2
ctime = Thu Dec 05 21:32:44 CST 2019
mZxid = 0x2
mtime = Thu Dec 05 21:32:44 CST 2019
pZxid = 0x6
cversion = 3
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 1
节点的状态信息
cZxid = 0x100000006 节点被创建时的事务id
ctime = Mon Aug 27 17:05:03 CST 2018 节点被创建时的时间
mZxid = 0x10000000d 节点被最后一次修改的事务id
mtime = Mon Aug 27 18:58:20 CST 2018 节点被最后一次修改的时间
pZxid = 0x100000007 子节点被最后一次修改的事务id
cversion = 1 子节点的版本号
dataVersion = 1 数据版本号
aclVersion = 0 accesscontrol 节点修改权限
ephemeralOwner = 0x0 创建临时节点的时候,会有一个sessionid,该值存储的就是这个id
dataLength = 3 数据长度
numChildren = 1 子节点数