NoSQL中的CAP思想
NoSQL中的CAP
关系型数据库的ACID
传统关系型数据库中事务有四个重要的特性,简称ACID,即
- 原子性 : 事务是一个不可分割的工作单位,事务中的操作要么都成功,如果有一个执行失败,所有的SQL将都被撤销,恢复到事务开始的状态
- 一致性 : 事务前后数据的完整性必须保持一致。 例如转账前AB两账户金额之和是2000元,事务结束后,金额之和仍然是2000元
- 隔离性:当多个用户并发的访问数据库时,数据库为每一个用户开启的事务之间是隔离的,一个事务不能被其他事务的操作所干扰
- 持久性 : 持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响 , 即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。
CAP简介
- C:(Consistency)强一致性,这和传统数据库中的C概念类似,在分布式系统中,A把记录服务器N1中的数据库V1中的0改成1,服务器之间需要通信,将服务器B1中V1的记录也改成1,用户B读不管是哪台服务器中的记录V1,也必须是1,这就是强一致性。
- A:(Availability)可用性,意思是在分布式系统中,用户不管是向哪台服务器发出请求,只要是服务器收到请求,就必须响应, 定义:非故障的节点在合理的时间内返回合理的响应
- P:(Partition tolerance)分区容错性,即分布式系统在遇到某服务器节点或网络分区故障,例如丢包,连接中断的时候,剩余的服务器节点仍然能够正常运转,对外提供满足一致性或可用性的服务。对于用户而言不会有任何影响
由于在复杂网络环境中,不可能不存在完全不丢包的情况,其次没有人可以保证网络环境百分百不会出现任何问题,所以,分区容错性是必须要满足的,CAP理论的核心就是:一个分布式系统不能同时满足CAP这三个特性,只能同时较好的满足其中的两个,所以也叫做三进二,但是由于分错容错性是必须满足的,因此也被叫做二进一。
为什么不能同时满足CAP
不能同时满足CAP的原因是因为分布式系统中必须满足P,也就是分区容错性的原因,因为可能出现网络通信失败。假设此时分布式系统中有两台服务器N1 N2,假设N1和N2之间通信的时候网络突然出现故障,有用户向N1发送数据更新请求,那N1中的数据DB0将被更新为DB1,由于网络是断开的,N2中的数据库仍旧是DB0;如果这个时候,有用户向N2发送数据读取请求,由于数据还没有进行同步(一致性),应用程序没办法立即给用户返回最新的数据DB1,怎么办呢?有二种选择,第一,牺牲数据一致性,响应旧的数据DB0给用户;第二,牺牲可用性,阻塞等待,直到网络连接恢复,数据更新操作完成之后,再给用户响应最新的数据DB1。以上就是不能同时满足CAP的原因
CAP的选择策略
-
CA :舍去分区容错性,这一点虽然保证了一致和可用,例如MySQL等关系型数据库,但是却放弃了系统的拓展性,只能用于单点,无法部署子节点,这和分布式系统的设计理念相违背
-
CP:舍去可用性,强制要求一致性,由于有P,在网络堵塞或者丢包,消息丢失的时候, 就要牺牲用户的体验,等待所有数据全部一致了之后再让用户访问系统 。事实上,Redis就是这么设计的一个分布式系统,因为redis一般是和MySQL等关系型数据库相结合,利用redis的高性能,用于减少关系型数据库的读写访问压力,而关系型数据库有一点最基本的要求则是满足一致性,如果一个分布式系统连这个标准都达不到,那么直接采用关系型数据库就好,没必要再浪费资源来部署分布式数据库。
-
AP:要高可用并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。放到实际应用中就是抢购场景,可能前几秒你浏览商品的时候页面提示是有库存的,当你选择完商品准备下单的时候,系统提示你下单失败,商品已售完。这其实就是先在 A(可用性)方面保证系统可以正常的服务,然后在数据的一致性方面做了些牺牲,虽然多少会影响一些用户体验,但也不至于造成用户购物流程的严重阻塞。或者一些应用不关心,不太重视的数据,例如点赞数,浏览数等,如果为了追求强一致性,放弃了可用性,网站瘫痪了,贼得不偿失,所以大部分网站都是弱一致性+AP
总结:因此引入redis的作用就是,用redis的一致性尽可能的保证AP的一致性,并且redis的高性能减少读写压力,将数据存进传统数据库里完成CA。
BASE策略
为了解决关系型数据库由于一致性导致的可用性降低的问题的解决方案,是基本可用,软形态,最终一致性的缩写,思路是放松对某一时刻一致性的要求来换取可用性和系统带的性能,等该时刻过去之后,再保证最终数据一致性,例如淘宝双11的浏览量,等等这些数据,在0点时刻不关注这些数据,尽可能为可用性服务,保证服务器不崩,等高峰期过后,比如说第二天,再将这些数据同步,完成最终一致性。