当前位置: 首页 > 科技观察

如何搭建高可用的ZooKeeper集群_0

时间:2023-03-17 11:56:31 科技观察

ZooKeeper是Apache的一个顶尖项目,为分布式应用提供高效高可用的分布式协调服务,提供数据发布/订阅、负载均衡、命名服务、分布式等服务协调/通知、分布式锁等分布式基础服务。ZooKeeper由于使用方便、性能优异、稳定性好,被广泛应用于Hadoop、HBase、Kafka、Dubbo等大型分布式系统中。本文的目标读者是对ZooKeeper有一定了解的技术人员。将从ZooKeeper运行方式、集群组成、容灾和水平扩展四个方面逐步深入,最终构建一个高可用的ZooKeeper集群。1.运行模式Zookeeper有三种运行模式:单机模式、伪集群模式和集群模式。1.1单机模式这种模式一般适用于开发和测试环境。一方面,我们没有那么多的机器资源,另一方面,平时的开发调试对稳定性要求不高。要在Linux环境下运行单机模式,需要执行以下步骤:1.准备Java运行环境,安装Java1.6或更高版本的JDK,并配置Java相关的环境变量$JAVA_HOME。2、下载ZooKeeper安装包下载地址:http://zookeeper.apache.org/releases.html。选择最新的稳定版解压到指定目录,我们用$ZK_HOME来表示目录。3.配置zoo.cfg***使用ZooKeeper,需要将$ZK_HOME下的zoo_sample.cfg文件重命名为zoo.cfg,进行如下配置123456tickTime=2000##Zookeeper最小时间unit,单位毫秒(ms),默认值为3000dataDir=/var/lib/zookeeper##Zookeeper服务器存放快照文件的目录,必须配置Zookeeper服务器存储事务日志,默认为dataDirclientPort=2181##服务器的对外服务端口,一般设置为2181initLimit=5##Leader服务器等待Follower启动并完成数据同步的时间,默认值为10,表示10倍的tickTimesyncLimit=2##Leader服务器和Follower的区别心跳检测的最大延迟时间,默认值为5,表示5倍的tickTime4.启动service使用$ZK_HOME/bin目录下的zkServer.sh脚本来启动服务。1.2集群模式一个ZooKeeper集群通常由一组机器组成,一般3台以上的机器可以组成一个可用的ZooKeeper集群。组成ZooKeeper集群的每台机器都在内存中维护当前服务器状态,并且每台机器都保持相互通信。重要的一点是,只要集群中一半以上的机器能够正常工作,整个集群就可以正常对外服务。ZooKeeper的客户端程序会选择与集群中的任意一台服务器建立TCP连接,一旦客户端与服务器断开连接,客户端会自动连接到集群中的其他服务器。那么如何运行ZooKeeper集群模式呢?首先,如果我们有三台服务器,分别是IP1、IP2、IP3,我们需要执行以下步骤:1、准备Java运行环境(同上)2、下载ZooKeeper安装包(同上)3、配置zoo.cfg123456789tickTime=2000dataDir=/var/lib/zookeeperdataLogDir=/var/lib/logclientPort=2181initLimit=5syncLimit=2server.1=IP1:2888:3888服务器.2=IP2:2888:3888server.3=IP3:2888:3888可以看出集群模式相比单机模式多了server.id=host:port1:port2的配置。其中id称为ServerID,用于标识本机在集群中的序号(在每台机器的dataDir目录下创建一个myid文件,文件内容为本机对应的ServerID号)机器)。host为本机IP,port1用于指定Follower服务器与Leader服务器通信和数据同步的端口,port2用于Leader选举过程中的投票通信。4、创建myid文件在dataDir目录下创建一个名为myid的文件,在文件***行写入对应的ServerID。5.其他机器按照同样的步骤配置zoo.cfg和myid文件。6、启动服务1.3伪集群模式这是一种特殊的集群模式,即集群的所有服务器都部署在一台机器上。当你手头有更好的机器时,如果以单机模式部署,会造成资源浪费。在这种情况下,ZooKeeper允许您通过启动不同的端口在一台机器上启动多个ZooKeeper服务实例。这是为了对外提供服务,具有集群的特点。这种模式下,只需要修改zoo.cfg如下:123456789tickTime=2000dataDir=/var/lib/zookeeperdataLogDir=/var/lib/logclientPort=2181initLimit=5syncLimit=2server.1=IP1:2888:3888server.2=IP1:2889:3889server.3=IP1:2890:38902.集群组成要搭建一个高可用的ZooKeeper集群,首先需要确定集群的大小簇。关于ZooKeeper集群的服务器组成,相信很多了解ZooKeeper但没有深入了解的读者都曾或曾经有过这样的误解:为了让ZooKeeper集群能够成功选举出Leader,ZooKeeper集群中服务器的数量必须部署ZooKeeper集群。成奇数。这里需要说明的一点是,任何ZooKeeper服务器都可以正常部署和运行。那么,存在于这么多读者中的这种误解究竟是怎么回事呢?事实上,关于ZooKeeper集群服务器的数量,ZooKeeper官方确实给出了奇数的建议,但大多数ZooKeeper用户对这个建议的理解是有偏差的。在本书前面提到的“过半生存可用”特性中,我们了解到,如果一个ZooKeeper集群要对外提供可用服务,那么集群中必须有过半数的机器正常工作并且可以正常交流。.基于这个特性,如果要搭建一个可以让N台机器宕机的集群,需要部署一个由2*N+1台服务器组成的ZooKeeper集群。所以3台机器组成的ZooKeeper集群在1台机器挂掉后仍然可以正常工作,5台服务器组成的ZooKeeper集群在2台机器挂掉的时候可以进行容灾。注意,如果是6台服务器组成的ZooKeeper集群,只能挂掉2台机器,因为如果挂掉3台机器,剩下的机器无法达到一半以上。所以,从上面的解释中,我们其实可以看出,对于6台机器组成的ZooKeeper集群,和5台机器组成的ZooKeeper集群,在容灾上并没有明显的优势,反而多占用了一台服务器资源。出于这个原因,ZooKeeper集群通常设计为部署奇数个服务器。3、灾难恢复所谓灾难恢复,在IT行业中,通常指的是我们的计算机信息系统在遭受火灾、地震、停电、其他基础网络等毁灭性灾难时,仍能提供可用信息的一种。设备故障。服务能力。对于一些常见的应用,为了满足容灾标准,我们通常会选择部署在多台机器上组成一个集群,这样即使集群中的一台或几台机器出现故障,整个集群仍然可以对外提供可用的服务。对于一些核心应用,不仅需要使用多台机器搭建集群提供服务,还需要将集群中的机器分别部署在两个机房。这样,即使其中一个机房发生灾难,仍然可以提供可用的服务。以上说的都是应用层面的容灾方式,那么ZooKeeper等底层组件如何实现容灾呢?说到这里,可能很多读者会有疑问,既然ZooKeeper解决了单点问题,为什么还需要容灾呢?3.1单点问题单点问题是分布式环境中最常见、最经典的问题之一,在很多分布式系统中都存在这样的单点问题。具体来说,单点问题是指在分布式系统中,如果某个组件出现故障,整个系统的可用性会大大降低甚至瘫痪,那么我们就认为这个组件存在单点问题。ZooKeeper确实很好的解决了单点问题。我们了解到,基于“超过一半”的设计原则,在ZooKeeper运行过程中,集群中至少有一半以上的机器保存了最新的数据。因此,只要集群中一半以上的机器还能正常工作,整个集群就可以对外提供服务。3.2容灾解决了单点问题,要不要考虑容灾?答案是不。构建高可用集群时仍然需要考虑容灾问题。如前所述,如果集群中有一半以上的机器还在正常工作,集群就可以对外提供正常的服务。那么,如果整个机房发生灾难性的事故,此时显然就不是单点的问题了。在设计ZooKeeper的容灾方案的过程中,必须充分考虑“过半原则”。也就是说,无论发生什么情况,我们都必须保证ZooKeeper集群中一半以上的机器能够正常工作。因此,通常有以下两种部署场景。3.3.1双机房部署在设计容灾方案时,我们通常会从机房的角度来考虑问题。现实中很多公司的机房并不大,双机房部署是一种比较常见的方案。但遗憾的是,在目前版本的ZooKeeper中,并没有办法在双机房的情况下达到更好的容灾效果——因为无论哪个机房出现异常,都有可能导致ZooKeeper集群中可用的机器不能超过一半。当然,在有两个机房的场景下,通常一个机房就是主机房(一般来说,公司会花更多的钱去租一个稳定性更好,设备更可靠的机房,而这个机房就是主机房。其他机房便宜)。我们唯一能做的就是在主机房部署尽可能多的机器。比如一个由7台机器组成的ZooKeeper集群,通常4台机器部署在主机房,其余3台机器部署在另一个机房。3.3.2三机房部署由于两机房部署方式无法达到容灾效果,对于有条件的企业来说,选择三机房部署无疑是更好的选择。无论哪一个机房出现故障,剩下的两个机房的机器数量都超过了一半。如果我们有三个机房可以部署服务,这三个机房的网络条件都很好,那么我们可以在这三个机房部署几台机器,组成一个ZooKeeper集群。我们假设组成ZooKeeper集群的机器总数为N,三个机房部署的ZooKeeper服务器数量分别为N1、N2、N3。如果我们想让ZooKeeper集群有更好的容灾能力,我们可以根据下面的算法计算一个ZooKeeper集群的机器部署方案。1、计算N1如果ZooKeeper集群的服务器总数为N,则:1N1=(N-1)/2在Java中,“/”运算符会自动向下取整计算结果。例如,如果N=8,那么N1=3;如果N=7,那么N1也等于3。2.计算N2可选值的计算规则和N1很相似,只是N2的取值在一个取值范围内:1的取值范围N2为1~(N-N1)/2,即如果N=8,则N1=3,则N2的取值范围为1~2,分别为1和2。注意1和2只是N2的可选值,不是最终值——如果N2是可选值,N3的值无法计算,那么可选值也是无效的。3.计算N3并确定N2的值。显然,现在只剩下N3了。可以简单的认为N3的值就是剩余机器的数量,即:1N3=N-N1-N2就是N3的值N3=(n1+n2)){继续;}System.out.println("("+n1+","+n2+","+n3+")");}}}4.水平扩展水平扩展可以说是分布式系统在高可用方面的一个基本且非常重要的需求。水平扩展可以帮助系统没有或几乎没有改进。快速完善系统对外服务支持Capability简单的说,水平扩展就是在集群中增加更多的机器来提高系统的服务质量。不幸的是,ZooKeeper在水平扩展和扩容方面做得不好,需要重启整个集群。重启方式通常有两种,一种是集群整体重启,另一种是逐台重启服务器。4.1整体重启所谓集群整体重启,就是先停止整个集群,然后更新ZooKeeper配置,再重新启动。如果在你的系统中,ZooKeeper不是一个很核心的组件,并且你可以容忍短暂的服务中断(通常是几秒的间隔),那么你不妨选择这种方式。在整个重启过程中,集群的所有客户端都无法连接到集群。当集群再次启动时,这些客户端将能够自动连接-请注意,在整体启动之前建立的客户端会话不会因这次整体重启而失效。即整体重启所花费的时间将不计入会话超时时间的计算。4.2一个一个重启更适合大部分实际场景。这样每次只重启集群中的一台机器,然后整个集群中的机器一台一台重启。这种方式在重启期间仍然可以保证集群对外的正常服务。参考文章:《从Paxos到Zookeeper 分布式一致性原理与实践》