文章目录
- 什么是 Zookeeper
- Zookeeper数据模型
- Zookeeper 应用场景
- 分布式协调
- 分布式锁
- 元数据/配置信息管理
- HA高可用性
- 安装 Zookeeper
- java环境
- standalone 模式
- Quorum 模式
- 目录与配置文件
- Zookeeper主要目录结构
- Zookeeper配置文件
什么是 Zookeeper
Zookeeper是一个分布式开源框架,提供了协调分布式应用的基本服务,它向外部应用暴露一组通用服务——分布式同步(Distributed Synchronization)、命名服务(Naming Service)、集群维护(Group Maintenance)等,简化分布式应用协调及其管理的难度,提供高性能的分布式服务。ZooKeeper本身可以以单机模式安装运行,不过它的长处在于通过分布式ZooKeeper集群(一个Leader,多个Follower),基于一定的策略来保证ZooKeeper集群的稳定性和可用性,从而实现分布式应用的可靠性。
- 1、zookeeper是为别的分布式程序服务的
- 2、Zookeeper本身就是一个分布式程序(只要有半数以上节点存活,zk就能正常服务)
- 3、Zookeeper所提供的服务涵盖:主从协调、服务器节点动态上下线、统一配置管理、分布式共享锁、统一名称服务等
- 4、虽然说可以提供各种服务,但是zookeeper在底层其实只提供了两个功能:
- 管理(存储,读取)用户程序提交的数据(类似namenode中存放的metadata);
- 并为用户程序提供数据节点监听服务;
Zookeeper数据模型
ZooKeeper 的数据模型是层次模型(Google Chubby 也是这么做的)。层次模型常见于文件系统。层次模型和 key-value 模型是两种主流的 数据模型。ZooKeeper 使用文件系统模型主要基 于以下两点考虑:
- 文件系统的树形结构便于表达数据之间的层次关系。
- 文件系统的树形结构便于为不同的应用分配独立的命名空间(namespace)。
ZooKeeper 的层次模型称作 data tree。
- Data tree 的每个节点叫作 znode,并且其有一个唯一的路径标识。
- 节点Znode可以包含数据和子节点(但是EPHEMERAL类型的节点不能有子节点)
- 每个节点都有一个版本 (version)。版本从 0 开始计数。每当节点数据发生变化,那么该节点的版本号会累加(乐观锁)
- 每个ZooKeeper节点存储的数据不宜过大,几k即可。
- 节点可以设置权限acl,可以通过权限来限制用户的访问。
znode 分类:
一个 znode 可以使持久性的,也可以是临时性的:
- 持久性的 znode (PERSISTENT): ZooKeeper 宕机,或者 client 宕机,这个 znode 一旦创建就不会丢失。
- 临时性的 znode (EPHEMERAL): ZooKeeper 宕机了,或者 client 在指定的 timeout 时间内没有连接 server ,都会被认为丢失。
znode 节点也可以是顺序性的。每一个顺序性的 znode 关联一个唯一的单调递增整数。这个单调递增整数是 znode 名字的后缀。如果上面两种 znode 具备顺序性,又有以下两种 znode:
- 持久顺序性的 znode(PERSISTENT_SEQUENTIAL): znode 除了具备持久性 znode 的特点之外,znode 的 名字具备顺序性。
- 临时顺序性的 znode(EPHEMERAL_SEQUENTIAL): znode 除了具备临时性 znode 的特点之外,znode 的名字具备顺序性。
ZooKeeper 主要有以上 4 种 znode。
Zookeeper 应用场景
- 分布式协调
- 分布式锁
- 元数据/配置信息管理
- HA高可用性
分布式协调
假设 A 系统发送请求到 mq,然后 B 系统消息消费之后处理完毕。那 A 系统如何知道 B 系统的处理结果?用 zookeeper 就可以实现分布式系统之间的协调工作。A 系统发送请求之后可以在 zookeeper 上对某个节点的值注册个监听器,一旦 B 系统处理完了就修改 zookeeper 那个节点的值,A 系统立马就可以收到通知。
分布式锁
对某一个数据连续发出两个修改操作,两台机器同时收到了请求,但是只能一台机器先执行完另外一个机器再执行。那么此时就可以使用 zookeeper 分布式锁,一个机器接收到了请求之后先去 zookeeper 创建一个 znode,接着执行操作;然后另外一个机器也尝试去创建那个 znode,结果发现自己创建不了,因为被别人创建了,那只能等着,等第一个机器执行完了自己再执行。
元数据/配置信息管理
zookeeper 可以用作很多系统或者微服务集中化的配置信息的管理,比如 kafka、storm 等等很多分布式系统都会选用 zookeeper 来做一些元数据、配置信息的管理,包括 dubbo 注册中心也支持 zookeeper。
HA高可用性
比如 hadoop、hdfs、yarn 等很多大数据系统,都选择基于 zookeeper 来开发 HA 高可用机制,就是一个重要进程一般会做主备两个,主进程挂了立马通过 zookeeper 感知到切换到备用进程。
ZooKeeper 适用于存储 和协同相关 的关键数据,不适合用于大数据量存储。
安装 Zookeeper
java环境
zookeeper必须要有jdk环境,比如oracle的jdk,下载地址:jdk-8u281-linux-x64.tar.gz
顺带一提,现在下载jdk还必须登录,若是嫌麻烦,也可以从我的网盘下载:
链接: https://pan.baidu.com/s/1xHl6_Y2et7ueRILVpVNG5w 提取码: tr32
java配置:
export JAVA_HOME=/opt/jdk
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
运行以下使配置生效:
source /etc/profile
其余过程不再赘述。
standalone 模式
- 到官网下载 Zookeeper,目前最新版:apache-zookeeper-3.6.2
- 解压到你常用的安装目录,比如:/opt/
mv apache-zookeeper-3.6.2-bin.tar.gz /opt/
tar -xvf apache-zookeeper-3.6.2-bin.tar.gz
mv apache-zookeeper-3.5.5-bin zookeeper
- 复制配置文件并修改数据存储目录
cd /opt/zookeeper/conf
cp zoo_sample.cfg zoo.cfg
vim zoo.cfg
注意同时在zookeeper创建data目录
- 配置环境变量
vim /etc/profile
export ZOOKEEPER_HOME=/opt/zookeeper
export PATH=${JAVA_HOME}/bin:${ZOOKEEPER_HOME}/bin:$PATH
运行以下使配置生效
source /etc/profile
启动 Zookeeper
- 使用 zkServer.sh start 启动 ZooKeeper 服务。
- 检查 ZooKeeper 日志是否有出错信息。
- 检查 ZooKeeper 数据文件。
- 检查 ZooKeeper 是否在 2181 端口上监听。
Quorum 模式
处于 Quorum 模式的 ZooKeeper 集群包含多个 ZooKeeper 节点。
下图的 ZooKeeper 集群有 3 个 节点,其中节点 1 是 leader 节点,节点 2 和节点 3 是 follower 节点。
leader 节点可以处理读写 请求,follower 只可以处理读请求。 follower 在接到写请求时会把写请求转发给leader来处理。
部署步骤:
- 修改配置文件, 在zoo.cfg最后面添加:
server.0=c1:2888:3888
server.1=c2:2888:3888
server.2=c3:2888:3888
- 创建服务器标识
在data目录下,新建文件 myid,内容为0 - 复制zookeeper
进行复制zookeeper目录到c1机器和c2机器
并且配置c1机器和c2机器的/etc/profile文件
把c1机器和c2机器中的myid文件里的值修改为1和2,路径(vi /opt/zookeeper/data/myid
) - 启动zookeeper
zkServer.sh start (注意这里3台机器都要进行启动)
常用命令
zkServer.sh start 启动服务
zkServer.sh status 查询状态
zkServer.sh stop 停止服务
目录与配置文件
Zookeeper主要目录结构
- bin: 主要的一些运行命令。
- conf:存放配置文件,其中我们运行zookeeper之前需要修改zk.cfg。
- zookeeper-contrb:附加的一些功能。
- dist-maven:mvn编译后的目录,包含写jar包及pom文件
- zookeeper-docs:文档
- lib:需要依赖的jar包
- recipes:案例demo代码
Zookeeper配置文件
# 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=/home/myuser/zooA/data
dataLogDir=/home/myuser/zooA/log
# the port at which the clients will connect
clientPort=2181
# ZooKeeper server and its port no. # ZooKeeper ensemble should know about every other machine in the ensemble # specify server id by creating 'myid' file in the dataDir # use hostname instead of IP address for convenient maintenance
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2988:3988
server.3=127.0.0.1:2088:3088
- tickTime:心跳时间,以毫秒为单位,最小超时时间为两个心跳时间。
- initLimit:多少个心跳时间内,允许其他server连接并初始化数据,如果ZooKeeper管理的数据较大,则应相应增大这个值。(用于集群,允许从节点连接并同步到master节点的初始化连接时间,以tickTime的倍数来表示)。
- clientPort:服务的监听端口(连接服务器的端口,默认2181)。
- dataDir:必须配置,用于存放内存数据库快照的文件夹,同时用于集群的myid文件也存在这个文件夹里(注意:一个配置文件只能包含一个dataDir字样,即使它被注释掉了。)
- dataLogDir:日志目录,用于单独设置transaction log的目录,transaction log分离可以避免和普通log还有快照的竞争,如果不配做会和dataDir公用。
- syncLimit:多少个tickTime内,允许follower同步,如果follower落后太多,则会被丢弃。(用于集群,master主节点与从节点之间发送消息,请求和应答时间长度,以tickTime的倍数来表示。心跳机制)
- server.A=B:C:D:
- A是一个数字,表示这个是第几号服务器,
- B是这个服务器的ip地址
- C集群成员的信息交换,表示的是这个服务器与集群中的Leader服务器交换信息的端口
- D是在leader挂掉时专门用来选举leader