Z.S.K.'s Records

Multi-Active Availability vs High Availability

当我们在讨论系统架构的时候经常听到HA(High Availability 高可用)如何如何保证, 在调研CockRoachDB时看到个MA(Multi-Active Availability 多活可用)的概念, 头一次听说, 比较新颖, 所以网上查了一上, 说到底还是CAP那一套.

High Availability

我们经常会错误的认为高可用就是一致性,其实并不然.

高可用性,是指应用程序在其中一个服务的宿主系统发生故障的时候,仍然能够不停地运行。这是通过水平拓展应用程序服务的方式来实现的(例如在多台机器和系统上部署相同的服务)。如果它们当中的其中一个服务发生故障,其他服务能够接替并提供相同的服务内容

高可用强调的是在节点发生故障时, 系统仍然可以提供服务, 并不关心数据一致性的问题.

两种使用最频繁的高可用性设计方案:Active-Passive和Active-Active系统

Active-Passive

在Active-Passive系统中,所有流量会路由到一个“Active“的主副本。这个副本上状态的变化将同步到备份的“Passive”的从副本,系统尽可能地保证“Passive”副本与“Active”副本之间的一致性。

很典型的是Oracle数据库.

然而这种设计存在以下缺点:

  • 如果用户使用异步复制策略,将无法保证所有数据成功地同步到“Passive”的从副本。这就意味着用户可能丢失数据,在特定的应用场景下这可能导致非常可怕的后果。
  • 如果用户使用同步复制策略,在“Passive”的从副本出现故障的时候,用户不得不牺牲整个应用系统的可用性,否则将面临不一致的风险

Active-Active

在Active-Active系统中,多个副本各自运行着独立的服务。负载被路由到所有副本上。如果一个副本出现故障,其他副本可以继续处理原本应该路由到故障副本上的负载。

对于数据库而言,Active-Active的系统对于大多数工作负载来说是难以实现的。例如:如果用户想让多个副本处理同一份数据的写操作,如何保证它们的一致性?

打个比说:

在Active-Active设计的高可用性集群当中有2个副本(AB)。

  1. A确认键xyz的写请求,值为'123',随后发生故障。
  2. B确认键xyz的读请求,因为没找到匹配键值对,返回NULL
  3. B确认键xyz的写请求,值为'456'
  4. A重启并尝试再次与B连接,此时如何处理xyz值的不同?在系统里面没有一个清晰的方式去处理这种数据不一致的情况。

在这个例子当中,集群在整个生命周期内保持Active状态。根据CAP理论,这是AP系统,它能够在分区发生时保证可用性,而不能保证一致性。

Multi-Active Availability

像Active-Ative设计模式,具备多活可用性的系统当中的所有副本,都处理读和写的负载。CockroachDB在此基础上做了改进,使用“一致性副本”实现了数据之间一致性。在这种设计里,同步请求将发送到至少3个副本,且只有绝大多数副本响应了该请求,才能视作同步完成。这就意味着用户在系统不满足可用条件时仍然会遇到系统故障。

为了避免冲突,保证数据的一致性,集群如果丢失了绝大多数副本,将停止响应。这是因为在故障系统里的副本丧失了使数据达成一致的能力。待到绝大多数副本重启以后,数据库将恢复可用。

在一个多活可用的集群中有3个CockroachDB节点(ABC)。

  1. A接收到键xyz的写请求,值为'123'。它与节点BC同步写请求结果,确保它们确认了写请求结果。一旦A收到第一个确认,写请求完成。
  2. A随后发生故障。
  3. B接收到键xyz的读请求,返回值'123'
  4. C接收到键xyz的更新请求,修改值为'456'。它与节点B同步写请求结果,确保B确认了写请求结果。在C接收到来自节点B的确认之后,写请求完成。
  5. A重启,再次加入集群。它接收到了键xyz的最新值,将旧值更新为'456'

在这个例子当中,如果在A故障以后B或C发生故障,集群将停止响应。根据CAP理论,这是一个CP系统,它能够在分区发生时保证一致性,而不是保证可用性。

参考文章:

转载请注明原作者: 周淑科(https://izsk.me)

 wechat
Scan Me To Read on Phone
I know you won't do this,but what if you did?