这是我参与「第五届青训营 」伴学笔记创作活动的第 11 天
这是我参与「第五届青训营 」伴学笔记创作活动的第 11 天
分布式概论
- 什么是分布式
- 分布式是系统是计算机程序的集合 这些程序利用多个独立计算节点的计算资源来实现共同的目标。可以分为分布式计算、分布式存储、分布式数据库等等
- 分布式的优势
- 去中心化
- 低成本
- 弹性(波峰波谷 调整资源分配)
- 资源共享
- 可靠性高
- 分布式的挑战
- 普遍的节点故障
- 不可靠的网络问题 (分布式中为三态 还有不确定状态)
- 异构的机械与硬件环境
- 安全问题
- 分布式存在的价值和意义
- 为什么我们需要分布式
- 数据爆炸下 对存储和计算有大规模的需求
- 低成本 可以构建在廉价的服务器之上
- 怎么去使用好分布式
- 分布式框架
- 成熟的分布式系统
- 我们使用的时候要注意什么
- 理清规模 负载 一致性要求等
- 明确稳定性要求,制定技术方案
- 为什么我们需要分布式
- 常见的分布式
- 分布式存储
- 分布式数据库
- 分布式计算
系统模型
- 故障模型
- 最终一致性和强一致性(又叫线性一致性)
最终一致性要求最后读取到的数据是正确的
线性一致性要求时刻读取到的数据均为正确的 一方读取到更新后的数据马上同步更新给其他端 (这个同步会带来延迟 可用性受到影响)
理论基础
三大分布式理论
- CAP理论
-
CA 传统的单机数据库
-
AP 放弃强一致性 注重用户体验的系统
-
CP 放弃可用性 比如钱财安全相关系统
-
CAP指出 我们不能100%的同时拥有CAP
-
- Base
- Base 倾向AP
- ACID
分布式事务
两阶段提交
为了使基于分布式系统架构下的所有节点在进行事务提交时保持统一性而设计
二阶段提交的三种假设
- 引入了协调者和参与者 并且相互进行网络通信
- 所有节点都采用预写式日志 且日志被写入后即被保存在可靠的存储设备之上
- 所有节点不会永久性损坏即使损坏后仍可以恢复
第一阶段 : Prepare阶段 第一阶段是“投票”阶段,即每个参与者检查事务的有效性,并决定是否投票给事务;
第二阶段 : Commit阶段 第二阶段是“提交”阶段,即如果所有参与者都投票给事务,则事务将被提交,否则事务将被取消。
故障维修: 如果协调者宕机: 调起新的协调者来
三阶段提交
三阶段提交与两阶段提交类似,但包括三个阶段:
- 第一阶段cancommit,
- 第二阶段precommit,
- 第三阶段commmit。
解决了单点故障问题和阻塞问题
另外引入了超时机制 在等待超时之后会继续进行事务的提交
三阶段提交比两阶段提交更安全,因为它可以更好地处理网络不稳定和故障情况。
MVCC
悲观锁:操作的过程中直接把数据锁住之道操作完成之后才会释放锁 上锁期间别人不能修改数据
乐观锁:不会上锁只是在执行更新的时候判断别人是否修改数据 只有冲突时才放弃操作
什么是MVCC?
MVCC,全称Multi-Version Concurrency Control,即多版本并发控制。MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。
MVCC在MySQL InnoDB中的实现主要是为了提高数据库并发性能,用更好的方式去处理读-写冲突,做到即使有读写冲突时,也能做到不加锁,非阻塞并发读
什么是当前读和快照读?
在学习MVCC多版本并发控制之前,我们必须先了解一下,什么是MySQL InnoDB下的当前读和快照读?
-
当前读:像select lock in share mode(共享锁), select for update ; update, insert ,delete(排他锁)这些操作都是一种当前读,为什么叫当前读?就是它读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。
-
快照读:像不加锁的select操作就是快照读,即不加锁的非阻塞读;快照读的前提是隔离级别不是串行级别,串行级别下的快照读会退化成当前读;之所以出现快照读的情况,是基于提高并发性能的考虑,快照读的实现是基于多版本并发控制,即MVCC,可以认为MVCC是行锁的一个变种,但它在很多情况下,避免了加锁操作,降低了开销;既然是基于多版本,即快照读可能读到的并不一定是数据的最新版本,而有可能是之前的历史版本
说白了MVCC就是为了实现读-写冲突不加锁,而这个读指的就是快照读, 而非当前读,当前读实际上是一种加锁的操作,是悲观锁的实现
当前读,快照读和MVCC的关系 -
准确的说,MVCC多版本并发控制指的是 “维持一个数据的多个版本,使得读写操作没有冲突” 这么一个概念。仅仅是一个理想概念
-
而在MySQL中,实现这么一个MVCC理想概念,我们就需要MySQL提供具体的功能去实现它,而快照读就是MySQL为我们实现MVCC理想模型的其中一个具体非阻塞读功能。而相对而言,当前读就是悲观锁的具体功能实现
-
要说的再细致一些,快照读本身也是一个抽象概念,再深入研究。MVCC模型在MySQL中的具体实现则是由 3个隐式字段,undo日志 ,Read View 等去完成的,具体可以看下面的MVCC实现原理。
MVCC能解决什么问题,好处是?
数据库并发场景有三种,分别为:
- 读-读:不存在任何问题,也不需要并发控制
- 读-写:有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,幻读,不可重复读
- 写-写:有线程安全问题,可能会存在更新丢失问题,比如第一类更新丢失,第二类更新丢失
MVCC带来的好处是?
多版本并发控制(MVCC)是一种用来解决读-写冲突的无锁并发控制,也就是为事务分配单向增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读该事务开始前的数据库的快照。 所以MVCC可以为数据库解决以下问题
- 在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性能
- 同时还可以解决脏读,幻读,不可重复读等事务隔离问题,但不能解决更新丢失问题
小结一下咯
总之,MVCC就是因为大牛们,不满意只让数据库采用悲观锁这样性能不佳的形式去解决读-写冲突问题,而提出的解决方案,所以在数据库中,因为有了MVCC,所以我们可以形成两个组合:
- MVCC + 悲观锁:MVCC解决读写冲突,悲观锁解决写写冲突
- MVCC + 乐观锁:MVCC解决读写冲突,乐观锁解决读写冲突
这种组合的方式就可以最大程度的提高数据库并发性能,并解决读写冲突,和写写冲突导致的问题
共识协议
分布式实践
这两部分还是不够了解 等了解后再进行补全
参考资料
码风略丑 读者见谅 --2023/2/12