Aerospike:入门与实战——高级概念

276 阅读21分钟

一些最具挑战性的用例超出了单一地点运行消费者服务的基本概念。地理分布式部署通常用于为大量(数百万到数十亿)消费者提供实时服务。这些服务通常需要可预测的低延迟服务级协议(SLA,以毫秒为单位)以及全天候的高可用性,以确保消费者的实时体验基本一致。目标是在确保服务始终可用的同时,为第一个用户和第十亿个用户提供相同的良好用户体验。数据跨地理分布站点的复制对于提高实时关键任务服务(例如金融系统、电商网站、电信服务和票务预订系统)的可用性至关重要。

许多生产环境中的服务需要在多个站点设置分布式数据库,以提高弹性和可用性。这种地理分布可以通过同步或异步复制来实现。

只有通过同步复制,才能在分布式系统组件之间提供一致性,但这将在网络分区期间限制系统的可用性。此外,同步的双活系统会带来更高的正常写延迟,特别是在跨大洲部署、站点分布在数千英里的情况下,延迟可能会达到数十毫秒甚至数百毫秒。

图 9-1 展示了一个同步双活部署的示例。在此示例中,单个 Aerospike 集群分布在三个站点和三个机架上,每个站点都拥有整个数据库的完整副本。同步复制导致写入延迟在 100 至 200 毫秒之间,而在正常操作中读取延迟可以非常低(低于毫秒级)。虽然系统可以在一个站点故障的情况下继续工作,但读取性能会有所下降,更复杂的故障可能会导致系统的全部或部分不可用。

image.png

一个很好的同步复制用例是意大利银行推出的即时支付结算系统 (TIPS),该系统“确保在几秒钟内完成结算,并且独特之处在于直接使用央行货币结算。”在这种场景下,一致性要求极高,没有人会使用一个偶尔丢失资金的支付系统,因此任何情况下都不能丢失单条记录。

然而,大多数面向消费者的高性能应用无法容忍同步复制所需的高写入延迟,也无法接受在分区脑裂(split-brain)情况下集群部分节点无法通信所导致的可用性问题。例如在 PayPal 支付系统的防欺诈流程中,机器学习和 AI 算法用于实时生成欺诈评分(约 100–200 毫秒)。通常,为了生成欺诈评分会进行数百次数据库读取,并且需要数十次写入来存储最近的历史记录。只有将最新的行为数据输入 AI 模型进行评分,算法才能有效。因此,为防止欺诈发生而不是事后检测,确保最近的交易历史记录可被快速访问至关重要。这就意味着,低延迟的读写是必要的前提条件。

这种场景在风险管理、推荐引擎、广告的实时竞价 (RTB) 等领域也有大量应用。这些应用场景需要高效处理最新数据,但对一致性要求稍有放宽,与支付结算案例不同。因此,对于这些应用而言,适当放宽一致性以获得极低的读写延迟、更高的吞吐量和极高的可用性是可以接受的,异步复制成为这些应用的最佳选择。

Aerospike 数据库广泛使用了多种同步和异步复制策略。在本文编写时,章节中提到的功能仅适用于 Aerospike 企业版。

同步活跃-活跃系统

Aerospike 支持多站点集群,即一个集群可以跨多个地理位置,如图 9-1 所示。这种部署方式允许在不同站点和云区域之间共享数据库,同时没有数据丢失的风险。自动化故障转移、高抗故障能力和强劲的性能构成了 Aerospike 的多站点集群的基础。Aerospike 的多站点集群由两个主要特性支持:机架感知(rack awareness)和强一致性。

机架感知允许数据分区的副本存储在不同的硬件故障组(即不同的机架)上。管理员可以配置每个机架通过设置复制因子(replication factor)来存储全部数据的副本,从而最大化数据的可用性和本地读取性能。Aerospike 会在每个机架内均匀分布数据。

在任一时刻,某一数据分区的主副本仅存储在一个机架的某个节点上。其他节点(位于不同机架上)存储数据的副本,Aerospike 会自动将这些副本与主副本同步。如第 5 章中详细描述的那样,Aerospike 使用节点清单(roster,即预期节点的列表)而不是法定人数来确保数据集的完整性。节点清单结合分区映射跟踪主副本和副本的位置,也能够识别健康集群中的机架和节点。

在图 9-1 的配置中,每个数据中心有一个包含三个节点的机架,且每个节点上都有节点清单的副本。考虑复制因子为 3 的情形,此示例中数据分区的主副本位于节点 9(机架 2);副本分别位于节点 1(机架 1)和节点 4(机架 3)。

可以配置 Aerospike 客户端将应用程序的读取请求路由到本地数据中心。在图 9-1 展示的部署配置中,每个机架上(即每个站点上)都存储有完整的数据库副本。因此,通过智能地处理读取请求,Aerospike 可以在正常运行期间为此集群提供亚毫秒级的读取延迟。

写入处理方式有所不同。为了保持集群的一致性,Aerospike 将每次写入路由到当前数据主节点,由该主节点确保写入已应用到其副本和所有副本上,然后才提交操作。由于路由写入和同步副本引入了开销,因此写入速度不如读取。在跨大陆的配置中,写入延迟平均在 100 到 200 毫秒之间。

Aerospike 的多站点集群在强数据一致性方面遵循与单站点集群相同的规则(第 5 章已述),并自动对大多数常见情况进行纠正操作。例如,如果主副本由于节点或网络故障不可用,Aerospike 会从现有的副本中指定一个新的主节点,并根据需要创建新的副本以满足复制因子要求。在多站点集群中,新的主节点通常会位于其他机架上。

考虑一种情形,其中一个站点因网络或电力故障不可用。假设美国东部站点(机架 2)无法被集群的其余部分访问。Aerospike 会自动形成一个由美国西部(机架 1)和美国中部(机架 3)组成的新子集群,以便继续处理读写操作,无需操作员干预。在这种降级系统中,通过应用第 5 章所述的一致性规则,所有数据将在机架 1 和机架 3 中保持完全一致,而机架 2 将不允许进行任何事务(读取或写入)。注意,当机架 2 重新加入集群时,分区方案、集群算法和强一致性规则将确保平稳地完成重新加入,无需操作员干预,最终集群将在准确安全地合并分裂期间的更改后回到稳定状态。

需要注意的是,在某些分裂情况下,为了保持一致性,系统可能会部分或全部不可用(例如图 9-1 所示的所有三个站点同时失去联系的情况)。

异步系统

在 Aerospike 中,实现异步复制的子系统被称为 XDR。最初,XDR 是跨数据中心复制(cross-datacenter replication)的缩写,但由于云端部署日益普及,这一名称并不完全准确。从这里开始,我们将简单地使用 XDR 来指代跨集群复制系统,无论这些集群是在数据中心、云区域还是云可用区中。

Aerospike 异步复制架构主要有以下三种应用场景:

  1. 灾难恢复 异步复制可以确保面向消费者的服务(如互联网或移动服务)在灾难性故障期间继续运行。
  2. 内容分发网络(CDN)的一部分 当 Aerospike 用作 CDN 的一部分时,消费者应用程序及其数据需要靠近终端用户,以提供最佳的用户体验。
  3. 集群复制 在复制现有集群时,异步复制可以在不中断服务的情况下设置新集群,并将所有数据和工作负载从现有集群传输到新集群。

Aerospike 的异步复制架构使用集群作为地理分布站点之间复制的基本单元。单一集群节点之间的所有复制默认是同步的,而集群之间的所有复制是异步的,如图 9-2 所示。系统支持两种主要拓扑结构:主动-被动(active-passive)和主动-主动(active-active)。

image.png

主动-被动拓扑结构

如图 9-3 所示,简单的主动-被动拓扑中,集群 A 为主动集群,负责接受应用程序的写操作,并将这些写操作发送到被动集群 B,在被动集群中本地应用。该拓扑的主动-被动行为由连接两个集群的单向箭头表示。应用程序不会直接向集群 B 进行写入操作。应用程序可以从被动集群读取数据,但最新的数据只有在主动集群的写操作被接收并应用到被动数据库集群 B 之后,才会出现在被动集群中。从主动集群提交写操作到达被动集群所需的时间称为延迟

image.png

在某些情况下,将写操作从一个集群转发到另一个集群并将它们串联成线性链的主动-被动拓扑结构是有用的。如图 9-4 所示,应用程序的写操作被发送到主动集群 A。集群 A 将其写操作传输到被动集群 B,接着 B 再将这些写操作传输到第二个被动集群 C。这种方案的缺点在于,距离主动集群较远的集群在传输数据时会产生累积延迟。

image.png

图 9-5 展示了一种更复杂的主动-被动拓扑结构。这种拓扑结构称为星型拓扑,具有一个主动集群 A,将所有写操作并行传输到其他集群。要创建一个星型拓扑,至少需要三个集群:一个主动集群(A)和至少两个被动集群(例如,D 和 E)。

image.png

主动-主动拓扑结构

在主动-主动配置中,系统中的所有集群都可以接受应用程序的写入操作并将其传输给其他集群。图 9-6 显示了一个简单的两集群主动-主动系统。在该例中,有两个集群 A 和 B。两个集群都可以接收来自应用程序的写入操作,并将其数据写入传输到另一个集群。

image.png

警告
如果在两个集群中同时修改同一条记录,可能会发生数据冲突。为避免此问题,可以使用一些设计策略,例如后面将介绍的“数据收敛”策略,但需要注意,这种冲突风险是 XDR 在主动-主动拓扑中特有的。

在实际应用中,拓扑结构可能非常复杂,通常会包含主动-主动和主动-被动链接的组合。图 9-7 展示了一个实例,其中有四个主动集群(A、B、C 和 D),每个集群都通过双向链接与其他三个集群相连,这种结构被称为“网状拓扑”。星形和网状拓扑是复杂真实环境部署中最常用的。

此外,主动集群 D 与一个被动集群 E 之间存在一个单向链接。每个主动集群(A、B、C 和 D)都允许应用程序写入,而被动集群 E 仅接收来自集群 D 的更改数据。由于 D 与所有其他主动集群相连,E 最终应会接收到在任何一个主动集群上发生的所有应用数据写入。

image.png

需要注意的一点是避免在数据传输配置中形成循环,以确保系统不会因沿循环链路重复转发相同的数据更改而陷入无限循环。

传输策略

异步复制使用存储在数据库索引中的记录元数据来确定需要传输的更改列表。Aerospike 的传输算法基于两部分关键元数据:最新更新时间(LUT)和每个分区的上次传输时间(LST)。Aerospike 会在其内存驻留的索引中跟踪这些信息。任何分区中记录的 LUT 大于该分区的 LST 时,该记录就成为传输候选对象。如果记录的 LUT 比记录分区的 LST 更新,那么记录会通过对应的活跃链接传输到远程集群。一旦传输完成,分区的 LST 就会更新。

Aerospike 支持传输已更改记录的部分内容,例如单个 bin(字段),并实现了一种数据收敛功能,可在主动-主动拓扑中解决写入冲突。该功能确保即使在多个站点同时对同一记录进行更新,最终在所有连接的站点上数据保持一致。为实现这一点,Aerospike 额外存储了关于每个 bin 的 LUT 信息,并在适当时使用。

图 9-8 展示了一个全球分布式部署的典型异步复制设置。可以看到,全球多个站点可以在复杂的拓扑结构中相互通信,支持主动-主动和主动-被动的部署方式。用于跟踪更改的元数据以及传输记录部分内容的能力,使得 Aerospike 的异步复制可以在复杂的部署拓扑中应用,而无需担心不同目标站点之间的传输速度差异或不同的网络特性。

image.png

回溯功能

XDR 的一个有用功能是允许数据库操作员指定过去的某个时间点,并请求 XDR 从该时间点开始传输所有更改过的数据。这称为“回溯”。

警告
删除操作在回溯时可能不会被传输,因为数据库不会永久存储这些信息(在集群中创建的删除标记在所有较早的副本被移除后会被周期性清除)。在回溯操作之外,删除操作通常会被转发到远程集群以保持同步。

回溯功能可用于通过 XDR 从源集群预填充新目标集群。更常见的是,回溯被用于纠正配置错误导致的丢失记录。它也可用来解决因应用程序中的错误导致某些数据未正确更新在源数据库中,进而未正确复制的问题。

数据收敛

在包含主动-主动和主动-被动模式的复杂拓扑结构(如图 9-7)中安装集群时,对同一记录的并发更新可能会导致两个目标集群中记录的值不一致,因为它们相互传输相同的数据。Aerospike 实现了一种基于记录子部分(bins)的收敛方案,每个 bin 都有其最新更新时间(LUT)随数据一起存储。每个 bin 会跟踪并传输以下数据:LUT、集群源 ID(src-id)和 XDR 写入标志(表明该版本的 bin 是否有资格被 XDR 传输的标志)。

该收敛算法使用“最后写入优先”(LWW)语义。LUT 较高的 bin 值可以覆盖 LUT 较低的 bin 值,反之则不行。如果两个 LUT 相同,则使用集群源 ID 按字母顺序打破平局。这一方案假设服务器的时钟在集群范围内同步,但单调递增的时钟足以确保良好的系统行为。

在图 9-9 中,您可以看到 Aerospike 的算法如何实现收敛,即强最终一致性。(垂直轴代表时间,过去在顶部,向下移动至未来。)在没有收敛的情况下,两个集群都可以获得更新,即更新 1 和更新 2。它们在相互传输数据时,最早写入的更新可能会延迟到达另一集群,导致其覆盖第二次更改。因此,集群 DC1 会有更改 2 的正确数据。而集群 DC2 中更改 2 被更改 1 覆盖,回到了较早的错误数据。

右侧两个集群展示了在 bin 收敛算法下的情况。更改 2 在更改 1 之后写入 DC1,因此它包含正确的数据。更改 1 到达集群 DC2 时,算法会比较最新更新时间并决定不应用更改 1。因此,更改 2 保持不变,两个集群最终都拥有正确的数据。

image.png

非 Aerospike 目标

尽管到目前为止的讨论集中在将 Aerospike 作为目标集群,但这种复制策略同样适用于非 Aerospike 目标。然而,这其中有一些关键差异:

  • 对于 Aerospike 目标,XDR 可以自动发现新节点、检测节点健康状况并提供基于分区的路由。
  • 对于非 Aerospike 目标,XDR 无法自动发现新节点,无法自动检测节点健康状况,只能支持基于摘要的负载均衡。

目前的假设是,源集群到目标集群的每个节点都存在稳定的网络访问。但在现实世界中,尤其是在涉及多个公有云和私有数据中心的部署中,这种访问情况并不总是可能的。对于 Aerospike 目标,可以在负载均衡器后面放置一个无状态的 XDR 代理,以便在目标端翻译 Aerospike 集群的网络协议,类似于图 9-10 中底部的两个拓扑图所示。而对于非 Aerospike 目标,可使用事件流处理(ESP)连接器,该连接器提供 HTTP 接口,从而更方便地将一种协议翻译成另一种协议,如图 9-10 底部的拓扑所示。

image.png

排序限制

由于复制策略的异步特性,在地理位置相距较远的集群之间强制执行更新顺序存在一定限制。虽然分区 ID 和摘要节点亲和性在正常情况下有助于实现排序,但在超时、目标节点故障(无论是真实还是感知的)、动态服务线程更改以及源节点故障(无论是真实还是感知的)等情况下会出现例外。图 9-11 展示了一个消息传递顺序错误的示例,导致 DC2 中保留了较早的值。在该示例中,假设 DC2 未使用 bin 收敛来强制排序。

image.png

在异步复制策略中原生强制排序的能力有限。可以通过引入 bin 收敛来改善排序限制。由于 bin 收敛开销较大,有一些轻量级的替代方案,尽管无法完全解决排序问题,但相较于默认的传输算法有显著改进。通常通过使用 XDR 代理或 ESP 连接器,在源集群和目标集群之间引入排序。表 9-1 显示了这些方法的部分优缺点。

流程X → AS/CX → P → AS/CX → LB → P → AS/CX → ESP → LB → P → AS/C
1: XDR 超时问题P 有帮助P 无法帮助ESP 有帮助
2: P 上下线不适用P 无法帮助P 无法帮助ESP 有帮助
3: 源集群上下线问题P 有帮助P 无法帮助ESP 无法帮助

在此表中,"AS/C" 表示目标 Aerospike 集群,"X" 表示通过 XDR 进行数据传输的源集群,"P" 表示代理,"LB" 表示负载均衡器,"ESP" 表示事件流处理器。

强一致性也可以快速实现

如第 1 章所介绍的,Aerospike 证明了强一致性可以实现高速度。第 5 章介绍了实现这种可能性的策略基础概念。现在我们来看看它们是如何协同工作的,并深入了解其中一些策略。

水平扩展方面,Aerospike 采用无共享架构,使所有数据库集群节点在 CPU、内存、存储和网络容量上保持一致。此方案的关键组成部分是统一的数据分区算法,可以消除数据库集群节点间的数据分布不均,从而避免热点问题。支持机架感知部署、动态数据再平衡和智能客户端的一跳访问数据,这使得系统即使在负载实时增减的情况下也能保持极高的效率和弹性。

垂直扩展方面,数据库充分利用硬件和云基础设施(CPU、主内存、存储、网络等)的每个方面,确保系统资源的 100% 利用,以提供最佳性能。HMA(热存储访问)技术使得实时数据可以存储在 SSD 中。由于 SSD 每节点可存储高达 100 TB 的数据,这种方式大大减少了集群节点的数量,但每个节点的事务需求增加了 10 倍或更多。为了支持这一需求,Aerospike 使用 C 语言编写,并采用高级技术,如 CPU 固定、NUMA 固定、流线化、网络队列等,以最大限度地提高每个节点的处理效率。

在分布式系统中实现强一致性的关键挑战是,在保持高性能的同时还要实现相当的可用性。得益于 Aerospike 的水平和垂直扩展效率,它可以使用写全读一的同步方案。

在故障期间提高可用性方面,Aerospike 的强一致性算法基于称为花名册的集群节点列表。在节点或网络故障期间,花名册信息用于定义何时特定数据项可用的决策规则。这些规则确保在常见维护或故障情况下,强一致性数据库系统中的所有数据都保持可用性:

  • 两路分裂脑,集群分为两个子集群
  • 滚动升级(集群中至少需要两个副本)
  • 三副本数据库系统在跨三个站点的三机架配置中出现单站点故障

该方案的一个关键优势是它可以使用两个副本来维护强一致性。与其他基于共识的方案(例如 Raft)相比,这种实现方式使强一致性变得非常高效。Aerospike 在不同一致性级别下的 5 节点集群基准测试结果如表 9-2 所示。测试在 5 亿个键、复制因子为 2 的情况下进行,Aerospike 配置为内存持久化存储。注意,线性一致性和顺序一致性都是强一致性的一种,即在这两种设置下不会发生数据丢失。测量结果显示,顺序一致性(CP 模式——优先一致性)与放宽一致性(AP 模式——优先可用性)的 TPS(每秒事务)和读/写延迟几乎相同。在这种情况下,Aerospike 实际上消除了强一致性配置和放宽一致性配置之间的性能差距。

配置类型线性一致性,无数据丢失,CP 模式顺序一致性,无数据丢失,CP 模式放宽一致性,AP 模式
TPS(每秒事务)1.87 百万5.95 百万6 百万
读延迟(微秒)548 μs225 μs220 μs
写延迟(微秒)630 μs640 μs640 μs

总结

在本章中,您了解了同步和异步复制策略,以及强一致性的快速事务实现。具备这些功能的 Aerospike 数据库通常被实时消费应用程序使用,这些应用程序需要高读写吞吐量,并且能够在相距较远的多个站点运行。在第 10 章中,您将看到一些使用案例,这些案例具有 Aerospike 设计得以很好满足的其他挑战性要求。