为什么NoSQL不支持事务
1. 背景
看书《Neo4j权威指南》的时候,发现个问题:日常的NoSQL都不支持事务(ACID)。
2. 问题
事务对数据的存储过程是有利的,既然事情是有利的,理论上存储型数据库都应该支持事务。但事实上是只有很少的一部分数据库支持事务,比如 MySQL,Neo4j,并且MySQL也只有部分存储引擎才支持事务,比如InnoDB。
那么为什么一般NoSQL都没有实现事务呢? 比如常用的几个:Redis,MangoDB,HBase,ES 等。
一起在网上查查,看有没有相关的文档介绍。
3. 什么是事务(ACID)
先复习下什么是事务(ACID)呢?
事务是由一系列对系统中数据进行访问或者更新操作组成的一个程序执行逻辑单元(Unit),也就是说,事务是要求这一组程序要么都执行成功,要么都不执行(执行失败)。
ACID,是指 数据库管理系统 ( DBMS )在写入或更新资料的过程中,为保证 事务 (transaction)是正确可靠的,所必须具备的四个特性:
- 原子性 Atomicity :要保证事务中包裹的逻辑,要么全部执行成功,要么全部都不执行。
- 一致性 Consistency:要保证事务在执行前后,数据库都要处于正确状态,满足完整性约束。
- 隔离性 Isolation:多个事务并发执行的时候,一个事务不应该影响另一个事务,保证所有事务都好像在独立运行。
- 持久性 Durability:事务处理完成,对数据的修改是永久性的,即使系统故障,都不会丢失。
我到现在也没有理解,为什么是ACID,而不是AID或者C。在我的理解中,AID是为了保证C存在的,而且只要保证了AID,就能得到C的结果,所以我认为C和AID并不是一个层次上的概念。接下来的解释,都是基于我这种理解范畴的。
下面的话参考引用了知乎上的一篇文章,跟我的理解是一样的,文章链接
ACID里的AID都是数据库的特征,也就是依赖数据库的具体实现.而唯独这个C,实际上它依赖于应用层,也就是依赖于开发者.这里的一致性是指系统从一个正确的状态,迁移到另一个正确的状态.什么叫正确的状态呢?就是当前的状态满足预定的约束就叫做正确的状态.而事务具备ACID里C的特性是说通过事务的AID来保证我们的一致性.
做个比喻事务就好比一个保镖,我们提到事务就会说ACID,而我们提到保镖会说强壮,保护安全,好功夫,踏实.这里强壮,好功夫和踏实都是保镖自己的特征,而安全是属于你的,而你通过保镖的特征来保护你的安全.
这里我们举个大家都在说的财务系统的例子.
A要向B支付100元,而A的账户中只有90元,并且我们给定账户余额这一列的约束是,不能小于0.那么很明显这条事务执行会失败,因为90-100=-10,小于我们给定的约束了.
这个例子里,支付之前我们数据库里的数据都是符合约束的,但是如果事务执行成功了,我们的数据库数据就破坏约束了,因此事务不能成功,这里我们说事务提供了一致性的保证.然后我们再看个例子
当然,也可以把C解释成与AID一致的层面,比如:数据一致性就是数据要满足一定约束条件,如果事务的执行违反了这个约束条件,那么事务应该失败,这样理解的话,就是ACID是一个层面的特性了。
不管是“AID 是特性,C是目的”,还是“ACID 都是 特性”,都看个人理解,然而这种个人理解无论是哪种,都是有利于“事务”的制定和发展的。
至于ACID怎么实现,这里不做赘述。
4. 关系型数据库和非关系型数据库
NoSQL又叫非关系型数据库,再回一下关系型数据库和非关系型数据库对的区别是什么。
关系数据库管理系统(RDBMS)能够非常有效地管理事务数据。关系数据库拥有原子性、一致性、隔离性和持久性(ACID)属性,这些属性使关系数据库成为企业管理数据的主要产品,并使它们跨越各种关键的业务功能。例子包括企业资源规划(ERP)、客户关系管理(CRM)、数据仓库和许多类似的应用程序。
NoSQL数据库不具备关系型数据库的全部特性,但是它能提供一个快速检索信息的机制。NoSQL数据库是高度分布的数据库,它能在普通商用硬件上运行,并只提供很少事务支持或没有事务支持;NoSQL支持非常灵活的模式定义(甚至不存在模式定义),因此它们非常适合快速存储、检索和更新非结构化的数据
5. 为什么NoSQL不支持事务(ACID)
NoSQL面对的场景与RDBMS并不相同,NoSQL主要应用场景在于 大数据量,高并发等场景,即 集群化,分布式是必然的架构。而这也是NoSQL不支持事务的本质原因。
因为分布式情况下:一系列写操作中访问的数据可能位于不同的分区服务器,这样的事务就变成分布式事务,在分布式事务中实现原子性需要彼此协调,而协调是耗费时间的,每台机器在一个大事务过程中必须依次确认,这就需要一种协议确保一个事务中没有任何一台机器写操作失败,这种协调是昂贵的,会增加延迟时间,关键问题是,当协调没有完成时,其他操作是不能读取事务中写操作结果的,针对分布式事务的分布式协调对整体数据库性能有严重影响,不只是吞吐量还包括延迟时间,这样大部分NoSQL数据库因为性能问题就选择不提供分布式事务。
换句话说,ACID就是关系型数据库的规则,不能套用到非关系型数据库上。
6. MySQL 是否支持分布式
广义上讲,MySQL是支持分布式的,分布式CAP理论下,它实现了CA。狭义上讲,MySQL是不支持分布式的,因为分布式理论中,P是必不可少的,也就是说,只有AP和CP可选,而属于CA的MySQL并不能说是支持分布式。同时,也有人说,正是因为MySQL是CA系统,所以MySQL可以支持ACID。也正是因为NoSQL大都是CP系统者是AP系统,所以NoSQL没办法支持ACID。
说明:虽然MySQL有集群化部署,但写操作的水平扩展只能依靠sharding(分库分表),但再怎么分,对数据的写永远是单机的(即一条数据只会写在一个服务器上)。
X. 参考文档
- http://www.codebaoku.com/it-mysql/it-mysql-193184.html
- https://www.cnblogs.com/cciejh/p/acid.html
- https://blog.51cto.com/u_15064656/4743241
- https://www.zhihu.com/question/30272728/answer/72476703
- https://jishuin.proginn.com/p/763bfbd5d83c
- https://cloud.tencent.com/developer/article/1630745