zookeeper基础知识分享(一)
写在前面
今天来学习Zookeeper部分的知识,之后会学习hbase的知识。
Zookeeper简介
Zookeeper是一个高效的分布式协调服务,可以提供以下功能:
- 配置信息管理
- 命名
- 分布式同步
- 集群管理
- 数据库切换等服务
它不适合用来存储大量信息,而是用于存储一些配置信息、发布与订阅等少量数据。以下是Zookeeper的典型应用场景:
- Hadoop
- Storm
- 消息中间件
- RPC服务框架
- 分布式数据库同步系统
Zookeeper集群
Zookeeper集群中节点的个数一般为奇数(>=3)。如果集群中的Master节点挂掉,且剩余节点数超过半数时,集群可以通过选举推举新的主节点继续对外提供服务。
客户端发起事务请求时,事务的结果在整个Zookeeper集群中所有机器上的应用是一致的。不会出现集群中部分机器应用了该事务,而其他机器未应用该事务的情况。Zookeeper确保集群中所有机器的数据模型一致。
Zookeeper能够保证客户端请求的顺序,每个请求都会分配一个全局唯一的递增编号,用来反映事务操作的先后顺序。
Zookeeper将全量数据保存在内存中,并直接服务于所有的非事务请求。因此,在以读操作为主的场景中,Zookeeper性能非常突出。
Zookeeper的数据结构与节点角色
Zookeeper使用的主要数据结构是树形结构,根节点为/
。Zookeeper集群中的节点有以下几种身份:
- Leader:负责客户端写请求(writer类型的请求)。
- Follower:负责客户端读请求(reader类型的请求),并参与Leader选举。
- Observer:是特殊的Follower节点,可以接收客户端的读请求,但不会参与选举。Observer可以用来扩展系统的读能力,提升读取性能。
Zookeeper的设计理念
Zookeeper是一个基于观察者模式设计的分布式服务管理框架。它负责存储和管理相关数据,并接收观察者的注册。一旦这些数据的状态发生变化,Zookeeper会通知已注册的观察者,以便观察者执行相关操作。
Zookeeper的协议与一致性保障
Zookeeper使用ZAB原子广播协议,节点之间的数据一致性算法采用Paxos算法,能够保障分布式环境中数据的一致性。
ZAB(Zookeeper原子广播协议)
Paxos算法
Paxos算法解决的问题是,如何在分布式系统中就某个值(决议)达成一致。典型的应用场景包括:分布式数据库系统中,如果各节点的初始状态一致,且执行相同的操作序列,则它们最终会得到一致的状态。
为了确保每个节点执行相同的命令序列,需要通过一致性算法来保证每个节点看到的指令一致。Paxos算法就是为了解决分布式系统中的一致性问题,它是基于消息传递模型的一致性算法。
Paxos算法不仅可以用于分布式系统中的一致性保证,也适用于多个进程/线程需要达成一致的场景,包括:
- 一台机器中多个进程/线程的数据一致性
- 分布式文件系统或数据库中的并发读写
- 分布式存储中多个副本响应读写请求的一致性
Zookeeper全解析——Paxos作为灵魂
Zookeeper(ZK)Server最基础的东西是什么呢?我想应该是Paxos。因此,本文将介绍Paxos及其在ZK Server中的实现。
什么是Paxos?
Paxos是一种基于消息传递的一致性算法,由Leslie Lamport于1990年提出,近年来被广泛应用于分布式计算中。Google的Chubby、Apache的Zookeeper都基于Paxos的理论进行实现。Paxos被认为是目前为止唯一成熟的分布式一致性算法,其他算法往往是对Paxos的改进或简化。
需要指出的是,Paxos有一个前提:没有拜占庭将军问题。意思是,Paxos只有在一个可信的计算环境中才能成立,这个环境不应受到入侵或破坏。
Paxos算法的描述
Paxos描述了这样一个场景:有一个叫做Paxos小岛(Island)的地方,岛上住着一批居民,他们的事务由一些特殊的人来决定,这些人被称为议员(Senator)。议员的数量是固定的,不可更改。
岛上的每次事务变更都需要通过提议(Proposal),每个提议都有一个编号(PID),这个编号是递增的,不能倒退。每个提议必须得到超过半数议员的同意才能生效。如果某个议员收到的提议编号小于等于他当前的编号,他会拒绝该提议,并告知对方“你的提议已经有人提过了”。
这个编号是每个议员在自己的记事本上记录的数字,随着时间的推移,议员会更新这个编号,确保提议按照正确的顺序进行。整个议会的目标是:保证所有议员对于提议达成一致的看法。
举个例子
假设岛上有三个议员:S1、S2、S3。
- S1提议将电费设定为1元/度,这时他将提议编号定为1。
- 其他议员收到S1的提议后,查找自己的记事本,发现当前编号为0,所以接受这个提议,并记录编号为1。
- 如果S1收到了超过半数(即2个议员)的同意,他就会宣布“1号提议生效!”
冲突解决
假设S1和S2同时发起了提议:
- S1提议设定电费为1元/度(提议编号为1)。
- S2提议设定电费为2元/度(提议编号也是1)。
S3先收到S1的提议并同意,接着收到S2的提议,但发现S2的提议编号小于等于自己当前的编号,因此拒绝了S2的提议,S1的提议生效。
Paxos在Zookeeper中的应用
现在让我们将Paxos的概念与Zookeeper(ZK Server)中的实现对应起来:
- 小岛(Island)—— Zookeeper集群(ZK Server Cluster)
- 议员(Senator)—— Zookeeper Server节点
- 提议(Proposal)—— ZNode的变更操作(如Create、Delete、SetData等)
- 提议编号(PID)—— Zxid(ZooKeeper事务ID)
- 正式法令 —— 所有ZNode及其数据
尽管概念对得上,但是Zookeeper中有一个特殊角色——Leader。这个角色在Paxos中并不明显,但实际上它是解决“活锁”问题的关键。Paxos的作者Leslie Lamport在《The Part-Time Parliament》中提到,只有一个总统(President)可以发出提议,以避免多个议员同时提议导致的冲突。
总统——ZK Server中的Leader
Zookeeper的Leader角色正是Paxos中的总统。在Zookeeper集群中,Leader负责协调事务的处理并保证一致性,而Follower节点则跟随Leader的决策。
总统选举
总统(Leader)的选举机制是Paxos的一部分,选举过程可能比较复杂,Zookeeper使用Paxos来确保集群中的Leader一致性。你可以阅读相关博客了解更多详细信息:如何选出总统
ZK Server的操作
让我们通过几个情景来更好地理解Zookeeper是如何实施Paxos算法的。
情况一:
- 客户端甲到某个ZK Server询问某条法令的情况(例如ZNode的数据)。ZK Server直接查看本地存储(local storage),并告诉客户端结果。ZK Server会声明:“我的数据不一定是最新的。”如果客户端想要最新的数据,ZK Server会同步到Leader并返回最新结果。
情况二:
- 客户端乙到某个ZK Server请求修改数据(例如ZNode数据)。ZK Server会将该请求提交给Leader,Leader会询问集群中的其他ZK Server的意见。当超过半数的ZK Server同意后,Leader会发布命令,完成数据的修改,ZK Server返回给客户端。
情况三:
- 如果ZK Server的Leader突然挂掉,其他ZK Server会发现无法联系上Leader。此时,ZK集群会启动Leader选举,选举出一个新的Leader。在此期间,客户端请求会被拒绝,直到选举完成。
总结
Paxos是Zookeeper的灵魂,它提供了分布式系统中达成一致性的基础。通过Paxos,Zookeeper保证了在分布式环境下的一致性与容错性。尽管Zookeeper还有其他特性(如Session、Watcher、Version等),但Paxos的核心原理仍然是理解Zookeeper工作的关键。
Zookeeper安装文档
1、上传并解压
上传安装包到master并解压
tar -zxvf apache-zookeeper-3.5.7-bin.tar.gz -C /usr/local/soft
# 重命名
cd /usr/local/soft
mv apache-zookeeper-3.5.7-bin/ zookeeper-3.5.7
2、配置环境变量
vim /etc/profile
# 加入下列内容
ZOOKEEPER_HOME=/usr/local/soft/zookeeper-3.5.7
export PATH=$PATH:$ZOOKEEPER_HOME/bin
# 重新加载环境变量
source /etc/profile
3、修改配置文件
# 切换到配置文件目录
cd /usr/local/soft/zookeeper-3.5.7/conf
# 复制默认配置文件并重命名
cp zoo_sample.cfg zoo.cfg
# 修改配置
vim zoo.cfg
# 找到dataDir并修改
dataDir=/usr/local/soft/zookeeper-3.5.7/data
# 在文件尾部增加
server.0=master:2888:3888
server.1=node1:2888:3888
server.2=node2:2888:3888
4、新建相关目录及文件
cd /usr/local/soft/zookeeper-3.5.7
# 创建ZK数据存放位置
mkdir data
cd data
# 在data目录下创建myid文件
touch myid
5、同步到其它节点
cd /usr/local/soft/
scp -r zookeeper-3.5.7 node1:`pwd`
scp -r zookeeper-3.5.7 node2:`pwd`
6、配置从节点的环境变量
配置node1和node2的环境变量
同步骤2中环境变量配置一致
最后记得source
7、修改myid文件
每台都需修改,并且myid都不同
cd /usr/local/soft/zookeeper-3.5.7/data
vim myid
# master ---> myid --> 0
# node1 ---> myid --> 1
# node2 ---> myid --> 2
8、启动与停止ZK
三台都需要执行
-
启动
zkServer.sh start
-
停止
zkServer.sh stop
-
查看ZK状态
通过jps可以查看zk的进程:QuorumPeerMain
当有一个leader的时候启动成功zkServer.sh status
9、ZK基本操作
zk 是一个目录结构 ,每个节点可以存数据,同时可以有子节点
# 连接ZK
zkCli.sh
# 创建目录
create /test testData
create /test/a aData
# 获取数据
get /test
# 查看目录
ls /test
# 删除节点
delete /test
# 如果节点非空
deleteall /test
10、重置zk
如遇故障,可进行重置
重置将清除ZK中所有数据,慎用!!!
-
杀掉所有zk进程
# 找到ZK的进程编号pid kill -9 {pid}
-
删除数据
删除data目录下的version文件, 所有节点都要删除rm -rf /usr/local/soft/zookeeper-3.5.7/data/version-2
-
重新启动zk
zkServer.sh start
11、配置启停脚本
1.进入脚本运行目录
cd /usr/local/bin
2.创建脚本文件
vim zk
3.添加以下内容:
#!/bin/sh
case $1 in
"start"){
for i in master node1 node2
do
echo "********$i --> zkServer.sh start **********"
ssh $i 'source /etc/profile; /usr/local/soft/zookeeper-3.8.4/bin/zkServer.sh start;exit'
done
};;
"stop"){
for i in master node1 node2
do
echo "********$i --> zkServer.sh stop **********"
ssh $i 'source /etc/profile; /usr/local/soft/zookeeper-3.8.4/bin/zkServer.sh stop;exit'
done
};;
"status"){
for i in master node1 node2
do
echo "********$i --> zkServer.sh status **********"
ssh $i 'source /etc/profile; /usr/local/soft/zookeeper-3.8.4/bin/zkServer.sh status;exit'
done
};;
"restart"){
for i in master node1 node2
do
echo "********$i --> zkServer.sh restart **********"
ssh $i 'source /etc/profile; /usr/local/soft/zookeeper-3.8.4/bin/zkServer.sh restart;exit'
done
};;
esac
4.修改文件权限
chmod 777 zk
5.直接运行
zk start
6.其他命令
zk stop
zk status
zk restart
今天的分享就到这了,之后会分享hbase相关的内容。