如果你想真正得到一些知识,最好过滤一下你的信息,否则你只是在别人的思考中得意着。
获得多少并不取决于读了多少,而取决于思考了多少。
《暗时间》 刘未鹏
此系列学习分布式数据库30讲的笔记,导图是本文结构,具体细节在后文,可用导图回忆框架,具体细节再具体查看。
文章图片和部分内容来自极客时间,如有版权问题,请联系我删除。
欢迎加入学习
总览
BASE
BA 表示基本可用性(Basically Available),S 表示软状态(Soft State),E 表示最终一致性(Eventual Consistency):
基本可用性
系统某部分出现故障,其余部分系统仍然可以提供服务
软状态
是指数据处理过程中,存在数据状态暂时不一致的情况,但最终会
实现事务的一致性
最终一致性
数据更改经过一段时间后,各个副本经过操作,数据达成一致
总结
BASE 的意义只在于放弃了 ACID 的一些特性,从而更简单地实现了高性能和可用性,达到一个新的平衡。
但是,架构设计上的平衡往往都是阶段性的,随着新技术的突破,原来的平衡点也自然会改变。不用说分布式数据库,就连不少 NoSQL 也开始增加对事务的支持了
事务ACID
原子性
Atomicity:Either all the changes from the transaction occur (writes, andmessages sent), or none occur.
事务中的所有变更要么全部发生,要么一个也不发生
一致性
Consistency:The transaction preserves the integrity of stored information.
事务要保持数据的完整性
隔离性
Isolation: Concurrently executing transactions see the stored information as if they were running serially (one after another).
多事务并行执行所得到的结果,与串行执行(一个接一个)完全相同。
持久性
Durability:Once a transaction commits, the changes it made (writes and messages sent) survive any system failures.
一旦事务提交,它对数据的改变将被永久保留,不应受到任何系统故障的影
响。
总结
一致性是事务总体的阑述,虽然系统中没有针对性的设计者这个,但整体的设计就是为了保证一致性而设计的。
持久性,它是为了应对系统故障而存在的。
假如发生了故障,系统可以通过之前的日志操作恢复数据。
- 存储硬件无损、可恢复的故障。这种情况下,主要依托于预写日志(Write Ahead Log,WAL)保证第一时间存储数据。WAL 采用顺序写入的方式,可以保证数据库的低延时响应。WAL 是单体数据库的成熟技术,NoSQL 和分布式数据库都借鉴了过去。
- 存储硬件损坏、不可恢复的故障。这种情况下,需要用到日志复制技术,将本地日志及时同步到其他节点。实现方式大体有三种:第一种是单体数据库自带的同步或半同步的方式,其中半同步方式具有一定的容错能力,实践中被更多采用;第二种是将日志存储到共享存储系统上,后者会通过冗余存储保证日志的安全性,亚马逊的 Aurora 采用了这种方式,也被称为 Share Storage;第三种是基于 Paxos/Raft 的共识算法同步日志数据,在分布式数据库中被广泛使用。无论采用哪种方式,目的都是保证在本地节点之外,至少有一份完整的日志可用于数据恢复.
原子性在单体数据库中得到了解决,但分布式中还需要继续考虑
隔离性
隔离性分为多个隔离级别,较低的隔离级别就是在正确性上做妥协,将一些异常现象交给应用系统的开发人员去解决,从而获得更好的性能。
可以说,事务模型的发展过程就是在隔离性和性能之间不断地寻找更优的平衡点。我觉得,甚至可以说事务的核心就是隔离性。而不同产品在事务一致性上的差别,也完全体现在隔离性的实现等级上,所以我们必须搞清楚隔离等级具体是指什么
隔离性
ANSI SQL-92
未提交读
已提交读
可重复读
可串形化
脏读:
脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
不可重复读:
是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
幻读:
是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
经典论文 Critique:更严谨的隔离级别
-
重要的异常现象
- 幻读
Critique 对幻读的描述大致是这样的,事务 T1 使用特定的查询条件获得一个结果集,事务 T2 插入新的数据,并且这些数据符合 T1 刚刚执行的查询条件。T2 提交成功后,T1 再次执行同样的查询,此时得到的结果集会增大。这种异常现象就是幻读。
不少人会将幻读与不可重复读混淆,这是因为它们在自然语义上非常接近,都是在一个事
务内用相同的条件查询两次,但两次的结果不一样。差异在于,对不可重复读来说,第二
次的结果集相对第一次,有些记录被修改(Update)或删除(Delete)了;而幻读是第二
次结果集里出现了第一次结果集没有的记录 (Insert)。一个更加形象的说法,幻读是在第一
次结果集的记录“间隙”中增加了新的记录。所以,MySQL 将防止出现幻读的锁命名为间
隙锁(Gap Lock)。- 写倾斜
写倾斜是一种更不易察觉的更新丢失
-
隔离级别
- 快照隔离
-
技术实现
- 多版本并发控制
产品实现
可串形化
-
两阶段封锁协议(2pl)
-
单进程
- VoltDB
-
可串形化快照(SSl)
- CockroachDB
强一致性
对分布式数据而言,最高级别的一致性是严格串行化(Strict Serializable),Spanner 实
现的“外部数据一致性”可以被视为与 “Strict Serializable” 等效。但由于两条路径上各
自实现难度及性能上的损耗,少有分布式数据库在顶端汇合。即使强大的 Spanner 也提供
了有界旧一致性(Bounded Stale),用于平衡性能和一致性之间的冲突。
产品分类
总结
-
分布式数据库的一致性其实是数据一致性和事务一致性的融合
-
隔离性是事务的核心。降低隔离级别,其实就是在正确性上做妥协,将一些异常现象交
给应用系统的开发人员去解决,从而获得更好的性能。所以,除“可串行化”以外的隔
离级别,都有无法处理的异常现象