大家好,我是大圣,很高兴又和大家见面。
在我们的上一篇 《并发编程之锁:守护数据的魔法》文章中,我们探讨了并发编程中的魔法力量——锁,展现了它如何巧妙地守护我们的数据,确保在并发环境下的数据安全性和一致性。但是,仅仅依赖锁可能会带来性能瓶颈,特别是在高并发的场景下。
那么,有没有一种机制,既能保证数据的一致性,又不牺牲太多的性能呢?答案是有的。今天,我们将探讨另一种强大的技术——MVCC(多版本并发控制),它在许多现代数据库中被广泛应用,提供了一个既高效又安全的方法来处理并发读写操作。
MVCC
举例理解 MVCC
场景:假设你正在使用一个在线购物应用。这个应用允许多个用户同时浏览和购买商品。其中,一款叫做 “魔法鼠标” 的商品目前只剩下1件库存。
事件1:用户A决定购买这款魔法鼠标,并点击了购买按钮。与此同时,系统开始处理用户A的订单。
事件2:在系统完成用户A的订单处理之前,用户B也看上了这款魔法鼠标,并打算购买。
在传统的锁定机制下,用户B在用户A完成订单之前可能会被阻止访问该商品信息或看到一个 “等待锁定” 的消息。这显然不是一个好的用户体验。
但是在MVCC的设计下,事情就会有所不同。
MVCC 是如何处理的:
-
当用户A决定购买魔法鼠标时,系统会为这个操作创建一个"版本",并开始处理订单。
-
当用户B几乎同时想要查看或购买这款魔法鼠标时,由于MVCC可以提供数据的多个版本,用户B会看到用户A操作前的数据版本,也就是商品仍然是可用状态。
3.当用户A的订单处理完成,库存减少到0,这个数据的版本会被更新。
4.如果此时用户B点击购买,系统会再次检查当前的数据版本,并告诉用户B商品已经售罄。
通过MVCC,我们可以让多个用户在几乎同一时间进行读和写操作,而不会互相阻塞。这提高了系统的吞吐量,并为用户提供了流畅的体验。
专业定义
MVCC (Multi-Version Concurrency Control) 是一种用于控制多个并发事务访问数据库中同一条记录时的并发控制方法。它通过为每个事务提供该记录的一个“快照”来避免其他事务所作的修改,从而使每个事务都在它的私有快照上工作。
这样,多个事务可以同时读取相同的记录,而无需等待其它事务完成。MVCC 的目标是提高并发性能,特别是在只读事务中,而不是通过使用锁和阻塞来解决并发冲突。很多现代的数据库系统,例如 PostgreSQL 和 MySQL 的 InnoDB 存储引擎,都使用了 MVCC 来实现事务。
MVCC 的设计思想
MVCC 的设计思想的核心是:“多版本”,为数据的每一个变化创建版本。这样,当多个事务尝试读取同一数据项时,它们可以读取到对应于自己的事务开始时间之前的最新版本。这避免了长时间的锁等待,并增强了数据库的并发能力。以下是 MVCC 的主要设计思想:
1. 数据有多个版本
每次数据更改不会直接覆盖原数据,而是创建一个新版本。
2. 读不阻塞写,写不阻塞读
因为每次读取都可以找到一个合适的数据版本,所以读和写操作不会互相干扰。
3. 避免锁的冲突
不需要为读和写操作设置锁,因此提高了效率。
4. 清理旧数据
随着时间的推移,旧的数据版本会被清理掉,以节省空间。
5. 保持数据的一致性
即使有很多并发操作,用户也总能看到一致的数据状态。
这样,MVCC允许数据库在高并发条件下维持性能,同时确保数据的一致性和完整性。
MVCC 解决了什么问题
MVCC 旨在解决数据库中的并发读写问题,特别是在高并发的OLTP(在线事务处理)系统中。MVCC 允许多个读操作与单个写操作并发进行,而不需要对整个读/写操作进行加锁。这大大提高了并发性能。
问题
在传统的数据库锁定机制中,当一个事务正在对一条记录进行写操作时,其他所有读或写该记录的操作都必须等待。这可能导致大量的等待时间,特别是在高并发系统中。
解决方法 - MVCC
通过为每个读/写操作提供一个独特的版本,MVCC 允许多个事务并发读取同一条记录的不同版本,同时另一个事务正在更新它。
例子说明
假设有一个图书馆数据库,记录中有一个字段表示某本书的可用数量。
1.早上:张三想借阅《哈利·波特》。当前系统中,《哈利·波特》的可用数量是 5 本。
2.中午:李四也来借阅《哈利·波特》,同时张三还书。
3.下午:王五查询《哈利·波特》的可用数量。
在传统的锁机制中:
如果张三正在借书(写操作),那么李四和王五都需要等待他完成操作。因为写操作会锁定数据,阻止其他读或写操作。
在 MVCC 中:
1.张三、李四和王五可以几乎同时进行他们的操作。
2.当张三开始借书时,他会看到书的数量为5。
3.当李四同时来借书,他也会看到书的数量为5,因为张三的事务还没有提交,所以李四看到的是这个数据的一个早期版本。
4.如果张三先提交事务,书的数量变为4,然后李四提交事务,数量变为3。当王五查询时,他会看到最新的版本,即可用数量为3。
MVCC 允许多个用户看到数据的不同版本,从而实现高并发,减少等待时间。同时,它确保每个事务看到的数据都是一致的,而不会受到其他并发事务的影响。
MVCC 和锁对比
我们举个例子来看一下锁和MVCC工作的流程。
数据库查询场景:
假设我们有一个大型的在线银行系统,用户经常查询自己的交易记录,而银行后台则定期更新这些记录,例如计算每日的利息。
使用传统的锁机制
当银行后台尝试更新一条记录时,它会锁定那条记录。
如果此时用户尝试查询自己的交易记录,他们必须等待,直到锁被释放。这将导致查询的延迟,用户可能会因此而不悦。
使用MVCC
当银行后台开始更新记录时,它不会立即锁定该记录。相反,它会创建一个新的版本。
同时,用户查询自己的交易记录,他们会立即看到该记录的旧版本,而不会感受到任何延迟。
当银行后台完成更新后,新版本变为最新的,后续的查询将返回新的记录
小结
MVCC的主要优势在于读操作不会被阻塞,这在只读查询比写入操作更频繁的系统中特别有价值。而在使用锁的情况下,即使是简单的读操作也可能因为等待写锁而被阻塞。
但是,MVCC并不是万能的。它有自己的开销(如版本管理),并且在某些场景下可能不如传统的锁机制高效。选择使用哪种技术取决于应用的具体需求和工作负载特点
MVCC 和锁的使用场景
MVCC 和 锁 (Locking) 是两种在数据库领域广泛使用的并发控制技术。它们各自有自己的优势和使用场景。
MVCC 的使用场景:
1. 读取操作为主的应用
在大多数情况下,MVCC 允许读操作不受写操作的阻塞,这使得在读密集型的应用中可以获取更好的性能。
2. OLAP 系统
在线分析处理(OLAP)系统,例如数据仓库,经常执行复杂的查询,这些查询可能需要长时间运行。使用MVCC可以避免这些长时间运行的查询阻塞其他操作。
3. 高并发应用
在高并发场景中,MVCC 可以减少事务之间的冲突,从而提高系统的吞吐量。
锁的使用场景:
1. 写入操作为主的应用
在一些情况下,如银行交易系统,保证数据完整性和一致性比性能更重要。在这样的系统中,使用锁来确保在修改数据时,其他操作不能并发地访问或修改相同的数据。
2. OLTP 系统
在线事务处理(OLTP)系统,如电子商务网站,需要快速地处理大量小型事务。在这样的场景中,锁可以确保事务的隔离性。
3. 控制数据访问的顺序
在某些情况下,可能需要控制数据访问的顺序。例如,一个系统可能需要先处理高优先级的请求。在这样的场景中,可以使用锁来控制对数据的访问。
结合使用:
很多现代数据库系统实际上结合使用了 MVCC 和锁。例如,PostgreSQL 使用 MVCC 来提供并发控制,但在某些情况下(例如,当两个事务试图修改相同的行时)它也会使用锁。
结合使用 MVCC 和锁可以为数据库提供更大的灵活性,并允许它在不同的场景中提供最佳的性能和一致性。
总结
本文主要说了 MVCC 的一些概念,相信大家看了这些概念对 MVCC 有了初步的认识。但是,大家千万不要被这些概念搞糊涂了。
回归问题本质
我们还应该回归 MVCC 和 锁的本质,它们的本质是在多个线程操作同一个数据的时候,会出现数据不一致的问题,MVCC 和锁就是为了解决这种数据不一致的。
MVCC 和锁 是怎么保证多线程操作同一个数据的时候数据的一致性呢?这就是我们这篇文章和上一篇文章所说的。看了这两篇文章,想必大家心里都有所理解了。
串联一下知识点
那为什么会出现多线程呢?这样因为在高并发的场景下,我们的系统在一段时间内接收了大量请求,为了我们的系统能够抗住高并发的请求,我们可以用多线程技术来短时间解决这些高并发的请求,让我们的系统可以正常运行。
那多线程是怎么解决高并发请求的呢?这部分知识 《多线程、异步编程、并发读写 新认识 》我们在多线程和异步编程那一篇文章里面也说了。
要想理解高并发这个概念的话,我们又需要对并行和并发这两个概念有清晰的了解,我们在 《并发、并行、高并发 新认识 》 文章里面也说过。
小结
经过我上面这样讲解一下MVCC 和锁的本质,你们就会发现我们就能把前面四篇文章所讲的知识点都能串联到一起了。
那下面我问大家几个问题,希望可以让大家对这些概念有更好的理解:
1.MVCC 和 锁 解决了什么问题
2.多线程解决了什么问题
3.高并发这个概念怎么理解?
大家把这三个问题回答好了,就可以把我这四篇文章说的东西理解透彻了。
彩蛋
大家理解了这些概念之后,接下来,我会从大数据源码的角度来给大家说一下在高并发的情况下,Flink 写 HDFS 和 Flink 写 Hudi 是怎么保证数据一致性的。
这样的话可以让大家对这些概念不止停留在一些概念的阶段,还可以落地我们的想法,这才是真正的学习。
可以给大家剧透一下,其实用到的方法就是我们这四篇文章里面所说的东西。
下一篇我会对 Flink Sink HDFS 的源码进行讲解,这里面会涉及到一些 HDFS 的概念,大家可以先去我公众号的 《 HDFS基础知识(上)》 文章里面看一下。
最后欢迎大家一起来讨论呀,可以关注微信公众号:大圣数据星球 进群讨论上面三个问题的答案。
共同学习,写下你的评论
评论加载中...
作者其他优质文章