写点什么

ZooKeeper 浅析(一)

作者:andy
  • 2022-10-29
    北京
  • 本文字数:4870 字

    阅读完需:约 16 分钟

1-服务器集群问题


服务器集群问题分析

1、集群需求

单节点服务已无法满足大数量用户需求,从而产生了集群服务

对于集群设计而言,最佳的集群服务体验就是,能够让用户在使用服务的过程中,察觉不到服务的某一个环节出现了问题,而能够一如既往顺畅地使用服务。

2、集群问题

集群问题关键在于能否实现高可用

我们知道,对于数据库而言,通常将数据源配置在服务器的文本文件上,从而让服务器能够获取数据库的关键信息(包含地址、端口、用户名以及密码),从而能够访问数据库。但是,一旦其中有一台数据库出现了问题,是不能让服务器再去访问“出问题”的数据库的。有没有什么方式可以解决这样的问题呢?而不是说去更改服务器上的文本文件,从而重新启动容器。

正如熟知的 Nginx 负载均衡容器一样,它可以方便的实现服务器反向代理以及多个服务器的控制,并且通过算法的设计,让各个服务器能够得到合理资源利用。例如其中有一台服务器出错了,那么,就不会让客户端再去访问。

有没有好的解决方案呢?

答案是有的,方案有很多,例如数据库集群。

目前阶段,ZooKeeper 可以作为中间的协调组件进行资源的合理访问策略



2-ZooKeeper


ZooKeeper

Apache ZooKeeper 是一个分布式应用实现高可靠性的分布式协调服务(A Distributed Coordination Service for Distributed Applications),致力于开源服务器能够拥有高依赖分布式的协调性。

ZooKeeper 是一种集中式的服务,用于管理配置信息命名服务提供分布式的同步以及提供组服务

各种应用程序运行着各种不同的服务,而这些服务往往又会碰到 bug 的修复以及不可避免的资源竞争。那么,当需要更新服务时,因为自动化组件的复杂和困难问题,大多数的技术团队选择少用这样的自动化组件。但是,正是因为缺乏使用,反而导致了服务更加困难的管理。

ZooKeeper 便是致力于解决以上问题。通过提取关键信息,使用简单的接口,从而达到集中协调管理这些服务。这些服务往往是分布式和高依赖性的。一致性、组管理以及存在协议被实现,以便用户可以不需要自己进行管理。这些用户只需要添加 ZooKeeper 组件就可以达到目的。

ZooKeeper 数据保存结构



1、文件系统的树形结构

ZooKeeper 数据保存是以分层的文件系统目录树结构(a shared hierarchal namespace)为主。

ZooKeeper 节点被称为 znode,根据节点的层级关系来进行数据保存处理的,其中根节点以“/”标记,根节点下还有各种子节点,各个节点可以进行数据的保存,主要目的是存储同步数据以及描述 znode 的元数据,根节点没有存储数据功能。层级一般建议不超过三层。

每个 znode 可以存储高达 1MB 的数据。节点中保存的都是关键信息,例如服务器地址、端口号、接口名称等等。ZooKeeper 的数据保存在内存之中,便于快速访问。

2、stat 结构

每个 znode 维护一个 stat 结构,一个统计 stat 只是提供一个 znode 元数据,它由版本号,动作控制列表(ACL),时间戳和数据长度组成

  • 版本号:每个 znode 都有一个版本号,这意味着每个相关的时间使用节点改变数据,其相应的版本号也将增加。使用版本号是重要的,通常多个客户端通过相同 znode 执行操作。

  • 动作控制列表(ACL):ACL 是基本的身份验证机制,用于访问 znode。它管理所有的 znode 读写操作。

  • 时间戳:时间戳表示过去时间,从 znode 创建和修改起算。它通常以毫秒表示。ZooKeeper 记录下“事务 ID”(zxid 是独特的)更改 znodes 的时间,使客户端可以轻松地识别从一个请求到另一个请求经过的时间。

  • 数据长度:存储在 znode 的数据大小,每个节点可以存储的最大数据容量为 1MB。


3、Znodes 类型

Znodes 类型分为持久性,顺序和短暂

  • 持久性 znode:持久性 znode 处于活动状态。默认情况下,所有的 znodes 都是持久的,除非另有说明。

  • 短暂 znode:短暂 znodes 活跃,只要客户端还活跃着,节点便一直存在着。当客户端与 ZooKeeper 集合断开连接,随后该类型节点自动删除。基于这一特点,短暂 znodes 不允许再有一个子节点。如果短周期 znode 被删除,那么下一个合适的节点,将填补其位置。短暂 znodes 在领导选举中发挥重要作用。

  • 连续 znode:连续 znodes 可以是持久或短暂的。当一个新的 znode 作为连续 znode 创建的,则 ZooKeeper 通过将 10 位的序列号为原始名称设置 znode 的路径。例如,如果使用路径/myapp 来创建一个 znode 作为连续 znode,ZooKeeper 将改变路径/myapp0000000001 并设置一个序列号为 0000000002。如果两个连续 znodes 同时被创建,在每个 znode 上,ZooKeeper 从来不使用相同数量。连续 znodes 在锁定和同步中起到重要作用。

会话

会话对于 ZooKeeper 操作是非常重要的。请求在会话 FIFO 顺序执行。当一个客户端连接到服务器,会话将建立一个会话 ID 并分配给客户端。

客户端在特定的时间间隔发送心跳来保持会话有效。如果 ZooKeeper 从客户端接收检测信号超过在服务的开始指定的期间(会话超时),它认为该客户死亡。

会话超时通常以毫秒表示。当一个会话因任何原因而结束,该会话期间创造了的短暂 znodes 会被自动删除。


监视

监视是一个简单的机制,在 ZooKeeper 集合通知下以获取客户有关的变化。 客户端可以设置监视,同时读取特定 znode。监视发送通知给注册的客户机对任何 znode(在其上的客户端寄存器)的变化。

节点改变时 znode 或子 znode 变化相关联的数据也会被修改。监视只被触发一次。如果客户想要再次通知,则必须通过另一次读操作来完成。当一个连接会话已过期,客户端会从服务器断开,并在相关的监视也将被删除。

ZooKeeper 特点

  • 顺序一致性:按照客户端发送请求的顺序更新数据;

  • 原子性:数据更新要么成功,要么失败,不会出现部分更新;

  • 单一性:无论连接哪个服务器,都会看到同一个视图,也即各个服务器配置了统一的 ZooKeeper 服务,存储的数据所有 ZooKeeper 节点共享;

  • 可靠性:一旦数据更新成功,将一直保持,直到新的更新;

  • 及时性:客户端会在一个确定的时间内得到最新的数据,更新速度极快。

ZooKeeper 体系结构



ZooKeeper 组件



3-ZooKeeper 工作流


客户端发送请求至集群服务某一结点,如果该节点发送确认,则连接成功,随后,客户端发送心跳至节点,确保连接不丢失。如果客户端没有得到确认,则另外尝试连接新的节点。

领导节点负责写入操作,并控制请求转发;追随节点负责接受领导节点指令,可以直接接受读操作

当 ZooKeeper 集合启动时,它会等待客户端连接。客户端将连接到 ZooKeeper 的集合的其中一个节点。它可能是一个领导者或跟随者节点。

当客户机连接时,该节点分配会话 ID 给特定的客户端,并发送一个确认消息给客户端。如果客户端没有得到确认,它会尝试连接 ZooKeeper 集合的另一个节点。

当连接到一个节点后,客户端将以规则的间隔发送心跳到节点,以确保连接不会丢失。

如果客户想要读取特定的 znode,它发送一个使用 znode 路径节点的读请求,该节点将从其自己的数据库中获取数据返回给客户。基于此,读取在 ZooKeeper 集合中速度非常快。

如果客户希望将数据存储在 ZooKeeper 集合中,它发送 znode 路径和数据到服务器。连接的服务器将请求转发给领导者,领导者将重新发出书面请求到所有的追随者。如果有一个节点成功响应,写请求成功,则一个成功的返回代码发送到客户端。反之,写请求失败。严格意义上,大部分的节点被称为定额。

ZooKeeper 集合的节点

接下来分析 ZooKeeper 集合中不同数量的节点作用。

1、一个节点

当该节点出现故障时,ZooKeeper 集合提供服务失败。该方式有利于单一失败教程,不建议在生产环境中使用。

2、两个节点

一个节点出现故障,此时并没有“多数”,二分之一并不能算是一个大多数。此时集合仍然失败。

3、三个节点

如果有三个节点,其中一个节点发生故障,因为有大多数,因此符合集群最低要求,依然可以使用。也正因为此,ZooKeeper 集合在实际生产环境中至少有三个节点。

4、四个节点

如果有四个节点,其中有当两个节点失败,它类似于有三个节点。额外的节点没有任何作用,因此,最好是单数增加节点,例如,3、5、7。

在 ZooKeeper 集合中,写处理比读过程昂贵,因为所有的节点需要写相同的数据在其数据库中。因此,最好是具有节点(3,5 或 7)比具有大量节点的一个平衡的环境的数量少。




4-领导选举


领导选举

考虑集群中有 N 个节点,领导选举的过程如下:

1、所有节点创建一个顺序,znode 具有相同路径,/app/leader_election/guid_;

2、ZooKeeper 集合将追加 10 位序列号的路径,创造了 znode 将回是/app/leader_election/guid_0000000001、/app/leader_election/guid_0000000002...等;

3、对于给定的实例,它在 znode 创建最小数量的节点成为领导者,所有其他节点成为追随者;

4、每一个追随者节点监控下一个最小号的 znode;

例如,创建/app/leader_election/guid_0000000008 的节点 znode,将监控创建/app/leader_election/guid_0000000007 的节点 znode,创建/app/leader_election/guid_0000000007 的节点 znode,将监控创建/app/leader_election/guid_0000000006 的节点 znode。

5、如果领导停机,接着其对应/app/leader_electionN 的 znode 将被删除;

6、跟随节点接下来将通过观察者得到有关领导去除的通知;

7、跟随节点接下来会检查是否有其他 znodes 用最小数量。如果没有,接着它将承担领导者的角色;否则,它会找到哪些用最小数创造的 znode 作为领导者的节点。

8、同样,其他所有跟随节点选举创造了最小数的 znode 作为领导者的节点。


Paxos 算法

Paxos 算法的本质:在一个信任的环境下,推选领导进行所有 ZooKeeper 节点操作

Paxos 是 Leslie Lamport 于 1990 年提出的一种基于消息传递的一致性算法,解决的问题就是一个分布式系统如何就某个值(决议)达成一致。

前提:没有拜占庭将军问题。所有计算机处于相互之间可信的状态,没有收到外界的入侵,Paxos 算法才能起作用。相互之间的信任,类似于 GIt 使用 SSH。



图 1 拜占庭将军



图 2 拜占庭将军问题


对于 Paxos 算法的实际场景,可以通过以下图片进行理解。



图 3 Paxos 算法提议



图 4 Paxos 算法提议 N 次


一定要有选举机制(多台服务),操作的环境一定是信任的环境。


5-安装


ZooKeeper 安装与配置

对于 ZooKeeper 而言,实际环境中,应用对多台主机下进行集群操作。但是在开发工作中,不可能去部署多台机器。因此,只需要配置一台机器进行开发即可。ZooKeeper 用于分布式集群服务,至少建立 3 个服务形成领导选举机制,也不可能只有一台服务。

1、当前 Linux 系统主机的名称不是 localhost,可能会出现问题,建议修改主机的配置信息。

查看主机名:hostname

编辑文件:vim /etc/sysconfig/network

修改主机名称:HOSTNAME=localhost

修改好主机名称后重启系统:reboot

修改 hosts 配置文件 vim /etc/hosts,追加当前主机名称的配置:

127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4

::1 localhost localhost.localdomain localhost6 localhost6.localdomain6

127.0.1.1 localhost

192.168.6.128 zk-server-01

2、下载 ZooKeeper 开发包,使用 ZooKeeper 开发包,前提是系统安装好 JDK

wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.4.10/zookeeper-3.4.10.tar.gz

3、解压 ZooKeeper 开发包

tar -zxvf zookeeper-3.4.10.tar.gz -C /app/

4、为了方便进行 ZooKeeper 使用,建议将解压后的文件更名

mv /app/zookeeper-3.4.10 /app/zookeeper

5、将 ZooKeeper 可执行命令配置到系统环境属性中

打开环境配置文件:vim /etc/profile

配置以下信息

JAVA_HOME=/app/jdk1.8.0_152

ZK_HOME=/app/zookeeper

JRE_HOME=/app/jdk1.8.0_152/jre

CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib

PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH:$ZK_HOME/bin:

export JAVA_HOME JRE_HOME CLASS_PATH PATH

生效环境配置文件:

source /etc/profile

6、拷贝 ZooKeeper 配置目录下的文件

cp -a /app/zookeeper/conf/zoo_sample.cfg /app/zookeeper/conf/zoo.cfg

7、启动 ZooKeeper 进程服务

/app/zookeeper/bin/zkServer.sh start

8、ZooKeeper 是一个 Java 进程,可以使用 jps 查看进程,进程名称为:QuorumPeerMain

9、查看 ZooKeeper 进程运行状态:

/app/zookeeper/bin/zkServer.sh status

返回结果为:

ZooKeeper JMX enabled by default

Using config: /app/zookeeper/bin/../conf/zoo.cfg

Mode: standalone

没有配置集群环境,当前 ZooKeeper 状态为独立。


用户头像

andy

关注

还未添加个人签名 2019-11-21 加入

还未添加个人简介

评论

发布
暂无评论
ZooKeeper浅析(一)_andy_InfoQ写作社区