在传统的数据中,有ACID四大原则,在分布式中也有对应的CAP理论和BASE理论,这些都是分布式理论的基础~
一、ACID
ACID分别是Atomicity 原子性、Consistency 一致性、Isolation 隔离性、Durability 持久性,有了这几个特性,就保证了数据库的可靠。
原子性
原子性代表一系列的操作要么全做,要么全不做。比如,在银行转账,从一个账号扣钱,另一个账号加钱,这两个操作必须同时进行。否则就会出现账目对不上的情况。
一致性
一致性官方的描述是,事务执行后必须是从一个一致性状态转到另一个一致性状态。通俗点说就是保证整个系统在操作完成后,虽然处于不同状态,但仍保持一致。比如在转账情境中,从一个账号转出500,转入另一个账号,那么整个系统的金额不应该有变化。
隔离性
隔离性意味着多个并发之间是不可见的,相互隔离不被打扰。隔离性在数据库操作中还是很重要的,如果不考虑隔离性,可能会出现下面的问题:
1 2 3 4 5 6 7 8 9 10 11 脏读:事务T1 读取了事务T2 未提交的数据,结果事务T2 回滚了,T1 拿到了一个脏数据 不可重复读:事务T1 读取数据后,紧接着事务T2 就更新了数据,事务T1 再次读取的时候发现数据不一致了 幻读:这种一般发生在大批量修改的时候,比如事务T1 把所有的数据从1 修改到了2 ,结果修改的过程中,事务T2 插入了一条新数据1 。最后检查数据发现有一条数据没有修改过来。 针对这几种情况,数据库如Mysql提供了几种事务的隔离级别: Serializable (串行化):可避免脏读、不可重复读、幻读的发生。 Repeatable read (可重复读):可避免脏读、不可重复读的发生。 Read committed (读已提交):可避免脏读的发生。 Read uncommitted (读未提交):最低级别,任何情况都无法保证。 持久性 这种最容易理解了,事务提交后,结果就保存不变了。
二、CAP
在分布式系统中,也有类似ACID的特性,那就是CAP,他们分别是:
1 2 3 4 5 6 7 8 9 10 11 12 Consistency 一致性,强调进群节点中数据一致。在分布式中一致性又包括强一致性和弱一致性,强一致性就是指在任何时刻任何节点看到的数据都是一样的;弱一致性一般实现是最终一致性,即刚开始可能存在差异,但随着时间的推移,最终数据保持一致。 Availability 可用性,强调集群在任何时间内都正常使用 Partition Tolerance 分区容错性,即使某一部分集群坏掉,另一部分仍能正常工作。 这三个特性只能满足其中两个,牺牲另一个。大部分系统也都是如此: 一般来说分布式集群都会保证P优先,即集群部分节点坏死不影响整个集群的使用,然后再去追求C和A。因为如果放弃P——分区可用性,那不如就直接使用多个传统数据库了。事实上,很多微服务分库分表就是这个道理。 如果追求强一致性,那么势必会导致可用性下降。比如在Master -Slave 的场景中,Master 负责数据写入,然后分发给各个节点,所有节点都写入成功,才算写入,这样保证了强一致性,但是延迟也会随之增加,导致可用性降低。 因此在可用性和一致性之间,就出现了各种解决方案,如时序一致性、最终一致性等等。
三、BASE
前面由于分布式在CAP面前各种纠结,因此有人总结出了一套适合分布式的理论——BASE:
1 2 3 4 5 6 7 8 9 10 BA,Basically Available 基本可用,比如降低性能要求、或者功能特性来保证整体的服务可用。比如服务的降级、增加延迟、等待等等。 S,Soft State 软状态,允许出现中间状态,比如节点的不同副本之间同步存在延迟 E,Eventual Consistency 最终一致性,具体的方案有很多,如因果一致性、读己一致性、会话一致性、单调读一致、单调写一致。 对于这几种一致性,可以简单的说一下: 因果一致性:进程B对进程A 有依赖关系,那么B读取到的应该总是A 更新后的值 读己一致性:进程A 更新某个值后,它自己读到的应该是最新的值 会话一致性:在会话中进行操作,需要保证总是读取到最新的值 单调读一致:从系统读取某个值后,不应该读取到比它还旧的值 单调写一致:同一个进程对系统的写操作,需要保证顺序
参考:CAP原则(CAP定理) 、BASE理论