开发者学堂课程【高校精品课-西安交通大学-数据库理论与技术:第四课】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/12/detail/15860
第四课(二)
内容介绍
一、CAP 定理
二、CAP 定理的起源
三、CAP 定理:鱼和熊掌不可兼得
四、CAP 定理:示例
五、CAP 定理:选择放弃
六、服务器一致性
七、一致性哈希
四、CAP 定理:示例
有两台机器,有两个 V0,有两个变量,在正常情况下,操作过程如下(如上图所示):
A 将V0更新,数据值为V1;G1服务器发送消息 m 给G2,数据V0更新为V1;B 读取到G2中的数据V1。拿饭卡的例子来说,V0相当于余额,吃了一次饭刷新了,刷新完后传过去两个值变得一样。
但网断时,
发生网络分区故障,即断网,G1发送的消息不能传送到 G2上。这样数据就处于不一致的状态,B 读取到的就不是最新的数据。如果采用阻塞,加锁等机制(比如卡在断网时,可以锁死)来保证数据一致性,就会影响系统可用性。正如查询卡里余额,一边是100元,另一边可能为50元,数据不一致。
五、CAP 定理:选择放弃
放弃P:如果想避免分区容错性问题的发生,一种做法是将所有的数据(与事务相关的)都放到一台机器上。虽然无法100%地保证系统不会出错,但不会碰到由分区带来的负面效果。当然,这个选择会严重影响系统的扩展性。
放弃A:一旦遇到分区容错故障,那么受到影响的服务需要等待数据一致,因此在等待期间系统无法对外提供服务。
放弃C:这里所说的放弃一致性,并不是完全放弃数据的一致性,而是放弃数据的强一致性,而保留数据的最终一致性。 以网络购物为例,对只剩最后一件库存的商品,如果同时接收到了两份订单,那么较晚的订单将被告知商品售罄。
一致性模拟背景
当我们在生产线上用一台服务器来提供数据服务的时候,会遇到如下两个问题:
一台服务器的性能不足以提供足够的能力服务所有的网络请求。
我们总是担心这台服务器停机,造成服务不可用或是数据丢失。
通常,我们会通过两种手段来扩展数据服务:
1.数据分区:就是把数据分块放在不同的服务器上(如:uid % 16, 一致性哈希等)。
2.数据镜像:让所有的服务器都有相同的数据,提供相当的服务。
那么问题来了:
在数据分区的方案中:如何支持分布式事务(Two- Phrase Commit),两阶段提交第一阶段为投票,第二阶段为表决。
数据镜像方案中:如何保证数据的一致性
只讨论在数据冗余情况下考虑数据的一致性和性能的问题。简单说来:
要想让数据有高可用性,就得写多份数据。如果所有机器都有,那么就近就可以投稿。更新时都要更新,
写多份的问题会导致数据一致性的问题。
数据一致性的问题又会引|发性能问题。
数据一致性分类
强一致性
强一致性(即时一致性)假如 A 先写入一个值到存储系统,存储系统保证后续的读操作都返回最新值。
例如:文件系统,RDBMS 都是强一致性的。
弱一致性
假如 A 先写入了一个值到存储系统,存储系统不能保证后续读取操作能够读到最新值。这个值已改了,但还没传播到其他地方,比如一个数据北京、西安、上海都放了一个,北京改了,但可能两个小时后再传到西安,此时在西安读取的还是改之前的值。这种情况下有一个“不一致性窗口”,比如北京改完后,保证两个小时之后传到西安,在这两个小时之内读取时是不一致的,两个小时后数据传播过来,则数据一致了。它特指从A写就入值,到后续操作 A,B,C 读取到最新值这一段时间 。例如:某些 cache 系统,网络游戏其它玩家的数据和你没什么关系,或是百度搜索引擎。数据引擎不断更新,可能在搜索时还没来得及更新,所以搜索到的是以前的信息,但这个不会对自己造成多大损失。可能等两个小时后再搜索,结果就变了,第一次搜索时数据已经改变,只不过百度的搜索引擎还未更改,所以搜索到的结果是旧的。比如听到一个消息,想去上网证实,结果没有搜索到,过一会儿搜索又出来了。
最终一致性
最终一致性即最终保证肯定一样,时间延迟可能很长。最终一致性是弱一致性的一种特例。假如 A 首先 write 了一个值到存储系统,存储系统保证,如果在A,B,C后续读取之前没有其他写操作更新同样的值的话,最终所有的读取操作都会读取到 A 写入的最新的值。这种情况下,如果没有失败发生的话,“不一致性窗口”的大小依赖以下的几个因素:
交互延迟
系统的负载
复制架构中 replica 的个数(可以理解为 master/slave模式中,slave 的个数)
例如:DNS,电子邮件。
一致性模型——强一致性
Two Phase Commit:
强一致性是利用两个阶段来提交,一个段落往往有多个参与者来做,在分布式系统中,为了保持事务的 ACID 特性,需要引入一个作为协调者的组件来统一掌控所有节点(称作参与者)的操作结果并最终指示这些节点是否要把操作结果进行真正的提交(比如将更新后的数据写入磁盘等等)。分布系统为做一件事,大家都需做同样的动作,要提交都提交,保证步调一致。通过两阶段提交协议来完成。
其他数据一致性分类
Causal consistency(因果一致性)
如果 Process A 通知 Process B 它已经更新了数据,那么 Process B 的后续读取操作则读取 A 写入的最新值,而与 A 没有因果关系的 C 则可以最终一致性。
Read-your- writes consistency(过程一致性)
如果 Process A 写入了最新的值,那么 Process A 的后续操作都会读取到最新值。但是其它用户可能要过一会才 可以看到。
Session consistency(会话一致性)
此种一致性要求客户端和存储系统交互的整个会话阶段保证 Read-your writesconsistency
例如:Hibernate 的 session 提供的一致性保证就属于此种。
Monotonic read consistency(简单读一致性)
此种一致性要求如果 Process A 已经读取了对象的某个值,那么后续操作将不会读取到更早的值。
Monotonic write consistency(简单写一致性)
此种一致性保证系统会序列化执行一个 Process 中的所有写操作。