(原文: http://www.zmannotes.com/index.php/2016/01/24/cap/)
分析CAP的缺陷及实际应用
CAP理论的应用缺陷
互联网公司中分布式系统设计一般都会考虑三个问题,高可用性、网络抖动、数据一致性问题。这三个问题全部是针对系统的后台集群来讨论,不包括系统的终端。如果你的系统不需要考虑数据一致性问题,那真是太幸运了!
CAP理论证明在分布式系统中不能同时满足这三个特征,只能满足其中两点。就是后半句话引起了人们在实际应用中的困惑和对理论的质疑。
来看CAP的定义:
Consistency:集群中所有节点的数据始终保持一致性。
Availability:集群中即使有部分节点挂了,集群依然可以对外提供服务。
Partition Tolerance:集群中即使节点之间不能互相通信,集群依然对外提供服务。(节点没挂,只是节点之间不能通信,比如网络抖动)
“满足其中两点”引发的困惑
困惑一
CP:为了实现一致性和分区容忍性必须放弃可用性。
实际应用中,比如系统存在A、B两个节点(或网络分区),数据写入A后,网络发生抖动导致A、B通信中断,数据无法写入B,为了保证数据一致性,系统将无法继续提供服务直到B完成写入,AB达到数据一致的状态。如果A、B通信永远不恢复,系统将永远不可用,这在实际应用中不可接受。
困惑二
CA:为了实现一致性和可用性放弃分区容忍性。
实际应用中,比如系统存在A、B两个节点(或网络分区),数据写入A后,网络发生抖动导致A、B通信中断,数据无法写入B,为了保证数据一致性,系统将无法继续提供服务直到B完成写入,AB达到数据一致的状态。如果A、B通信永远不恢复,系统将永远不可用,这在实际应用中不可接受。
是的,实际应用中CP、CA本质上没有区别,同样是面对网络抖动问题,为了满足一致性,都会导致系统无法使用。这是因为实际应用中,节点A没有办法判断节点B是挂掉了、还是无法与其正常通信。于是CA和CP在不引入第三方组件的情况下都是无法达到的。而这完全是由C(一致性)导致,所以如果可以在业务上避免对分布式系统的一致性要求那是极好的!
实际应用分析
只求AP
放弃一致性,保证系统高可用、高扩展性、分区容忍性。系统设计将极大简化,同时保证高可用、高扩展,系统的运维也很方便,最终的结果是从设计、开发、测试、上线、运维都极大的降低了成本。就如Amazon SQS,的确是不错。
寻求A、C折中
网络抖动时,保留一致性,放弃可用性。在一定时间窗口内(比如5s),如果服务依然没有恢复,就放弃一致性,恢复对外提供服务。这种策略在实际应用比较普遍,根据具体的业务场景,设定一个时间窗口,保证系统在可容忍的时间内尽可能保持一致性,如果实在保证不了,那就放弃一致性,继续提供服务。毕竟更多时候,不能提供服务造成的损失要比部分数据不一致造成的损失大很多。更多的时候,我们自然而然的把failover逻辑放在系统的终端实现,就如ActiveMQ的failover、RocketMQ的rebalance。
耶鲁Daniel教授将此方法上升到理论层面提出PACELC,还发表了论文。
总而言之,在分布式系统中,能在业务层面回避一致性就回避。实在做不到,就进行可用性与一致性的折中。对于CAP是什么,可以完全抛到脑后,它只能带来困惑。
- https://en.wikipedia.org/wiki/CAP_theorem#cite_note-Burgess-7
- https://www.quora.com/What-is-the-difference-between-availability-and-partition-tolerance-in-CAP
- http://dbmsmusings.blogspot.com/2012/10/ieee-computer-issue-on-cap-theorem.html