晦涩难懂的 CAP,是否完全正确?
CAP
说到 CAP,首先不能不说分布式系统,前面几篇也说过,分布式系统的出现,很大的一个原因是要解决单机系统的瓶颈问题,但是工作模式上还需要保证系统的可用性,一致性,性能等。一个分布式系统,网络不可靠的特性必然存在,这就导致了分布式系统比单机系统要面对更多的不确定因素的挑战。
CAP 是针对分布式系统提出的一个重要理论,在很多开发者眼里被视为金律。CAP 理论是对分布式系统特点的一个高度抽象,也是我们设计一个分布式系统很好的参考框架。在 CAP 理论提出初期,有很多人提出各种质疑,后来 CAP 之父又再次给 CAP 理论做出了重要修正。
很多架构师在设计系统的时候都以 CAP 理论为重要参考依据,其中 CAP 不可能三角是最重要的指导思想。CAP 把一个分布式系统抽象为三个固有属性:
一致性(Consistency):客户端无论访问系统的哪个节点,要么读到的数据都是最新的,要么读取失败。这本质上是说分布式系统的所有节点上的数据都是实时同步的,一致性强调的是数据正确性。
可用性(Availability):当系统内任意一个节点发生了故障,非故障的节点仍然能响应客户端的请求,无论这个响应返回的是最新数据还是旧数据。这个特性可以看做是对客户端的一个保证:无论何时,我都能给你响应。
分区容错性(Partition Tolerance):即使系统内部某个节点有消息丢失或者高延迟,系统仍然能持续提供服务。这个指标强调的是对分布式系统的容错能力。
分布式系统是由通过网络通信的多个节点组成,因为系统需要持续对外提供服务,所以分区容错性(P)是分布式系统必须要保证的。三角理论这个时候就尴尬到只需要从一致性和可用性这两个指标中选择一个,所以有人根据这个特点提出:
基于 CAP 理论的分布式系统,分区容错是固有而且必须要保证的一个指标,设计分布式系统要根据业务的场景来选择一致性还是可用性。
使用 CAP 理论设计系统
当我们在设计一个分布式系统的时候,由于分区容错性必须要保证,所以就演化成了是选择 AP,还是选择 CP 指标。
当我们选择了 CP(一致性)的时候,客户端的每次请求一定会读取到最新的数据,但是因为消息丢失,节点通信高延迟等原因,被读取的节点中的数据不一定是最新数据,所以为了保证一致性,这个时候返回给客户端的是出错信息,换句话说,这个节点在这个时候是不可用的。
当我们选择了 AP(可用性)的时候,为了始终响应客户端的请求,哪怕节点上的信息不是最新数据也要给客户端响应,这个时候客户端得到的可能是过时的数据。
真实的线上系统环境中,其实还存在另外一个场景:随着节点的不断增加,严格的一致性会导致系统的响应时间变慢,系统资源消耗的增加,这个时候为了维护强一致性的成本可能要超出我们的预期,在这种情况下,我们就只剩下了一种选择:更多的选择可用性,放弃强一致性,采用最终一致性。
退一步说,在分布式系统节点不是很多的情况下,CAP 三个指标在一定程度上是可以同时能够保证的。但是针对分布式数据库事务领域,后来的专家已经证实并不适用于 CAP。
举一个很简单的例子:如果要设计一套分布式的日志收集系统改如何选择呢?俗话说脱离业务的架构就是耍流氓,具体的系统设计还要看每个业务的场景。日志收集的分布式系统很典型的一个特点是:读少写多,数据重要性级别低,数据量大,可以容忍部分数据丢失。这样的场景下,我们可以优先选择 AP,能持续的提供服务比数据一致性要重要很多。
再举一个简单例子:每个公司有自己的配置中心,配置中心中可能会存储分布式系统重要的配置信息,比如:每个节点的 IP 和端口信息等。在这样的系统中,客户端每次读取配置中心的信息要求必须为最新数据,如果不是最新数据会发生业务错误信息,比如一个分布式系统中 A 节点挂掉了,配置中心中所有的节点数据必须要保证一致(删除 A 节点信息),不然的话,客户端还能读到 A 节点的信息,然后去访问 A 节点会发生业务异常的。
BASE 理论
由于 CAP 原则在只能在 AP 和 CP 之间二选一,而且在选择强一致性的同时会大大牺牲性能,这对于并发和响应时间都有要求的系统都是难以接受的。于是 eBay 公司尝试选择了不同的方案,提出了一套名为 BASE 的理论。
BASE 理论基本思想是牺牲了数据一致性来满足系统的可用性,在系统发生故障或者部分数据不一致的时候,扔能提供系统“主要可用”。
BASE:全称:Basically Available(基本可用),Soft state(软状态),和 Eventually consistent(最终一致性)三个短语的缩写
BASE 理论是对 CAP 理论的一个延伸,或者说是对 AP 模型的一个延伸,它是对互联网大规模分布式系统的一个总结,强调的是可用性。
Basically Available(基本可用)
基本可用不同的系统有不同的解释,但是总体思想是保证系统大部分可用。
在一个分片的分布式存储系统中,假设有 10 个节点来存储数据,假设其中两个节点发生故障,那么其他 8 个节点仍然能提供服务,既:系统的 80%仍然可用。
我们平时用的流量削峰策略,其实本质上也是要保证系统的主要可用。服务降级,服务熔断也是通过牺牲一部分系统的可用性来保证核心功能可用。
以上所说都说明了一个事实:基本可用本质上是一种妥协,在节点出现故障的时候通过牺牲非核心功能的可用性,来保证核心功能的可用性。
Soft state(软状态)
对于服务端的系统来说,每个节点或者服务都可以设计为有状态(stateful)和无状态(stateless),这在根本上决定了一个分布式系统是否具有良好的扩展性,故障恢复等高级特性。对于完全无状态的服务来说,具有更好的水平扩展性,而对于有状态的服务来说,如果要实现水平扩展,可能涉及到状态的迁移等过程,比较复杂。
基于有状态和无状态的思想,BASE 理论提出一个介于中间的状态:soft state:服务端会维护数据的状态,但是有一个期限,过了这个期限,服务端将会丢弃这些状态信息,恢复正常的状态。
Eventually consistent(最终一致性)
最终一致性是指系统在经过一段时间内,每个节点的数据会达到一个一致的状态,换句话说,它是必须经过一段时间才能达到强一致性的过程。
由于强一致性的缺陷,现在几乎所有的互联网系统都是基于最终一致性来设计架构,当然如果最终一致性不满足业务场景的情况下,才会使用牺牲性能和可用性来采用强一致性。比如在支付的场景中,必须要采用强一致性来设计系统,不然这个锅是程序员背不起的。
至于如何实现最终一致性,有很多的解决方案,目前最常用的是利用 MQ 消息来实现,前提是你的 MQ 需要保证不丢失消息。举个很简单的例子:一个典型的电商场景,商品管理系统和订单系统是两个物理上隔离的两个系统,可以看做是两个微服务,当一个订单支付成功之后,商品管理系统需要把对应的商品减少库存,这个过程可以采用最终一致性来设计。当订单支付成功,发一个 mq 消息,当商品管理系统接收到这个消息,会把对应商品的库存扣掉。
写在最后
CAP 理论是分布式设计中一个重要的参考指标,但是这个理论并非放之四海而皆准的思想,它的适用场景仅仅在非数据库系统的原子读写。在互联网高速发展的今天,分布式系统早已不是之前的简单系统了,架构师在设计系统中还需要考虑安全性,扩展性,自动化等诸多因素,所以现在做程序员多累呀!!
BASE 理论绕过了难以实现的分布式强一致性,采用一种权衡的策略来达到业务要求。BASE 理论主要针对数据分片场景,让不同的数据分布在不同的节点,以提升系统的可用性。
更多精彩文章
版权声明: 本文为 InfoQ 作者【架构师修行之路】的原创文章。
原文链接:【http://xie.infoq.cn/article/5899885a1020d0a38f27133f3】。文章转载请联系作者。
评论