Zookeeper入门
一、Zookeeper概述
Zookeeper是一个开源的为分布式应用提供协调服务的Apache项目。主要用来解决分布式集群中应用系统的一致性的问题,例如怎样避免同时操作同一数据造成脏读的问题。ZooKeeper 本质上是一个分布式的小文件存储系统。提供基于类似于文件系统的目录树方式的数据存储,并且可以对树种 的节点进行有效管理。从而来维护和监控你存储的数据的状态变化。将通过监控这些数据状态的变化,从而可以达到基于数据的集群管理。诸如:统一命名服务(dubbo)、分布式配置管理(solr的配置集中管理)、分布式消息队列(sub/pub)、分布式锁、分布式协调等功能。
Zookeeper的工作机制可以从设计模式的角度进行理解:是一个基于观察者模式的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接收观察者的注册。一旦数据的状态发生变化,就会通知那些注册了的观察者并作出相应的反应。
本质:文件系统 + 监听通知机制。
- Leader: ZooKeeper 集群工作的核心 事务请求(写操作)的唯一调度和处理者,保证集群事务处理的顺序性;集群内部各个服务的调度者。 对于 create,setData,delete 等有写操作的请求,则需要统一转发给 leader 处理,leader 需要决定编号、执行操作,这个过程称为一个事务。(处理事务请求,更新系统状态;负责投票的发起和决议)
- Follower: 处理客户端非事务(读操作)请求 转发事务请求给 Leader 参与集群 leader 选举投票2n-1台可以做集群投票 此外,针对访问量比较大的 zookeeper 集群,还可以新增观察者角色(处理客户端非事务请求并返回客户端结果,将事务请求转发给Leader;参与选举投票,同步Leader的状态)
- Observer: 观察者角色,观察ZooKeeper集群的最新状态变化并将这些状态同步过来,其对于非事务请求可以进行独立处理,对于事务请求,则会转发给Leader服务器处理 不会参与任何形式的投票只提供服务,通常用于在不影响集群事务处理能力的前提下提升集群的非事务处理能力 。(接收客户端读请求,并将写请求转发给Leader;不参与投票过程,只同步Leader状态;目的仅仅是为了扩展系统,提高读取速度)
- Client:请求发起方。
二、Zookeeper特点
- 全局数据一致:每个 server 保存一份相同的数据副本,client 无论链接到哪个 server,展示的数据都是一致的;
- 可靠性:如果消息被其中一台服务器接受,那么将被所有的服务器接受
- 数据更新原子性:一次数据更新要么成功,要么失败,不存在中间状态;
- 实时性:ZooKeeper 保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息;
- 有序性:更新请求顺序进行,来自同一个Client的更新请求按其发送顺序依次执行;
- 集群中只要有半数以上的节点存活,Zookeeper集群就能正常的服务(因此,集群一般设置为奇数台)。
三、Zookeeper的应用场景
提供的服务包括:统一命名服务、统一配置管理、统一集群管理、服务器节点动态上下线、软负载均衡等。
1、统一命名服务:在分布式的环境下,经常需要对应用/服务进行统一的命名,方便管理识别。例如:IP不容易记住,而域名就更容易记住。
2、统一配置管理:一般要求一个集群中,所有节点的配置信息是一致的。对配置文件修改后,希望能够快速同步到各个节点上。配置管理就可以交给Zookeeper来实现,将配置信息写入Zookeeper上的一个Znode,各个客户端服务器监听这个Znode,一旦Znode中的数据被修改了,Zookeeper1将通知各个客户端服务器。
3、统一集群管理:在分布式环境中,可实时掌握节点的状态并作出相应的调整;实时地在集群和节点状态中加入/离开节点。
4、软负载均衡:在Zookeeper中记录了每台服务器的访问数,让访问数最少的服务器去处理最新的客户端请求。
5、锁定和同步服务:在修改数据的同时锁定数据。此机制可帮助你在连接其他分布式应用程序(如Apache HBase)时进行自动故障恢复。
6、选举算法:选举一个节点作为协调目的的leader。
四、Zookeeper安装配置
官网地址:https://zookeeper.apache.org/
在node01、node02和node02三个节点上部署Zookeeper。
-
在node01节点,解压Zookeeper安装包到/opt/module/目录下
$ tar -zxvf zookeeper-3.5.9-bin.tar.gz -C /opt/module/
-
在/opt/module/zookeeper-3.5.9/这个目录下创建zkData和logs两个文件夹
$ mkdir zkData $ mkdir logs
- 在zkData目录下创建并编辑文件myid
#在文件中添加与server对应的编号: #三个节点分别对应1、2、3 1 #注意:该文件内一定不要有空格
- 配置conf下的zoo.cfg文件
#复制/opt/module/zookeeper-3.4.10/conf这个目录下的zoo_sample.cfg为zoo.cfg $ cp zoo_sample.cfg zoo.cfg #打开文件 #修改数据存储路径配置 dataDir=/opt/module/zookeeper-3.4.10/zkData #添加日志路径 dataLogDir=/opt/module/zookeeper-3.5.9/logs #添加如下集群配置 #server.id=主机host:leader和follower的通信端口:选举leader的端口 server.1=node01:2888:3888 server.2=node02:2888:3888 server.3=node03:2888:3888
-
使用集群分发脚本,将/opt/module/zookeeper-3.5.9/同步分发到node02、node03(集群分发脚本 - 干了这瓶老干妈 - 博客园 (cnblogs.com)),并修改node2、node3中的myid文件。
- 编写Zookeeper集群群启脚本 zk.sh
#!/bin/bash if [ $# -lt 1 ]; then #statements echo "No Args Input..."; exit; fi case $1 in "start") echo "=========================启动zookeeper集群========================" for i in node01 node02 node03; do #statements echo "------------------$i启动服务端----------------------" ssh $i "source /etc/profile;/opt/module/zookeeper-3.5.9/bin/zkServer.sh start" done ;; "stop") echo "=========================关闭zookeeper集群========================" for i in node01 node02 node03; do #statements echo "------------------$i关闭服务端----------------------" ssh $i "source /etc/profile;/opt/module/zookeeper-3.5.9/bin/zkServer.sh stop" done ;; "status") echo "=========================查看zookeeper集群状态=====================" for i in node01 node02 node03; do #statements ssh $i "source /etc/profile;/opt/module/zookeeper-3.5.9/bin/zkServer.sh status" done ;; *) echo "Input Args Error..." ;; esac
- 将 zk.sh 放在/usr/bin/目录下,并添加执行权限
$ sudo chmod +x zk.sh
- 启动脚本
zk.sh start
启动成功后如上图所示。
- 启动Zookeeper客户端
$ bin/zkCli.sh start