什么是 CAP ?什么是最终一致性?什么是幂等操作?
# CAP理论
CAP的结论非常简单:在分布式系统里,有3个属性非常重要,但只能同时满足其中的2个。
Consistency:all nodes在任何时刻看到的data都是一样的(或说client的read操作总是返回最新写入的那个value) Availability:系统时刻都允许操作,并且操作总会快速被Coordinator响应,最终client很快就得到返回的结果 Partition-tolerance:尽管网路有时候会因为故障导致被分隔开,但是系统依然在正常工作(或者说在满足前述的条件下工作)
# 为什么这三者如此重要?
For Availability:
经统计,对于Google、Amazon这样的数据公司,系统增加500ms的延迟就会损失公司20%的收益,所以必须快速且可靠地进行 Read/Write。
For Consistency:
比如在银行系统,任何client都必须查看到最新的updated data item,不然就会给交易造成致命的影响。
For Partition-tolerance:
因为Internet可能因为某些原因随时断开(Router故障、海地线缆断开、DNS故障);即使在同一个data center里,故障都会随时随地地发生,比如 Rack switcher 宕机。
# CAP权衡
- 如今的云计算环境里,因为网络随时都会被隔离开来,这是无法避免的,P是必须满足的,那么CAP暗示一个system要在C和A中做出抉择。
- A和C并不是一个硬币的两面,只能选择其中一个;A和C应该看成天平,系统可以选择向哪边倾斜,但另一边也应该一定程度的保留。
- 对于A和C之间的选择,不应该粗粒度的整个系统级别进行选取,而应该针对系统中的不同子系统,针对性的采取不同的取舍策略。
# 三种组合
- CA: 保证可用性和一致性,放弃分区:除非不是分布式架构,或者应用在一个永不会通信故障的网络中(理想),只有个别场景符合,当前的互联网架构显然不符合使用
- CP: 保证一致性和分区容忍性,放弃可用性:当节点间不可通信时,进行阻塞,直到通信恢复,期间无法再对外提供服务,用户体验不好,如A转账给B,只有A扣款成功并B收款成功,整个事务才算完成,显然耗费资源
- AP: 保证可用性和分区容忍性,放弃强一致性(使用最终一致性):给出一个用户可以忍受的时间,时间内达成数据的最终一致性,比如跨行转账,并不是立刻到账,可能是明天,或者2小时内到账
# 一致性的妥协——最终一致性和Base原则
- BA(Basically Available)基本可用:系统在绝大部分时间应处于可用状态,允许出现故障损失部分可用性,但保证核心可用。
- S(Soft State)软状态:数据状态不要求在任何时刻都保持一致,允许存在中间状态,而该状态不影响系统可用性。对于多副本的存储系统而言,就是允许副本之间的同步存在延时,并且在这个过程中系统依旧可以响应客户端请求。
- E(Eventual Consistency)最终一致性:尽管软状态不要求分布式数据在任何时刻都保持一致,但经过一定时间后,这些数据最终能达到一致性状态。 BASE理论的核心思想是:把分布式系统的可用性放在首位,放弃CAP中对数据强一致性的追求,只要系统能保证数据最终一致。
# 幂等性
在微服务架构下,不同微服务间会有大量的基于http,rpc或者mq消息的网络通信,接口的重复调用以及消息的重复消费可能会经常发生。
微服务架构应该具有幂等性,当接口被重复调用时,消息被重复消费时,对系统的产生的影响应该和接口被调用一次,消息被消费一次时一样。
# 如何解决幂等性问题
全局唯一ID。根据业务生成一个全局唯一ID,在调用接口时会传入该ID,接口提供方会从相应的存储系统比如Redis中去检索这个全局ID是否存在,如果存在则说明该操作已经执行过了,将拒绝本次服务请求;否则将相应该服务请求并将全局ID存入存储系统中,之后包含相同业务ID参数的请求将被拒绝。
数据库表唯一键。这种方法适用于在业务中有唯一标识的插入场景。比如在支付场景中,一个订单只会支付一次,可以建立一张去重表,将订单ID作为唯一索引。把支付并且写入支付单据到去重表放入一个事务中,这样当出现重复支付时,数据库就会抛出唯一约束异常,操作就会回滚。这样保证了订单只会被支付一次。
多版本并发控制适合对更新请求作幂等性控制,比如要更新商品的名字,这是就可以在更新的接口中增加一个版本号来做幂等性控制