原始网页:https://www.cockroachlabs.com/docs/stable/multi-active-availability.html


CockroachDB可用模型可以描述为多活可用性(Multi-Active Availability)。多活可用性可以提供跟传统高可用性在概念上类似的好处,同时允许用户在集群的任意节点上进行读取和写入操作,不会产生冲突。

什么是高可用性?

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

在深入地讲解CockroachDB的多活可用性之前,我们将回顾一下两种使用最频繁的高可用性设计方案:Active-Passive和Active-Active系统。

Active-Passive

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

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

Active-Active

在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值的不同?在系统里面没有一个清晰的方式去处理这种数据不一致的情况。

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

什么是多活可用性

多活可用性是CockroachDB的可用模型(在部分节点发生故障的时候系统服务仍然在线),是设计用来规避传统的Active-Passive或是Active-Active系统的缺陷。

像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'

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