20200808 linux搭建zookeeper集群

搭建zookeeper集群(一主两从)

zk启动依赖java的JDK,所以要先安装JDK

不会安装JDK的可以看这https://www.jianshu.com/p/ea5c72b273d7教程,安装完成JDK后

下载zk的tar包并使用winSCP上传到3台linux服务器

https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/

开始搭建zookeeper集群(一主两从)

我启动了3台linux服务器,IP分别是

192.168.79.135、192.168.79.136、192.168.79.137

操作192.168.79.135服务器

执行linux命令解压zk

tar -zxvf zookeeper-3.4.14.tar.gz

解压后多了zookeeper-3.4.14文件夹,进行到zk的conf目录

cd zookeeper-3.4.14/conf/

image

可以查看到zoo_sample.cfg配置文件,把这个配置文件copy一份并重命名为zoo.cfg

cp zoo_sample.cfg zoo.cfg

修改zoo.cfg配置文件的日志目录datadir(后面创建myid要在这个目录下)

vi zoo.cfg

image

启动看是否安装正常,在zookeeper-3.4.14目录执行

启动

bin/zkServer.sh start

查看是否启动成功

ps -ef|grep zookeeper或者netstat -nltp | grep 2181查看是否启动成功

image

检查启动成功

先关闭zk

bin/zkServer.sh stop

另外两台服务器也执行以上同样的操作↑

以上操作安装好单机的zk,现在开始搭建zk集群 一leader两follower

三台****服务器都修改配置文件

1.打开配置文件,

vi zoo.cfg

****2.在最后加上****

server.1=192.168.79.135:2888:3888

server.2=192.168.79.136:2888:3888

server.3=192.168.79.137:2888:3888

image

三台机器都修改完配置后

操作192.168.79.135服务器

在之前配置的dataDir目录(我配置在这个目录下/data/zookeeper-3.4.14/data),第一次zk就会创建这个目录(也可以手动创建),在这个目录下新建myid文本

vi myid

文本里面写上 **** 1

image

保存

wq!

操作192.168.79.136服务器

也是在dataDir(日志目录)下创建myid文本****

vi myid

文本里面写上 **** 2

image

操作192.168.79.137服务器

也是在dataDir(日志目录)下创建myid文本****

vi myid

文本里面写上 **** 3

image

配置完成后,关闭防火墙systemctl stop firewalld

启动3台服务器的zk,启动后

./zkServer.sh status查询zk节点

192.168.79.135节点信息Mode: leader

image

192.168.79.136节点信息Mode: follower

image

192.168.79.137节点信息Mode: follower

image

第一次启动,myid最小的选举为leader
下面操作看创建节点之后,其他zk就否会同步

bin/zkCli.sh ****启动zk客户端

ls /****查询zk根目录下的节点

image

192.168.79.135创建一个node1节点,看其他zk节点是否能同步

create /node1 1

image

查询192.168.79.136的zk节点服务

image

查询192.168.79.137的zk节点服务

 

image

 

192.168.79.136的zk创建node2节点,发现followerzk也能创建节点,并且其他zk也都能同步数据。

**kill 192.168.79.135的zk后,192.168.79.137的zk选举成了leader

我们在192.168.79.137创建一个node3节点再重新启动192.168.79.135的zk

image

重启后变成了follower节点

image

******在zk重启之前创建的node3节点也能同步过来******

******3台zk如果挂掉一台还能正常使用,如果挂掉2台,正常的那台zk也不能使用了,要等其中至少1台zk启动后才能恢复正常(必须要一半或以上的zk服务正常才能运行)。******

测试:

 

将两台follower关闭

./zkServer.sh stop

查询没有关闭的zk(leader)的status状态,发现not running,不能正常使用

image

现在恢复启动一台刚刚关闭的zk

再查询没有关闭的zk(leader)的status状态

 

image

发现从leader变成了follower

**测试完成。结论:集群必须要一半或以上的zk服务正常才能运行集群,并且最后一台没有挂掉的如果是leader,集群恢复正常后,可能就不是leader了

测试集群搭建成功

下面说说集合的配置作用:

server.1=192.168.79.135:2888:3888的意思

****server.id=host:port1:port2****

id 是一个数字,表示这个是第几号服务器(与myid的值相同)。

****host ****是这个服务器的 ip 地址。**

****port1 ******表示这个服务器与集群中的Leader服务器交换信息的端口。**

****port2******表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。**

****myid文件******该文件创建在zoo.cfg里dataDir指定的目录下,只有一行内容,对应每台机器的Server ID 数字;比如server.1 的myid 文件内容就是1【必须确保每个服务器的myid 文件中的数字不同,并且****和自己所在机器的zoo.cfg 中server.id 的id 值一致,id 的范围是1~255】

集群角色

**Leader 角色 **
Leader 服务器是整个 zookeeper 集群的核心,主要的工作 任务有两项 1. 事物请求的唯一调度和处理者,保证集群事物处理的顺 序性
2. 集群内部各服务器的调度者

**Follower 角色 **
Follower 角色的主要职责是
1. 处理客户端非事物请求、转发事物请求给 leader 服务器
2. 参与事物请求 Proposal 的投票(需要半数以上服务器 通过才能通知 leader commit 数据; Leader 发起的提案, 要求 Follower 投票)
3. 参与 Leader 选举的投票

**Observer 角色 **
Observer 是 zookeeper3.3 开始引入的一个全新的服务器 角色,从字面来理解,该角色充当了观察者的角色。 观察 zookeeper 集群中的最新状态变化并将这些状态变化 同步到 observer 服务器上。Observer 的工作原理与 follower 角色基本一致,而它和 follower 角色唯一的不同 在于 observer 不参与任何形式的投票,包括事物请求 Proposal的投票和leader选举的投票。简单来说,observer 服务器只提供非事物请求服务,通常在于不影响集群事物 处理能力的前提下提升集群非事物处理的能力 。

*集群组成 **
通常 zookeeper是由2n+1台server组成,每个server都知道彼此的存在。对于2n+1台server,只要有n+1台(大多数server可用,整个系统保持可用。我们已经了解到,一个 zookeeper 集群如果要对外提供可用的服务,那么集 群中必须要有过半的机器正常工作并且彼此之间能够正常 通信,基于这个特性,如果搭建一个能够允许F台机器down掉的集群,那么就要部署2
F+1台服务器构成的 zookeeper 集群。因此3台机器构成的 zookeeper 集群,能够在挂掉一台机器后依然正常工作。一个5 台机器集群 的服务,能够对2台机器挂掉的情况下进行容灾。如果一台由6台服务构成的集群,同样只能挂掉2台机器。因此,5台和6台在容灾能力上并没有明显优势,反而增加了网络通信负担。系统启动时,集群中的server 会选举出一台server为Leader,其它的就作为follower(这里先不考虑 observer角色)。
之所以要满足这样一个等式,是因为一个节点要成为集群中的leader,需要有超过及群众过半数的节点支持,这个涉及到leader选举算法。同时也涉及到事务请求的提交投票

zookeeper的集群工作
在zookeeper中,客户端会随机连接到zookeeper集群中的一个节点,****如果是读请求,就直接从当前节点中读取数据,如果是写请求,那么请求会被转发给 leader 提交事务,然后 leader 会广播事务,只要有超过半数节点写入成功,那么写请求就会被提交(类 2PC 事务)所有事务请求必须由一个全局唯一的服务器来协调处理****,这个服务器就是Leader服务器,其他的服务器就是follower。

leader服务器把客户端的失去请求转化成一个事务Proposal(提议),并把这个Proposal分发给集群中的所有 Follower 服务器。之后Leader服务器需要等待所有Follower 服务器的反馈,****一旦超过半数的 Follower 服务器 进行了正确的反馈,那么 Leader 就会再次向所有的 Follower 服务器发送 Commit 消息****,要求各个 follower 节点对前面的一个 Proposal 进行提交;**


+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥

说到分布式开发Zookeeper是必须了解和掌握的,分布式消息服务kafka 、hbase 到hadoop等分布式大数据处理都会用到Zookeeper,所以在此将Zookeeper作为基础来讲解。

   Zookeeper 是分布式服务框架,主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等等。

Zookeeper 的核心是广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。

Zab协议有两种模式,它们分别是恢复模式(选主)和广播 模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后, 恢复模式就结束了。

状态同步保证了leader和Server具有相同的系统状态。为了保证事务的顺序一致性,zookeeper采用了递增的事务id号 (zxid)来标识事务。

所有的提议(proposal)都在被提出的时候加上了zxid。实现中zxid是一个64位的数字,它高32位是epoch用 来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的统治时期。低32位用于递 增计数。

每个Server在工作过程中有三种状态:

LOOKING:当前Server不知道leader是谁,正在搜寻。

LEADING:当前Server即为选举出来的leader。

FOLLOWING:leader已经选举出来,当前Server与之同步。

 

  ZooKeeper的安装模式分为三种,分别为:单机模式、集群模式和集群伪分布模式

环境

  CentOS7.0  (windows中使用就使用zkServer.cmd)

  ZooKeeper最新版本

  用root用户安装(如果用于hbase时将所有文件权限改为hadoop用户)

     Java环境,最好是最新版本的。

分布式时多机间要确保能正常通讯,关闭防火墙或让涉及到的端口通过。

下载

  去官网下载 :http://zookeeper.apache.org/releases.html#download

  下载后放进CentOS中的/usr/local/ 文件夹中,并解压到当前文件中 /usr/local/zookeeper(怎么解压可参考之前的Haproxy的安装文章)

安装

单机模式

  进入zookeeper目录下的conf子目录, 重命名 zoo_sample.cfg文件,Zookeeper 在启动时会找这个文件作为默认配置文件:

mv /usr/local/zookeeper/conf/zoo_sample.cfg  zoo.cfg

  配置zoo.cfg参数

# 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=/usr/local/zookeeper/data
dataLogDir=/usr/local/zookeeper/log
# the port at which the clients will connect
clientPort=2181
# Be sure to read the maintenance section of the 
# administrator guide before turning on autopurge.
#
#http://zookeeper.apache.org/doc/current/zookeeperAdmin.html
#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1


参数说明:
tickTime:毫秒值.这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
dataDir:顾名思义就是 Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。
dataLogDir:顾名思义就是 Zookeeper 保存日志文件的目录
clientPort:这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。

  再创建上面配置的data和log文件夹:

mkdir  /usr/local/zookeeper/data

mkdir  /usr/local/zookeeper/log

启动zookeeper

  先进入/usr/local/zookeeper文件夹

cd /usr/local/zookeeper

  再运行 

bin/zkServer.sh start

  检测是否成功启动:执行

bin/zkCli.sh

echo stat|nc localhost 2181

 

 伪集群模式

所谓伪集群, 是指在单台机器中启动多个zookeeper进程, 并组成一个集群. 以启动3个zookeeper进程为例,模拟3台机。

将zookeeper的目录多拷贝2份:

zookeeper/conf/zoo.cfg文件与单机一样,只改为下面的内容:

tickTime=2000
initLimit=5
syncLimit=2
dataDir=/usr/local/zookeeper/data
dataLogDir=/usr/local/zookeeper/log
clientPort=2180
server.0=127.0.0.1:2888:3888
server.1=127.0.0.1:2889:3889
server.2=127.0.0.1:2890:3890

新增了几个参数, 其含义如下:

1 initLimit: zookeeper集群中的包含多台server, 其中一台为leader, 集群中其余的server为follower. initLimit参数配置初始化连接时, follower和leader之间的最长心跳时间. 此时该参数设置为5, 说明时间限制为5倍tickTime, 即5*2000=10000ms=10s.

2 syncLimit: 该参数配置leader和follower之间发送消息, 请求和应答的最大时间长度. 此时该参数设置为2, 说明时间限制为2倍tickTime, 即4000ms.

3 server.X=A:B:C 其中X是一个数字, 表示这是第几号server. A是该server所在的IP地址. B配置该server和集群中的leader交换消息所使用的端口. C配置选举leader时所使用的端口. 由于配置的是伪集群模式, 所以各个server的B, C参数必须不同.

参照zookeeper/conf/zoo.cfg, 配置zookeeper1/conf/zoo.cfg, 和zookeeper2/conf/zoo.cfg文件. 只需更改dataDir, dataLogDir, clientPort参数即可.

在之前设置的dataDir中新建myid文件, 写入一个数字, 该数字表示这是第几号server. 该数字必须和zoo.cfg文件中的server.X中的X一一对应.

/usr/local/zookeeper/data/myid文件中写入0, /usr/local/zookeeper1/data/myid文件中写入1, /Users/apple/zookeeper2/data/myid文件中写入2.

  分别进入/usr/local/zookeeper/bin, /usr/local/zookeeper1/bin, /usr/local/zookeeper2/bin三个目录, 启动server。启动方法与单机一致。

bin/zkServer.sh start

  分别检测是否成功启动:执行

bin/zkCli.sh

echo stat|nc localhost 2181

 

集群模式

集群模式的配置和伪集群基本一致.

由于集群模式下, 各server部署在不同的机器上, 因此各server的conf/zoo.cfg文件可以完全一样.

下面是一个示例:

tickTime=2000
initLimit=5
syncLimit=2
dataDir=/usr/local/zookeeper/data
dataLogDir=/usr/local/zookeeper/log
clientPort=2180
server.0=192.168.80.30:2888:3888
server.1=192.168.80.31:2888:3888
server.2=192.168.80.32:2888:3888

 

示例中部署了3台zookeeper server, 分别部署在192.168.80.30, 192.168.80.31, 192.168.80.32上. 

需要注意的是, 各server的dataDir目录下的myid文件中的数字必须不同,192.168.80.30 server的myid为0, 192.168.80.31 server的myid为1, 192.168.80.32 server的myid为2

  分别进入/usr/local/zookeeper/bin目录, 启动server。启动方法与单机一致。

bin/zkServer.sh start

  分别检测是否成功启动:执行

bin/zkCli.sh

echo stat|nc localhost 2181

   这时会报大量错误?其实没什么关系,因为现在集群只起了1台server,zookeeper服务器端起来会根据zoo.cfg的服务器列表发起选举leader的请求,因为连不上其他机器而报错,那么当我们起第二个zookeeper实例后,leader将会被选出,从而一致性服务开始可以使用,这是因为3台机器只要有2台可用就可以选出leader并且对外提供服务(2n+1台机器,可以容n台机器挂掉)。

 

ZooKeeper服务命令

1. 启动ZK服务: zkServer.sh start2. 查看ZK服务状态: zkServer.sh status3. 停止ZK服务: zkServer.sh stop4. 重启ZK服务: zkServer.sh restart

 

zk客户端命令:

  ZooKeeper 命令行工具类似于Linux的shell环境,使用它可以对ZooKeeper进行访问,数据创建,数据修改等操作.

  使用 zkCli.sh -server 192.168.80.31:2181 连接到 ZooKeeper 服务,连接成功后,系统会输出 ZooKeeper 的相关环境以及配置信息。命令行工具的一些简单操作如下:

1. 显示根目录下、文件: ls / 使用 ls 命令来查看当前 ZooKeeper 中所包含的内容

2. 显示根目录下、文件: ls2 / 查看当前节点数据并能看到更新次数等数据

3. 创建文件,并设置初始内容: create /zk"test" 创建一个新的 znode节点“ zk ”以及与它关联的字符串

4. 获取文件内容: get /zk 确认 znode 是否包含我们所创建的字符串

5. 修改文件内容: set /zk"zkbak" 对 zk 所关联的字符串进行设置

6. 删除文件: delete /zk 将刚才创建的 znode 删除

7. 退出客户端: quit

8. 帮助命令: help

 

 扩展

  通过上述命令实践,我们可以发现,zookeeper使用了一个类似文件系统的树结构,数据可以挂在某个节点上,可以对这个节点进行删改。另外我们还发现,当改动一个节点的时候,集群中活着的机器都会更新到一致的数据。 

zookeeper的数据模型

在简单使用了zookeeper之后,我们发现其数据模型有些像操作系统的文件结构,结构如下图所示

(1)     每个节点在zookeeper中叫做znode,并且其有一个唯一的路径标识,如/SERVER2节点的标识就为/APP3/SERVER2

(2)     Znode可以有子znode,并且znode里可以存数据,但是EPHEMERAL类型的节点不能有子节点

(3)     Znode中的数据可以有多个版本,比如某一个路径下存有多个数据版本,那么查询这个路径下的数据就需要带上版本。

(4)     znode 可以是临时节点,一旦创建这个 znode 的客户端与服务器失去联系,这个 znode 也将自动删除,Zookeeper 的客户端和服务器通信采用长连接方式,每个客户端和  服务器通过心跳来保持连接,这个连接状态称为 session,如果 znode 是临时节点,这个 session 失效,znode 也就删除了

(5)     znode 的目录名可以自动编号,如 App1 已经存在,再创建的话,将会自动命名为 App2

(6)     znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的集中管理,集群管理,分布式锁等等。

 选举流程

当 leader崩溃或者leader失去大多数的follower,这时候zk进入恢复模式,恢复模式需要重新选举出一个新的leader,让所有的 Server都恢复到一个正确的状态。Zk的选举算法有两种:一种是基于basic paxos实现的,另外一种是基于fast paxos算法实现的。系统默认的选举算法为fast paxos。

basic paxos流程:

1 .选举线程由当前Server发起选举的线程担任,其主要功能是对投票结果进行统计,并选出推荐的Server;

2 .选举线程首先向所有Server发起一次询问(包括自己);

3 .选举线程收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中;

4. 收到所有Server回复以后,就计算出zxid最大的那个Server,并将这个Server相关信息设置成下一次要投票的Server;

5. 线程将当前zxid最大的Server设置为当前Server要推荐的Leader,如果此时获胜的Server获得n/2 + 1的Server票数, 设置当前推荐的leader为获胜的Server,将根据获胜的Server相关信息设置自己的状态,否则,继续这个过程,直到leader被选举出来。

通 过流程分析我们可以得出:要使Leader获得多数Server的支持,则Server总数必须是奇数2n+1,且存活的Server的数目不得少于 n+1.每个Server启动后都会重复以上流程。在恢复模式下,如果是刚从崩溃状态恢复的或者刚启动的server还会从磁盘快照中恢复数据和会话信 息,zk会记录事务日志并定期进行快照,方便在恢复时进行状态恢复。

应用场景

   是指通过指定的名字来获取资源或者服务的地址,提供者的信息。利用Zookeeper很容易创建一个全局的路径,而这个路径就可以作为一个名字,它可以指向集群中的集群,提供的服务的地址,远程对象等。简单来说使用Zookeeper做命名服务就是用路径作为名字,路径上的数据就是其名字指向的实体。

  阿里巴巴集团开源的分布式服务框架Dubbo中使用ZooKeeper来作为其命名服务,维护全局的服务地址列表。在Dubbo实现中:

服务提供者在启动的时候,向ZK上的指定节点/dubbo/${serviceName}/providers目录下写入自己的URL地址,这个操作就完成了服务的发布。

服务消费者启动的时候,订阅/dubbo/{serviceName}/providers目录下的提供者URL地址, 并向/dubbo/{serviceName} /consumers目录下写入自己的URL地址。

  注意,所有向ZK上注册的地址都是临时节点,这样就能够保证服务提供者和消费者能够自动感应资源的变化。

  另外,Dubbo还有针对服务粒度的监控,方法是订阅/dubbo/{serviceName}目录下所有提供者和消费者的信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值