如何在系统设计中使用CAP定理?

什么是CAP定理?在Consistency一致性, Availability可用性, Partition-tolerance分区容错性三者之中只能选两。

CP: 高一致性C和分区容错性P的系统,放弃可用性A。
AP: 可用性A和分区容错性P的系统,放弃高一致性C。
AC: 可用性A和高一致性C系统,放弃分区容错性P。

根据CAP定理,存在网络分区的情况下,只能在可用性和一致性之间选择。

以下面一个简单案例为例,写操作在主节点服务器,读操作在从节点服务器:

CLient ----> Web-API -----> 分布式缓存/DB(写操作在主节点+读操作在从节点)

假设有一个网络分区:

CLient ----> Web-API -----> 分布式缓存/DB(主节点+ 这里增加了网络分区 +从节点)

如果因为网络分区通讯出错,导致主从服务器节点无法同步数据,写入主节点的数据,无法在从节点服务器读出。

我们只能做两件事,在事务完成后发送500错误响应给用户,放弃了可用性,破坏用户体验,这是一种悲观做法,另外一个乐观做法是早点发送200正确响应给用户,放弃一致性,保住可用性,保住了用户体验。

哪个更好?没有哪个更好,完全取决于场景情况决定。

那么谁在两个方案中做决定呢?如果是开发团队,也许不太对,任何一种方法选择需要根据以下因素决定:
1. 实现高一致性C的成本是多少?或者不一致性的成本是多少?
2.达到高可用性有多重要?还是仍出一个错误信息更合适?
3.可以容忍多长的延迟?接近无穷大∞的高延迟等于没有可用性。
4.方案复杂性如何?

那么除了以上方案,有没有可选的设计思路?

PACELC定理

PACELC定理如下:


If there is Partition,
       how does the system trade-off 
       between Availability and Consistency
Else
       how does the system trade-off
       between Latency and Consistency


如果有分区P,那就是在可用性和一致性之间平衡选择。
否则,就是在延迟Latency和一致性之间平衡选择。

高可用性和高一致性是我们完美的追求,但是存在网络分区情况下,鱼和熊掌是不可兼得的。

变通方法:放弃一点高一致性,获得一点高可用性(低延迟),也就是最终一致性方式。

如何针对我们这个案例实现最终一致性?

1. 针对耗时的API调用使用异步响应给用户。
2. 在后台做所有的写操作工作。
3. 在数据库集群和缓存达成共识,同时不让用户等待。

这样做的结果是开发与业务两个方面双赢。

结论
在系统设计中考虑CAP定理是重要的。必须考虑整个系统的所有故障点。Casandra,Zoo Keeper,Kafka等技术可以在数据层面实现最终一致性。在AP和CP之间选择并不容易。在大多数情况下,它取决于业务要求。

猜你喜欢

转载自my.oschina.net/u/1185936/blog/1590854