关于Zookeeper
Zookeeper 是一个分布式协调服务的开源框架。 主要用来解决分布式集群中应用系统的一致性问题
ZooKeeper 典型应用
-
数据发布与订阅
发布者将数据发布到 ZK节点上,供订阅者动态获取数据,实现配置信息的集中式管理和动态更新。(适合数据量很小的场景, 这样数据更新可能会比较快) -
命名服务(Naming Service)
通过使用命名服务,客户端应用能够根据指定名字来获取资源或服务的地址,提供者等信息。(如 Dubbo中使用 ZooKeeper 来作为其命名服务,维护全局的服务地址列表) -
分布式锁
保持独占: 创建节点(非序列化,短暂的)谁先创建谁就获得锁, 其他软件的master 选举,slaves监听这个节点
控制时序: 创建临时有序节点,所有试图来获取这个锁的客户端,最终都是会被安排执行
Watch机制
- Watcher 为以下三个过程
客户端向服务端注册 Watcher
服务端事件发生触发 Watcher
客户端回调 Watcher 得到触发事件情况 - Watch 机制特点
一次性触发 (这种效果是一次性的, 后续再次发生同样的事件,不会再次触发)
事件封装
event 异步发送
先注册再触发
ZooKeeper的特性
- 全局数据一致: 集群中每个服务器保存一份相同的数据副本, client 无论连接到哪个服务器,展示的数据都是一致的,这是最重要的特征;
- 可靠性:如果消息被其中一台服务器接受,那么将被所有的服务器接受。
- 顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息 a 在消息 b 前发布,则在所有 Server 上消息 a 都将在消息 b 前被发布;偏序是指如果一个消息 b 在消息 a 后被同一个发送者发布, a 必将排在 b 前面。
- 数据更新原子性:一次数据更新要么成功(半数以上节点成功),要么失败,不存在中间状态;
- 实时性: Zookeeper 保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息
ZooKeeper集群
ZooKeeper 集群角色
- Leader:
Zookeeper 集群工作的核心
事务请求(写操作) 的唯一调度和处理者,保证集群事务处理的顺序性;集群内部各个服务器的调度者。
对于 create, setData, delete 等有写操作的请求,则需要统一转发给leader 处理, leader 需要决定编号、执行操作,这个过程称为一个事务 - Follower:
处理客户端非事务(读操作) 请求,转发事务请求给 Leader;
参与集群 Leader 选举投票 - Observer: (针对访问量比较大的 zookeeper 集群)
观察者角色,观察 Zookeeper 集群的最新状态变化并将这些状态同步过来,其对于非事务请求可以进行独立处理,对于事务请求,则会转发给 Leader服务器进行处理。
不会参与任何形式的投票只提供非事务服务,通常用于在不影响集群事务处理能力的前提下提升集群的非事务处理能力。
ZooKeeper集群搭建
Zookeeper 集群搭建指的是 ZooKeeper 分布式模式安装。 通常由 2n+1台 servers 组成。 这是因为为了保证 Leader 选举(基于 Paxos 算法的实现) 能过得到多数的支持,所以 ZooKeeper 集群的数量一般为奇数。
-
搭建前的准备
准备三台Linux服务器node1, node2, node3
配置好主机主机名和IP地址的映射
安装好JDK
同步时间:yum install -y ntp
ntpdate ntp6.aliyun.com关闭防火墙:
service iptables stop
永久关闭防火墙:
chkconfig iptables off
-
下载、上传、解压安装包
下载地址: https://www.apache.org/dyn/closer.cgi/zookeeper/
上传到Linux后解压并移动至要安装的路径tar zxvf tar -zxvf zookeeper-3.4.5.tar.gz
mv zookeeper-3.4.5 /export/server/zookeeper -
修改Zookeeper配置文件
进入到zookeeper下的conf目录cd zookeeper/conf
复制一份配置文件并编辑
cp zoo_sample.cfg zoo.cfg
vi zoo.cfg添加如下内容
dataDir=/export/data/zkdata # 指定的两个端口分别为心跳端口、选举端口 server.1=node1:2888:3888 server.2=node2:2888:3888 server.3=node3:2888:3888
将zookeeper文件夹分发到其余两台Linux上
scp -r /export/server/zookeeper root@node2:/export/server/zookeeper
scp -r /export/server/zookeeper root@node3:/export/server/zookeeper分别在三台Linux的/export/data/路径下创建zkdata文件夹并创建文件myid
cd /export/data
mkdir zkdatamyid的内容分别为 1、2、3
echo 1 > myid
-
配置环境变量(每台Linux都要配置)
vi /etc/profile
export ZOOKEEPER_HOME=/export/server/zookeeper export PATH=$PATH:$ZOOKEEPER_HOME/bin
生效环境变量:
source /etc/profile
-
启动与关闭
在每台Linux上执行启动命令:zkServer.sh start
启动完成后查看状态:
zkServer.sh status
会发现有一个Leader, 两个Follower
如果启动不成功,可以观察zookeeper.out日志,查看错误信息进行排查
tail -100f zookeeper.out
关闭命令
zkServer.sh stop
为方便启动编写一键启动脚本:
#!/bin/bash for host in node1 node2 node3 do { echo $host start ssh $host "source /etc/profile;/export/server/zookeeper-3.4.7/bin/zkServer.sh start" echo "$host zk is running" } done
一键停止脚本:
#!/bin/bash for host in node1 node2 node3 do { echo "$host zk is stopping" ssh $host "/export/server/zookeeper-3.4.7/bin/zkServer.sh stop" } done
注意:使用脚本前需要配置好ssh免密登录
配置ssh免密登录的方法: 1.生成密钥 在node1上输入命令 ssh-keygen -t rsa 后按4下回车生成密钥 2.发送密钥 ssh-copy-id node1 ssh-copy-id node2 ssh-copy-id node3 3.登录 ssh root@node2 第一次需要验证,按照提示进行输入即可 4.退出 exit 5.每台机器上都要做此操作
-
关于配置文件中的参数说明
tickTime=2000
tickTime这个时间是作为zookeeper服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是说每个tickTime时间就会发送一个心跳。
initLimit=10
initLimit这个配置项是用来配置zookeeper接受客户端(这里所说的客户端不是用户连接zookeeper服务器的客户端,而是zookeeper服务器集群中连接到leader的follower 服务器)初始化连接时最长能忍受多少个心跳时间间隔数。
当已经超过10个心跳的时间(也就是tickTime)长度后 zookeeper 服务器还没有收到客户端的返回信息,那么表明这个客户端连接失败。总的时间长度就是 10*2000=20秒。
syncLimit=5
syncLimit这个配置项标识leader与follower之间发送消息,请求和应答时间长度,最长不能超过多少个tickTime的时间长度,总的时间长度就是5*2000=10秒。
dataDir=/export/data/zkdata
dataDir顾名思义就是zookeeper保存数据的目录,默认情况下zookeeper将写数据的日志文件也保存在这个目录里;
clientPort=2181
clientPort这个端口就是客户端连接Zookeeper服务器的端口,Zookeeper会监听这个端口接受客户端的访问请求;
server.A=B:C:D
A是一个数字,表示这个是第几号服务器,
B是这个服务器的IP地址,
C第一个端口用来集群成员的信息交换,表示这个服务器与集群中的leader服务器交换信息的端口
D是在leader挂掉时专门用来进行选举leader所用的端口。
shell基本操作
启动客户端
zkCli.sh – server ip
创建节点
create [-s] [-e] path data acl
-s 顺序节点: 可以创建同名节点zookeeper会在同名节点名字末尾加上序号
-e : ephemeral缩写;只和创建的会话有关系会话关闭节点就会消失。而且不能存在子节点。[不指定则表示永久节点]
读取节点
get 命令可以获取 Zookeeper 指定节点的数据内容和属性信息。
ls 命令可以列出 Zookeeper 指定节点下的第一级的所有子节点
更新节点
set path data [version]
data 就是要更新的新内容, version 表示数据版本
删除节点
delete path [version]
存在子节点,那么无法删除该节点,必须先删除子节点,再删除父节点。
递归删除节点Rmr path
历史命令history