Zookeeper新手指南

空心菜 发表了文章 0 个评论 77 次浏览 2021-03-27 22:41 来自相关话题

目标今天,我们将开始迈向Apache ZooKeeper的新旅程。在这个ZooKeeper教程中,我们将看到Apache ZooKeeper的含义以及ZooKeeper的流行度。此外,我们将了解ZooKeeper 的功能,优点,应用和用 ...查看全部

目标

今天,我们将开始迈向Apache ZooKeeper的新旅程。在这个ZooKeeper教程中,我们将看到Apache ZooKeeper的含义以及ZooKeeper的流行度。此外,我们将了解ZooKeeper 的功能,优点,应用和用例。此外,我们将讨论不同的术语,如ZooKeeper Client,ZooKeeper Cluster,ZooKeeper WebUI。除此之外,Apache ZooKeeper教程将为使用ZooKeeper的原因提供答案。此外,我们将看到使用ZooKeeper的公司。最后,我们将看到Apache ZooKeeper架构。


由于ZooKeeper本质上是分布式的,因此在进一步研究之前,了解分布式应用程序的一两件事非常重要。因此,首先,我们将看到ZooKeeper讨论,快速介绍分布式应用程序。


那么,让我们开始Apache ZooKeeper教程。

什么是分布式应用程序?

为了以快速有效的方式完成特定任务,分布式应用程序可以在给定时间(同时)在网络中的多个系统上运行。它们可以通过中间协调来实现。此外,我们可以说,通过使用所涉及的所有系统的计算能力,复杂且耗时的任务(需要数小时才能完成非分布式应用程序(在单个系统中运行))可以在几分钟内通过帮助完成分布式应用程序。


此外,通过将分布式应用程序配置为在更多系统上运行,可以进一步减少完成任务的时间。有一个集群,它基本上是一组运行分布式应用程序的系统。在集群中有机器在运行,那些在集群中运行的机器就是我们所说的节点。


通常,服务器和客户端应用程序是分布式应用程序的两个部分。定义两者:


服务器端应用
具有通用接口的分布式应用程序就是我们所说的服务器端应用程序。基本上,它确保客户端可以连接到群集中的任何服务器并获取相同的结果。

客户端应用
有助于与分布式应用程序交互的工具就是我们所说的客户端应用程序。

分布式应用的好处
a.可靠性
如果一个或几个系统发生故障,则不会使整个系统失效。

b.可伸缩性
通过添加更多的机器,只需对应用程序的配置进行少量更改,而无需停机,就可以根据需要提高性能。

c.透明度
这仅仅意味着它隐藏了系统的复杂性。而且,它显示自己是一个单独的实体/应用程序。

分布式应用程序的挑战
1.竞争条件
有时有两个或更多的机器试图执行一个特定的任务,即使当任务实际上只需要在任何给定的时间由一台机器来完成。

2.死锁
为了无限期地完成,两个或多个操作等待彼此。

3.不一致
这意味着数据部分失效。

什么是ZooKeeper?

我们称之为ZooKeeper的分布式协调服务也有助于管理大量主机。由于特别是在分布式环境中管理和协调服务是一个复杂的过程,因此ZooKeeper由于其简单的架构和API而解决了这个问题。ZooKeeper是最好的,不用担心应用程序的分布式特性,它允许开发人员专注于核心应用程序逻辑。


最初,为了以简单而强大的方式访问应用程序,ZooKeeper框架最初是在“Yahoo!”上构建的。但在此之后,为了组织Hadoop,HBase和其他分布式框架所使用的服务,Apache ZooKeeper成为了标准。例如,要跟踪分布式数据的状态,Apache HBase使用ZooKeeper。


此外,它们还可以轻松支持大型Hadoop集群。为了检索信息,每个客户机与其中一个服务器通信。但是,在过去,大多数工作都需要在实现分布式应用程序时修复错误。虽然我们可以说,实现中的这些各种困难是创建ZooKeeper背后的主要原因。因为它简明扼要地关注整个集群的同步和协调。


Zookeeper受众

那些希望通过使用ZooKeeper框架在大数据分析领域开展事业的专业人士可以参考这个Zookeeper序列文章。因为这个Apache ZooKeeper序列教程文章将详细介绍如何使用ZooKeeper创建分布式集群。


Zookeeper运行先决条件

虽然,在继续使用这个ZooKeeper教程之前,必须对Java有一个很好的理解,因为它的服务器运行在JVM,分布式进程以及Linux环境中。


Zookeeper的功能

有一些最好的Apache ZooKeeper功能,这使它从人群中脱颖而出:

  • 简单
    在共享的分层命名空间的帮助下,它进行协调。

  • 可靠性
    即使多个节点发生故障,系统也会继续运行。

  • 速度
    在“读取”更常见的情况下,它以10:1的比例运行。

  • 可扩展性
    通过部署更多集群节点,可以提高性能。

ZooKeeper教程设计

下面,我们将讨论Apache ZooKeeper的一些设计目标:

a. Zookeeper是简单的
在使用ZooKeeper时,所有分布式进程都可以相互协调。这种协调可以通过共享的分层命名空间实现。但是,它的组织方式与标准文件系统相同。这里的命名空间由数据寄存器组成,我们称之为znodes,用ZooKeeper的说法。但是,这些与文件和目录相同。此外,ZooKeeper数据保留在内存中,因为它实现了高吞吐量和低延迟数量。

b. Zookeeper支持复制
Apache ZooKeeper本身旨在通过一组称为集合的主机进行复制,就像它协调的分布式进程一样。

c. 如何让Zookeeper顺序一致性更有效?
为了实现更高级别的抽象(同步原语,后续操作),需要使用顺序一致性。

d. Zookeepr很快
特别是,在“读取占优势”的工作负载中,ZooKeeper的工作速度非常快。

Apache ZooKeeper架构

在这个Apache ZooKeeper教程的下面,给出了ZooKeeper架构的几个组成部分,例如:


  • 服务器端应用程序:通过通用接口,这些应用程序便于与客户端应用程序进
  • 客户端应用程序:有几种工具可以帮助与分布式应用程序进行交互。
  • ZooKeeper节点:这些是集群运行的系统。
  • Znode:通过集群中的任何节点,我们都可以更新或修改Znode。

我们可以通过一组机器轻松地通过Hadoop ZooKeeper的架构复制ZooKeeper服务。但是,每个都维护一个内存数据树的映像以及事务日志。此外,客户端应用程序联系到单个服务器并且还建立TCP链接。因此,通过他们,他们发送请求,接收回复,观看事件等等。


为什么选择Apache ZooKeeper?

基本上,为了在(节点组)之间进行协调并使用强大的同步技术维护共享数据,集群使用 Apache ZooKeeper。但是,对于编写分布式应用程序,ZooKeeper本身就是一个提供多种服务的分布式应用程序。所以,我们在这里列出了ZooKeeper提供的常用服务,例如:

a. 命名服务
在群集中,按名称标识节点。

b. 配置管理
对于加入节点,系统的最新和最新配置信息。

c. 集群管理
实时地,在群集和节点状态中加入/下架节点。

d. Leader选举
出于协调目的,选择一个节点作为领导者。

e. 锁定和同步服务
在修改它时,锁定数据。在连接其他分布式应用程序(如Apache HBase)时,此机制可帮助我们自动进行故障恢复。

f. 高度可靠的数据注册表
即使一个或几个节点关闭 了数据的可用性。

由于分布式应用程序也提供了很少的复杂和难以破解的挑战,因此,为了克服所有挑战,ZooKeeper框架提供了一个完整的机制。此外,使用故障安全同步方法,我们可以处理竞争条件和死锁。此外,ZooKeeper解决了数据与原子性的不一致性。


使用Docker容器化ZooKeeper

通过使用Docker容器化ZooKeeper。因此,作为一个很大的好处,可以按需添加和删除节点。但是,只能通过在Docker镜像中添加ZooKeeper并在集群的每个主服务器上使用它来运行容器。


此外,它应该独立地创建一个集群,或者它应该能够在启动容器期间连接到现有集群并成为其一部分。因此,它允许使用Docker容器化动态重新配置整个Hadoop集群,这是使用Docker容器的好处。


什么是ZooKeeper客户端?

与所有分布式应用程序一样,Zookeeper分布式应用程序也包含服务器和客户端。它有一个集中的界面,客户端可以通过该界面连接到服务。但是,这些客户端可以是命令行或GUI客户端。基本上,可用于与ZooKeeper分布式应用程序交互的工具就是我们所说的ZooKeeper客户端应用程序。


什么是Zookeeper群集?

因为我们需要在集群模式下拥有ZooKeeper基础架构,以便在我们大规模运行Apache ZooKeeper时使系统处于最佳值。我们还将ZooKeeper集群称为集合体。但是,如果ZooKeeper集群必须成功运行,请确保大多数集群节点始终需要启动并运行。


ZooKeeper WebUI

基本上,要使用ZooKeeper资源管理,ZooKeeper WebUI或Web用户界面是一种更简单的方法。因此,WebUI允许使用Web用户界面使用ZooKeeper,而不是使用命令行与ZooKeeper应用程序进行交互。因此,我们可以说它使工作变得更加容易和有效。


Apache ZooKeeper应用程序

简而言之,为了大规模创建高度可用的分布式系统,它已成为最受欢迎的选择之一。因此,Apache基金会最成功的项目之一是ZooKeeper项目。


点击链接了解有关ZooKeeper Applications的更多信息


Apache ZooKeeper通过为实现不同的大数据工具提供坚实的基础,使公司能够在大数据世界中顺利运行。因此,它是大规模实施的最优选应用之一,因为它能够一次提供多种益处。


使用ZooKeeper的公司

现在,在这个Apache ZooKeeper教程中,我们提供了一个使用ZooKeeper的公司列表:


  • Yahoo
  • Facebook
  • 易趣
  • eBay
  • Netflix
  • Twitter
  • Netflix
  • Zynga
  • Nutanix
  • 百度
  • 腾讯
  • 阿里
  • 携程
  • 京东
  • 小米

Apache ZooKeeper的好处

有各种ZooKeeper的好处,例如:

a. 同步
它允许互斥以及服务器进程之间的协作。因此,这有助于Apache HBase,用于配置管理

b. 有序消息
通过用表示其顺序的数字标记每个更新,它会跟踪。

c. 序列化
它确保我们的应用程序一致运行。要协调队列以执行正在运行的线程,可以在MapReduce中使用此方法。

d. 可靠性
应用更新后,它将从该时间开始持续,直到客户端覆盖更新。

e. 原子性
没有事务是部分的,数据传输成功或完全失败。

f. 顺序一致性
按照发送它们的顺序,它应用来自客户端的更新。

g. 单系统镜像
无论它连接到哪个服务器,客户端都会看到相同的服务视图。

h. 及时性
在一定的时间范围内,客户端对系统的视图是最新的。

ZooKeeper用例

Apache ZooKeeper教程中ZooKeeper的一些最突出的用例是:


  • 管理配置
  • 命名服务
  • 选择Leader
  • 对消息进行排队
  • 管理通知系统
  • 同步

通过使用ZooKeeper CLI,我们还可以与ZooKeeper集合进行通信。基本上,这为我们提供了使用各种选项的功能。此外,为了调试,还依赖于命令行界面。
教程英文原文: https://henduan.com/igCAR

Nacos注册中心的设计原理详解

OS小编 发表了文章 0 个评论 77 次浏览 2021-03-27 16:32 来自相关话题

前言服务发现是一个古老的话题,当应用开始脱离单机运行和访问时,服务发现就诞生了。目前的网络架构是每个主机都有一个独立的 IP 地址,那么服务发现基本上都是通过某种方式获取到服务所部署的 IP 地址。DNS 协议是最早将一个网络名称翻译为 ...查看全部

前言

服务发现是一个古老的话题,当应用开始脱离单机运行和访问时,服务发现就诞生了。目前的网络架构是每个主机都有一个独立的 IP 地址,那么服务发现基本上都是通过某种方式获取到服务所部署的 IP 地址。DNS 协议是最早将一个网络名称翻译为网络 IP 的协议,在最初的架构选型中,DNS+LVS+Nginx 基本可以满足所有的 RESTful 服务的发现,此时服务的 IP 列表通常配置在 nginx 或者 LVS。后来出现了 RPC 服务,服务的上下线更加频繁,人们开始寻求一种能够支持动态上下线并且推送 IP 列表变化的注册中心产品。


互联网软件行业普遍热捧开源产品,因为开源产品代码透明、可以参与共建、有社区进行交流和学习,当然更重要的是它们是免费的。个人开发者或者中小型公司往往会将开源产品作为选型首选。Zookeeper 是一款经典的服务注册中心产品(虽然它最初的定位并不在于此),在很长一段时间里,它是国人在提起 RPC 服务注册中心时心里想到的唯一选择,这很大程度上与 Dubbo 在中国的普及程度有关。Consul 和 Eureka 都出现于 2014 年,Consul 在设计上把很多分布式服务治理上要用到的功能都包含在内,可以支持服务注册、健康检查、配置管理、Service Mesh 等。而 Eureka 则借着微服务概念的流行,与 SpringCloud 生态的深度结合,也获取了大量的用户。去年开源的 Nacos,则携带着阿里巴巴大规模服务生产经验,试图在服务注册和配置管理这个市场上,提供给用户一个新的选择。

开源产品的一个优势是开发人员可以去阅读源代码,理解产品的功能设计和架构设计,同时也可以通过本地部署来测试性能,随之而来的是各种产品的对比文章。不过当前关于注册中心的对比,往往停留在表面的功能对比上,对架构或者性能并没有非常深入的探讨。

另一个现象是服务注册中心往往隐藏在服务框架背后,作为默默支持的产品。优秀的服务框架往往会支持多种配置中心,但是注册中心的选择依然强关联与服务框架,一种普遍的情况是一种服务框架会带一个默认的服务注册中心。这样虽然免去了用户在选型上的烦恼,但是单个注册中心的局限性,导致用户使用多个服务框架时,必须部署多套完全不同的注册中心,这些注册中心之间的数据协同也是一个问题。


本文从各个角度深度介绍 Nacos 注册中心的设计原理,并试图从我们的经验和调研中总结和阐述服务注册中心产品设计上应该去遵循和考虑的要点。由于作者水平有限,文中的错误还希望大家多多指正。


数据模型

注册中心的核心数据是服务的名字和它对应的网络地址,当服务注册了多个实例时,我们需要对不健康的实例进行过滤或者针对实例的一些特征进行流量的分配,那么就需要在实例上存储一些例如健康状态、权重等属性。随着服务规模的扩大,渐渐的又需要在整个服务级别设定一些权限规则、以及对所有实例都生效的一些开关,于是在服务级别又会设立一些属性。再往后,我们又发现单个服务的实例又会有划分为多个子集的需求,例如一个服务是多机房部署的,那么可能需要对每个机房的实例做不同的配置,这样又需要在服务和实例之间再设定一个数据级别。

Nacos 的数据模型虽然相对复杂,但是它并不强制你使用它里面的所有数据,在大多数场景下,你可以选择忽略这些数据属。

另外一个需要考虑的是数据的隔离模型,作为一个共享服务型的组件,需要能够在多个用户或者业务方使用的情况下,保证数据的隔离和安全,这在稍微大一点的业务场景中非常常见。另一方面服务注册中心往往会支持云上部署,此时就要求服务注册中心的数据模型能够适配云上的通用模型。Nacos 一开始就考虑到如何让用户能够以多种维度进行数据隔离,同时能够平滑的迁移到阿里云上对应的商业化产品。

Nacos 提供了四层的数据逻辑隔离模型,用户账号对应的可能是一个企业或者独立的个体,这个数据一般情况下不会透传到服务注册中心。一个用户账号可以新建多个命名空间,每个命名空间对应一个客户端实例,这个命名空间对应的注册中心物理集群是可以根据规则进行路由的,这样可以让注册中心内部的升级和迁移对用户是无感知的,同时可以根据用户的级别,为用户提供不同服务级别的物理集群。再往下是服务分组和服务名组成的二维服务标识,可以满足接口级别的服务隔离。

Nacos 1.0.0 介绍的另外一个新特性是:临时实例和持久化实例。在定义上区分临时实例和持久化实例的关键是健康检查的方式。临时实例使用客户端上报模式,而持久化实例使用服务端反向探测模式。临时实例需要能够自动摘除不健康实例,而且无需持久化存储实例,那么这种实例就适用于类 Gossip 的协议。右边的持久化实例使用服务端探测的健康检查方式,因为客户端不会上报心跳,那么自然就不能去自动摘除下线的实例。

在大中型的公司里,这两种类型的服务往往都有。一些基础的组件例如数据库、缓存等,这些往往不能上报心跳,这种类型的服务在注册时,就需要作为持久化实例注册。而上层的业务服务,例如微服务或者 Dubbo 服务,服务的 Provider 端支持添加汇报心跳的逻辑,此时就可以使用动态服务的注册方式。

数据一致性

数据一致性是分布式系统永恒的话题,Paxos 协议的艰深更让数据一致性成为程序员大牛们吹水的常见话题。不过从协议层面上看,一致性的选型已经很长时间没有新的成员加入了。目前来看基本可以归为两家:一种是基于 Leader 的非对等部署的单点写一致性,一种是对等部署的多写一致性。当我们选用服务注册中心的时候,并没有一种协议能够覆盖所有场景,例如当注册的服务节点不会定时发送心跳到注册中心时,强一致协议看起来是唯一的选择,因为无法通过心跳来进行数据的补偿注册,第一次注册就必须保证数据不会丢失。而当客户端会定时发送心跳来汇报健康状态时,第一次的注册的成功率并不是非常关键(当然也很关键,只是相对来说我们容忍数据的少量写失败),因为后续还可以通过心跳再把数据补偿上来,此时 Paxos 协议的单点瓶颈就会不太划算了,这也是 Eureka 为什么不采用 Paxos 协议而采用自定义的 Renew 机制的原因。


这两种数据一致性协议有各自的使用场景,对服务注册的需求不同,就会导致使用不同的协议。Nacos 因为要支持多种服务类型的注册,并能够具有机房容灾、集群扩展等必不可少的能力,在 1.0.0 正式支持 AP 和 CP 两种一致性协议并存。1.0.0 重构了数据的读写和同步逻辑,将与业务相关的 CRUD 与底层的一致性同步逻辑进行了分层隔离。然后将业务的读写(主要是写,因为读会直接使用业务层的缓存)抽象为 Nacos 定义的数据类型,调用一致性服务进行数据同步。在决定使用 CP 还是 AP 一致性时,使用一个代理,通过可控制的规则进行转发。


目前的一致性协议实现,一个是基于简化的 Raft 的 CP 一致性,一个是基于自研协议 Distro 的 AP 一致性。Raft 协议不必多言,基于 Leader 进行写入,其 CP 也并不是严格的,只是能保证一半所见一致,以及数据的丢失概率较小。Distro 协议则是参考了内部 ConfigServer 和开源 Eureka,在不借助第三方存储的情况下,实现基本大同小异。Distro 重点是做了一些逻辑的优化和性能的调优。
数据一致性

负载均衡

负载均衡严格的来说,并不算是传统注册中心的功能。一般来说服务发现的完整流程应该是先从注册中心获取到服务的实例列表,然后再根据自身的需求,来选择其中的部分实例或者按照一定的流量分配机制来访问不同的服务提供者,因此注册中心本身一般不限定服务消费者的访问策略。
客户端侧负载均衡
在阿里巴巴集团内部,却是使用的相反的思路。服务消费者往往并不关心所访问的服务提供者的负载均衡,它们只关心以最高效和正确的访问服务提供者的服务。而服务提供者,则非常关注自身被访问的流量的调配,这其中的第一个原因是,阿里巴巴集团内部服务访问流量巨大,稍有不慎就会导致流量异常压垮服务提供者的服务。因此服务提供者需要能够完全掌控服务的流量调配,并可以动态调整。

服务端的负载均衡,给服务提供者更强的流量控制权,但是无法满足不同的消费者希望使用不同负载均衡策略的需求。而不同负载均衡策略的场景,确实是存在的。而客户端的负载均衡则提供了这种灵活性,并对用户扩展提供更加友好的支持。但是客户端负载均衡策略如果配置不当,可能会导致服务提供者出现热点,或者压根就拿不到任何服务提供者。
服务端侧负载均衡
抛开负载均衡到底是在服务提供者实现还是在服务消费者实现,我们看到目前的负载均衡有基于权重、服务提供者负载、响应时间、标签等策略。其中 Ribbon 设计的客户端负载均衡机制,主要是选择合适现有的 IRule、ServerListFilter 等接口实现,或者自己继承这些接口,实现自己的过滤逻辑。这里 Ribbon 采用的是两步负载均衡,第一步是先过滤掉不会采用的服务提供者实例,第二步是在过滤后的服务提供者实例里,实施负载均衡策略。Ribbon 内置的几种负载均衡策略功能还是比较强大的,同时又因为允许用户去扩展,这可以说是一种比较好的设计。

基于标签的负载均衡策略可以做到非常灵活,Kubernetes 和 Fabio 都已经将标签运用到了对资源的过滤中,使用标签几乎可以实现任意比例和权重的服务流量调配。但是标签本身需要单独的存储以及读写功能,不管是放在注册中心本身或者对接第三方的 CMDB。


在 Nacos 0.7.0 版本中,我们除了提供基于健康检查和权重的负载均衡方式外,还新提供了基于第三方 CMDB 的标签负载均衡器,具体可以参考 CMDB 功能介绍文章。使用基于标签的负载均衡器,目前可以实现同标签优先访问的流量调度策略,实际的应用场景中,可以用来实现服务的就近访问,当您的服务部署在多个地域时,这非常有用。使用这个标签负载均衡器,可以支持非常多的场景,这不是本文要详细介绍的。虽然目前 Nacos 里支持的标签表达式并不丰富,不过我们会逐步扩展它支持的语法。除此以外,Nacos 定义了 Selector,作为负载均衡的统一抽象。关于 Selector,由于篇幅关系,我们会有单独的文章进行介绍。


理想的负载均衡实现应该是什么样的呢?不同的人会有不同的答案。Nacos 试图做的是将服务端负载均衡与客户端负载均衡通过某种机制结合起来,提供用户扩展性,并给予用户充分的自主选择权和轻便的使用方式。负载均衡是一个很大的话题,当我们在关注注册中心提供的负载均衡策略时,需要注意该注册中心是否有我需要的负载均衡方式,使用方式是否复杂。如果没有,那么是否允许我方便的扩展来实现我需求的负载均衡策略。


健康检查

Zookeeper 和 Eureka 都实现了一种 TTL 的机制,就是如果客户端在一定时间内没有向注册中心发送心跳,则会将这个客户端摘除。Eureka 做的更好的一点在于它允许在注册服务的时候,自定义检查自身状态的健康检查方法。这在服务实例能够保持心跳上报的场景下,是一种比较好的体验,在 Dubbo 和 SpringCloud 这两大体系内,也被培养成用户心智上的默认行为。Nacos 也支持这种 TTL 机制,不过这与 ConfigServer 在阿里巴巴内部的机制又有一些区别。Nacos 目前支持临时实例使用心跳上报方式维持活性,发送心跳的周期默认是 5 秒,Nacos 服务端会在 15 秒没收到心跳后将实例设置为不健康,在 30 秒没收到心跳时将这个临时实例摘除。


不过正如前文所说,有一些服务无法上报心跳,但是可以提供一个检测接口,由外部去探测。这样的服务也是广泛存在的,而且以我们的经验,这些服务对服务发现和负载均衡的需求同样强烈。服务端健康检查最常见的方式是 TCP 端口探测和 HTTP 接口返回码探测,这两种探测方式因为其协议的通用性可以支持绝大多数的健康检查场景。在其他一些特殊的场景中,可能还需要执行特殊的接口才能判断服务是否可用。例如部署了数据库的主备,数据库的主备可能会在某些情况下切换,需要通过服务名对外提供访问,保证当前访问的库是主库。此时的健康检查接口,可能就是一个检查数据库是否是主库的 MYSQL 命令了。


客户端健康检查和服务端健康检查有一些不同的关注点。客户端健康检查主要关注客户端上报心跳的方式、服务端摘除不健康客户端的机制。而服务端健康检查,则关注探测客户端的方式、灵敏度及设置客户端健康状态的机制。从实现复杂性来说,服务端探测肯定是要更加复杂的,因为需要服务端根据注册服务配置的健康检查方式,去执行相应的接口,判断相应的返回结果,并做好重试机制和线程池的管理。这与客户端探测,只需要等待心跳,然后刷新 TTL 是不一样的。同时服务端健康检查无法摘除不健康实例,这意味着只要注册过的服务实例,如果不调用接口主动注销,这些服务实例都需要去维持健康检查的探测任务,而客户端则可以随时摘除不健康实例,减轻服务端的压力。
Nacos的健康检查
Nacos 既支持客户端的健康检查,也支持服务端的健康检查,同一个服务可以切换健康检查模式。我们认为这种健康检查方式的多样性非常重要,这样可以支持各种类型的服务,让这些服务都可以使用到 Nacos 的负载均衡能力。Nacos 下一步要做的是实现健康检查方式的用户扩展机制,不管是服务端探测还是客户端探测。这样可以支持用户传入一条业务语义的请求,然后由 Nacos 去执行,做到健康检查的定制。

性能与容量

虽然大部分用户用到的性能不高,但是他们仍然希望选用的产品的性能越高越好。影响读写性能的因素很多:一致性协议、机器的配置、集群的规模、存量数据的规模、数据结构及读写逻辑的设计等等。在服务发现的场景中,我们认为读写性能都是非常关键的,但是并非性能越高就越好,因为追求性能往往需要其他方面做出牺牲。


在对容量的评估时,不仅要针对企业现有的服务规模进行评估,也要对未来 3 到 5 年的扩展规模进行预测。阿里巴巴的中间件在内部支撑着集团百万级别服务实例,在容量上遇到的挑战可以说不会小于任何互联网公司。这个容量不仅仅意味着整体注册的实例数,也同时包含单个服务的实例数、整体的订阅者的数目以及查询的 QPS 等。阿里巴巴之所以字研 Nacos,容量是一个非常重要的因素。


Nacos 在开源版本中,服务实例注册的支撑量约为 100 万,服务的数量可以达到 10 万以上。在实际的部署环境中,这个数字还会因为机器、网络的配置与 JVM 参数的不同,可能会有所差别。图 9 展示了 Nacos 在使用 1.0.0 版本进行压力测试后的结果总结,针对容量、并发、扩展性和延时等进行了测试和统计。
Nacos性能与容量报告
完整的测试报告可以参考 Nacos 官网:
https://nacos.io/en-us/docs/nacos-naming-benchmark.html
https://nacos.io/en-us/docs/nacos-config-benchmark.html


易用性

易用性也是用户比较关注的一块内容。产品虽然可以在功能特性或者性能上做到非常先进,但是如果用户的使用成本极高,也会让用户望而却步。易用性包括多方面的工作,例如 API 和客户端的接入是否简单,文档是否齐全易懂,控制台界面是否完善等。对于开源产品来说,还有一块是社区是否活跃。


Nacos 提供了官方的控制台来查询服务注册情况,且目前依然在建设中,除了目前支持的易用性特性以外,后续还会继续增强控制台的能力,增加控制台登录和权限的管控,监控体系和 Metrics 的暴露,持续通过官网等渠道完善使用文档,多语言 SDK 的开发等。


集群扩展性

集群扩展性和集群容量以及读写性能关系紧密。当使用一个比较小的集群规模就可以支撑远高于现有数量的服务注册及访问时,集群的扩展能力暂时就不会那么重要。


集群扩展性的另一个方面是多地域部署和容灾的支持。当讲究集群的高可用和稳定性以及网络上的跨地域延迟要求能够在每个地域都部署集群的时候,我们现有的方案有多机房容灾、异地多活、多数据中心等。
容灾
Nacos 支持两种模式的部署,一种是和 Eureka 一样的 AP 协议的部署,这种模式只支持临时实例,并支持机房容灾。另一种是支持持久化实例的 CP 模式,这种情况下不支持双机房容灾。

在谈到异地多活时,很巧的是,很多业务组件的异地多活正是依靠服务注册中心和配置中心来实现的,这其中包含流量的调度和集群的访问规则的修改等。机房容灾是异地多活的一部分,但是要让业务能够在访问服务注册中心时,动态调整访问的集群节点,这需要第三方的组件来做路由。异地多活往往是一个包含所有产品线的总体方案,很难说单个产品是否支持异地多活。


多数据中心其实也算是异地多活的一部分。Nacos 基于阿里巴巴内部的使用经验,提供的解决方案是才有 Nacos-Sync 组件来做数据中心之间的数据同步,这意味着每个数据中心的 Nacos 集群都会有多个数据中心的全量数据。Nacos-Sync 是 Nacos 生态组件里的重要一环,不仅会承担 Nacos 集群与 Nacos 集群之间的数据同步,也会承担 Nacos 集群与 Eureka、Zookeeper、Kubernetes 及 Consul 之间的数据同步。
多数据中心方案

用户扩展性

在框架的设计中,扩展性是一个重要的设计原则。Spring、Dubbo、Ribbon 等框架都在用户扩展性上做了比较好的设计。这些框架的扩展性往往由面向接口及动态类加载等技术,来运行用户扩展约定的接口,实现用户自定义的逻辑。在 Server 的设计中,用户扩展是比较审慎的。因为用户扩展代码的引入,可能会影响原有 Server 服务的可用性,同时如果出问题,排查的难度也是比较大的。设计良好的 SPI 是可能的,但是由此带来的稳定性和运维的风险是需要仔细考虑的。在开源软件中,往往通过直接贡献代码的方式来实现用户扩展,好的扩展会被很多人不停的更新和维护,这也是一种比较好的开发模式。


那么这样的扩展性是否是有必要的呢?举一个上文提到过的例子,假如要添加一种新的健康检查方式,连接数据库执行一条 MySQL 命令,通常的方式是在代码里增加 MySQL 类型的健康检查方法、构建、测试然后最终发布。但是如果允许用户上传一个 jar 包放到 Server 部署目录下的某个位置,Server 就会自动扫描并识别到这张新的健康检查方式呢?这样不仅更酷,也让整个扩展的流程与 Server 的代码解耦,变得非常简单。所以对于系统的一些功能,如果能够通过精心的设计开放给用户在运行时去扩展,那么为什么不做呢?毕竟增加扩展的支持并不会让原有的功能有任何损失。


所有产品都应该尽量支持用户运行时扩展,这需要 Server 端 SPI 机制设计的足够健壮和容错。Nacos 在这方面已经开放了对第三方 CMDB 的扩展支持,后续很快会开放健康检查及负载均衡等核心功能的用户扩展。目的就是为了能够以一种解耦的方式支持用户各种各样的需求。


尾声

本文并不是一篇介绍 Nacos 功能的文章,因此 Nacos 的一些特色功能并没有在文中涉及,这些特色功能其实也是 Nacos 区别与其他注册中心的重要方面,包括 Nacos 支持的 DNS 协议,打自定义标等能力。


Nacos 已经在 4 月 10 号发布 GA 版本,后续将会以和社区共建的方式,持续输出新的功能,在服务发现和配置管理这两大领域继续深耕,期待与大家一起建设出最好用的服务发现和配置管理平台。


作者简介: 朱鹏飞,Github ID: nkorange,Nacos 注册中心等模块主要贡献者,阿里巴巴中间件高级开发工程师
分享阅读原文: https://henduan.com/K3lIt

更多话题 >>

热门话题

更多用户 >>

热门用户

空心菜

0 个问题, 106 次赞同

OpenSkill

31 个问题, 30 次赞同

poppanpan

0 个问题, 0 次赞同

lbct59

0 个问题, 0 次赞同