掘金 后端 ( ) • 2024-04-26 13:41

theme: scrolls-light

搭建Zookeeper主从运行环境

前言

Zookeeper准确来说没有集群模式,只有主从复制模式,因为每台ZooKeeper服务器中存储的数据都是一样的,master主服务器在ZooKeeper中称为Leader领导者,slave从服务器在ZooKeeper中称为Follower跟随者,Leader服务器会将数据同步复制到Follower服务器中,Leader和Follower中的数据是一样的,所以并不是集群模式,而是主从复制模式。

采用Leader-Follower复制架构建议至少使用3台以上的服务器,并且服务器的数量是奇数,有利于选举Leader。

ZooKeeper不仅可以单机提供服务,同时也支持物理多机组成主从复制架构来提供服务,每台物理机安装一个ZooKeeper服务来搭建主从复制架构是在生产环境下建议使用的。当然也可以在一台物理机上运行多个ZooKeeper实例,但这种方式不建议在生产环境下使用,因为当这台物理机出现宕机时,整体的ZooKeeper服务全部呈失效的状态。

来自客户端的所有写入请求都被转发到Leader服务器,再由Leader服务器向其他的Follower同步数据。

由于服务器数量的原因,本文在1台服务器模拟实现物理主从环境。

1.1 initLimit和syncLimit配置

ZooKeeper主从复制架构有以下两个核心配置选项。

 initLimit=10
 syncLimit=5
  • initLimit:代表主从复制环境中Follower服务器与Leader服务器之间初始连接时能容忍的最多心跳数。

    Follower服务器在启动时,会连接Leader服务器,并从Leader服务器同步所有最新的数据,连接和同步数据的操作是需要时间的。

    如果tickTime=2000,initLimit=10,则说明Leader允许Follower在20秒时间内完成连接和同步数据的工作,2000\times 10=20000毫秒,即20。如果超过20秒,则连接失败。

    通常情况下使用默认配置即可,因为ZooKeeper中不会存储大量数据,ZooKeeper也不是存储大量数据的方案。如果网络传输速度慢,则Follower对Leader进行连接和同步数据的时间也会相应变长,在这种情况下,可以适当调大这个参数值,以增加同步数据所使用的时间。

如果在设定的时间段内,半数以上的Follower未能完成同步,Leader便会宣布放弃Leader地位,进行另一次的Leader选举。

  • syncLimit:代表主从复制环境中的Follower服务器与Leader服务器在请求和响应之间能容忍的最多心跳数。

如果tickTime=2000,syncLimit=5,则syncLimit时间值就是10秒,2000\times 5=10000毫秒。主从复制环境搭建成功后,Leader负责与其他所有的Follower进行通信,包括通过心跳检测机制来检测对方服务器的存活状态。如果Leader向Follower发出心跳包在10秒之后还没有从Follower那里收到响应,则Leader就认为这个Follower已经不在线了,不需要对不在线的Follower同步数据。注意,不要把这个参数设置得过大,否则可能会掩盖一些问题。

常规环境下,这两个值都不需要修改,使用默认值即可。

1.2 创建myid文件及更改cfg配置文件。

安装和配置ZooKeeper的主从复制架构非常简单,在zoo.cfg配置文件中增加两个服务器节点的配置项,示例如下:

 dataDir=/xtt/zookeeper/z_x/dataDir
 clientPort=2181
 server.1=主机IP或虚拟机IP:2881:3881
 server.2=主机IP或虚拟机IP:2882:3882
 server.3=主机IP或虚拟机IP:2883:3883

由于本实验是在一台物理机中模拟多机环境下组成ZooKeeper的主从复制架构,所以使用dataDir属性设置每个ZooKeeper实例的数据和日志文件要存储到不同的位置,防止多个实例之间发生文件覆盖的情况。还要使用clientPort属性设置每个实例使用不同的端口

注意:配置文件zoo.cfg中不要有重复的配置,比如多个clientPort。

多个ZooKeeper的实例如何找到彼此?使用server.X=A:B:C格式进行配置,比如:

 server.1=localhost:2881:3881
 server.2=localhost:2882:3882
 server.3=localhost:2883:3883

选项名server.X代表第X台服务器使用=后面的配置,X值是整数。

模式server.X=A:B:C解释如下:

  • A代表第X台服务器的IP地址或虚拟机IP地址。
  • B表示第X台服务器与Leader服务器交换信息的端口。
  • C表示万一Leader服务器宕机,则第X台服务器就需要C端口在多个Follower之间重新进行选举,选出一个新的Leader,端口C就是用来执行选举时服务器相互通信的端口。

注意,B和C的端口一定不要写成2181,这样会使server port和client port一样,最终日志中会出现异常。

这里我们将Zookeeper的安装文件配置3份即可,分别配置每个的zoo.cfg配置文件,每个zoo.cfg配置文件配置当前ZooKeeper实例的信息。如果是在一台物理机上搭建主从复制环境,则A的值都是一样的,但不同的ZooKeeper实例之间通信端口号不能一样,就要给它们分配不同的端口号。

本实验需要3个ZooKeeper实例,所需需要分别创建3个文件夹,把3个ZooKeeper实例分别放在不同的文件夹中,效果如下

image-20240331211207192

当ZooKeeper启动时候需要根据myid文件确定当前ZooKeeper属于第X台计算机,端口。因此在以下文件夹中分别创建myid文件,无扩展名,里面的值就是server.X中X的值。

 dataDir=/xtt/zookeeper/z_x/dataDir
 dataDir=/xtt/zookeeper/z_y/dataDir
 dataDir=/xtt/zookeeper/z_z/dataDir

ZooKeeperX的myid文件内容如下:

image-20240331211518060

对应server.1

ZooKeeperY的myid文件内容如下:

image-20240331211604940

对应server.2

ZooKeeperZ的myid文件内容如下:

image-20240331211648620

对应server.3

文件myid创建在dataDir文件夹下,该文件里面只有一个数据,就是X的值,ZooKeeper实例启动时会读取这个文件,拿到里面X的值,然后到zoo.cfg配置文件中进行匹配,从而判断是哪个Server服务器。

1.3 启动每个ZooKeeper实例

分别打开3个终端窗口,并进入每个终端窗口中ZooKeeper实例的文件夹,输入zkServer命令,但不要按Enter健,3个终端窗口内容分别如下:

image-20240331212033257

image-20240331212108586

image-20240331212141655

确保当前ZooKeeper实例启动后再到其他的终端窗口中按下Enter键,全部启动后通过ps -ef|grep zookeeper可以看到有3个ZooKeeper进程在系统中进行。

1.4 向Leader中存数据及从Follower中取数据

使用命令:./zkCli.sh -server 127.0.0.1:2181

image-20240331212451425

使用命令:./zkCli.sh -server 127.0.0.1:2182

image-20240331212545791

使用命令:./zkCli.sh -server 127.0.0.1:2183

image-20240331212627668

至此,主从复制架构,也就是Leader-Follower架构环境搭建就结束了。

在ZooKeeper的Leader-Follower架构中,存在“大于半数即存活”的特性,如果整个Leader-Follower架构对外提供的服务可用的话,那么Leader-Follower架构中必须有过半的机器正常工作,并且彼此之间能够正常通信。

1.5 获取ZooKeeper实例的角色

判断实例是Leader还是Follower,需要使用如下命令

 zkServer.sh status

上面的命令需要在不同的ZooKeeper的bin文件夹下执行。

z_x/bin:

image-20240331212951224

z_y/bin:

image-20240331213017768

z_z/bin:

image-20240331213043188

从上图可知,2182端口的ZooKeeper实例为Leader,2181和2183端口的ZooKeeper实例为Follower。

注意:ZooKeeper并不保证从某个ZooKeeper服务中读取的是最新数据,所以需要执行sync命令进行数据的同步。