1. 简介
ZooKeeper(官网)是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
2. 特征/保障
ZooKeeper非常快而且非常简单。然而,由于它的目标是成为构建更复杂的服务(例如同步)的基础,因此它提供了一组保障:
- 顺序一致性:来自客户端的更新将按照发送的顺序应用。
- 原子性:更新要么成功,要么失败,没有部分结果。
- 统一视图:无论客户端连接到哪个服务器,客户端都将看到相同的服务视图。即,即使客户端故障转移到具有相同会话的不同服务器,客户端也永远不会看到系统的旧视图。
- 可靠性:一单应用更新,它将从那时起持续存在,直到客户端覆盖更新。
- 及时性:保证系统的客户视图在一定的时间范围内是最新的。
3. 安装/验证/使用/集群配置
ZooKeeper在Linux虚拟机中安装的详细步骤如下:
安装笔记:
准备 node01~node04 4台Linux虚拟机
1, 安装jdk,并设置javahome(最好不要yum安装jdk!它不是Hotspot的JVM,而是OpenJDK,后期几乎不维护了!)
*, node01:
2, 下载zookeeper # 官网:zookeeper.apache.org
3, tar xf zookeeper.*.tar.gz # 解压
4, mkdir /opt/mxf # 创建用于存放zk解压后的文件的目录
5, mv zookeeper /opt/mxf
6, vi /etc/profile # 配置环境变量
export ZOOKEEPER_HOME=/opt/mxf/zookeeper-3.4.6
export PATH=$PATH:$ZOOKEEPER_HOME/bin
# 使配置生效
source /etc/profile
或者 . /etc/profile 都可以
之后,可以复制到其他虚拟机下:
scp /etc/profile node02:/etc
7, cd zookeeper/conf
8, cp zoo.sam*.cfg zoo.cfg # 复制后的 zoo.cfg 是zk启动默认加载的配置文件
9, vi zoo.cfg
dataDir=/var/mxf/zk # 放日志、快照、myid等数据文件
server.1=node01:2888:3888
server.2=node02:2888:3888
server.3=node03:2888:3888
server.4=node04:2888:3888
# 这里如果这样配置的node01·node04必须要有配置映射,或者node01修改了/etc/hosts
# 否则需要改成节点主机的IP,下文有说明
注:zk集群和redis sentinel(有发布订阅机制)不同:
1、它必须要把集群都有谁写进来,靠人来规划集群
2、而且它们的 【行数/2 + 1】 就是过半数
3、node01~node04 表示4个节点
4、端口号 3888 表示首次启动没有leader时,各节点通信投票选出一个leader
5、端口号 2888 表示,上步选出leader后,leader会起一个2888端口,其它节点
通过它连接leader
6、zk选举leader是谦让出来的,谁的ID(server.4等)最大,谁是leader,后续再
配合事务ID(前提是:需要拥有最新的事务ID,谁的数据最完整),进行选举
注2:由于这里配置的node01·node04没有配置映射,或者node01修改了/etc/hosts 原因,
导致zk启动报错,在关闭了iptables前提下,也无法连接,后来修改:
====================================================================================
server.1=192.168.246.111:2888:3888
server.2=192.168.246.112:2888:3888
server.3=192.168.246.113:2888:3888
server.4=192.168.246.114:2888:3888
即修改为具体IP即可
====================================================================================
10, mkdir -p /var/mxf/zk # -p 两级目录都不存在,直接创建
11, echo 1 > /var/mxf/zk/myid # 这里每台都要唯一的一个 myid,必须和配置文件相同
12, cd /opt && scp -r ./mxf/ node02:`pwd` # 分发给其它3台,注意拷贝的是整个文件夹
注:这里如提示:-bash: scp: command not found,需要各节点安装:
# yum install openssh-clients
并且node01需要配置,否则无法复制:
===============================================================================
[root@node01 opt]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.246.111 node01
192.168.246.112 node02
192.168.246.113 node03
192.168.246.114 node04
===============================================================================
13, node02~node04 创建 myid
14, 启动顺序 1,2,3,4
15, zkServer.sh start-foreground # 前台启动,默然是后台启动
注:zkServer.sh help 可以有命令提示
zkCli.sh
help
ls / (显示根目录)
create /o "" (持久节点:这里data是必须的,为空也得给出 "",否则无法创建)
create -s /abc/aaa (-s,即sequential,防止并发下,节点目录被覆盖)
create -e /o/xx (-e 表示创建的是临时节点)
create -s -e /xx/xo
set /o "hello" (二进制安全的,只存放字节数组)
get /o
目录树中,各项含义:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
[zk: localhost:2181(CONNECTED) 20] get /o
"hello"
cZxid = 0x300000003
(zk是顺序执行,体现在事务ID上,单机维护其递增。
1、cZxid:这项是创建时的事务ID
2、共64个字节,0x 表示16进制,后面00000003是每个数字代表4个字节,共32位,是递增序列,
从0开始;0x3 中前面0省略不写,前32位代表是一个纪元,是第几个Leader,即2是第
二代Leader
)
ctime = Wed Sep 14 22:09:01 CST 2022
(创建时间)
mZxid = 0x300000003
(修改的事务ID)
mtime = Wed Sep 14 22:09:01 CST 2022
(修改时间)
pZxid = 0x300000003
(当前这个节点下,创建的最后一个事务ID,父节点事务ID)
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
(临时归属者:创建的临时节点有 sessionID,值就是sessionID,如果客户端端口,
随之销毁--即临时节点只在session会话期有效)
dataLength = 2
numChildren = 0
[zk: localhost:2181(CONNECTED) 21]
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
可以查看该节点(如 node01)下对于端口的所有连接信息:
netstat -natp | egrep '(2888|3888)'
-- 3888:选主投票用的
-- 2888:leader 接收 write 请求
4. 集群
4.1 主从
- ZooKeeper主从集群中重要的两个角色:
- Leader:主节点,可以对外提供读写服务;
- Follower:从节点,只能对外提供读服务。
- 每一个client和zk连接都会有一个session:
- session是描述这个连接的用户是谁;
- session有创建和消亡的概念。
4.2 问题
上面图中的ZooKeeper主从集群,包含一个Leader主节点和多个Follower从节点,由于Leader是单节点,会出现如下问题:
Leader是单节点,就会有单点故障,一旦挂掉,就会导致整个集群服务不可用,这样的集群就会缺少可靠性。
如果有一种方式,可以在主节点挂掉后快速地恢复出一个Leader,就会解决上述问题。
事实上,zk集群极其高可用。它可以在极短时间(200ms)内重新选举出一个Leader,使集群快速恢复服务。
4.3 zk两种运行状态
- 可用状态:即Leader和Follower同时运转正常,zk集群正常对外提供服务;
- 不可用状态:当集群中的Leader挂掉期间,整个集群呈无主状态,此时无法对外提供服务;
- 不可用状态恢复到可用状态,应该越快越好,而ZooKeeper在这方面做的非常好。
4.4 不要把zk当做数据库用
ZooKeeper的节点node只能存1M的数据,不应该把zk当做数据库来存储数据用。因为作为一个分布式协调服务,要保证zk对外快。它是一个Service,对外提供协调服务时要很快,就要减少所有网络带宽和数据延迟。
5. zk是一个目录树结构
5.1 节点类型
Zookeeper的节点node可以用来存储最多1M的数据,它包含如下几种节点类型:
- 持久节点:创建节点后,只要不删除就会一直存在;
- 临时节点:其创建和消亡是随着client端session会话的创建和断开,而client建立连接和断开连接,session都会消耗一个事务id;
- 序列节点:只是一个概述上的节点,基于zk集群中的Leader维护着的递增序列。
5.2 目录结构的功能
zk的目录结构可以应用如下的功能:
- 统一配置管理 <- 1M数据;
- 分组命名 <- path结构;
- 统一命名 <- sequential;
- 同步 <- 临时节点。
5.3 分布式应用场景
- 分布式锁(临时节点):锁依托于一个父节点,且具备-s(递增序列),代表父节点下可以有多把锁–即队列式事务的锁,需要client客户端通过代码实现。
- HA高可用,选主。