澄清数据库一致性概念

0 前言

最近在和同学讨论分布式事务以及分布式一致性时产生了分歧. 我的疑问是

2PC这种算法有没有保证数据的一致性呢? 如果保证了保证的是什么样的一致性呢?

而同学的回答是

2PC是一种事务提交协议, 是用来保证分布式事务的原子性的, 和数据的一致性没有关系

这样的回答并不能认我满意, 我不知道自己为什么会认为2PC与数据的一致性有关系, 我总感觉它们之间是有关系的.

而同学也说不清为什么两者之间没有关系.

冷静下来想一想, 发现, 其实两个人对数据的一致性这个概念的理解是片面和模糊的.

本文的目的是澄清这个概念, 进而开头的问题也可以做出回答了.

1 一致性是什么?

一致性这个概念在不同的上下文中含义是不同的, 这里只是说明在数据库这个上下文中的含义, 再细分一下, 就是单机数据库分布式数据库上下文中的含义

2 单机数据库下一致性的含义

在单机数据库下, 事务有ACID的性质. 其中C就是一致性, 而这里说的一致性, 有两种含义

原子一致性: 拿最经典的转账举例, 一个事务是A向B转100块钱, 事务的原子性保证了要么全部执行, 要么全部不执行, 不存在A扣了钱, B没有加钱的情况. 这里, 谈讨原子一致性时有个前提, 即只有一个事务, 当涉及到并发时, 仅仅有原子性是无法保证一致性的.

并发一致性: 当有并发事务的情况下, 事务之间的操作可能产生互相影响, 如两个事务同时修改一份数据, 可能导致一个事务的修改覆盖了另一个事务的修改. 事务的隔离性保证了并发的一致性, 但事务有四种隔离级别, 而不同隔离级别的选择对一致性的保证程度是不同的, 如Read Uncommited下, 一个事务可能读到另一个事务还未提交的数据.

所以, 谈到一致性时, 需要明确一下, 是指的原子一致性, 还是并发一致性.

3 分布式数据库下一致性的含义

在说分布式数据库下一致性含义时, 先解释一下为什么需要分布式数据库. 主要有两点考虑

  1. 性能问题: 一台数据库服务器性能不行了, 需要多台
  2. 容灾问题: 防止一台数据库挂了之后不能提供服务了.

针对以上两个问题, 可以使用三种思想来处理

  1. 数据分区: 不同的数据放在不同的服务器上, 这样可以解决性能问题
  2. 数据镜像: 同一数据有多个备份
  3. 数据分区与数据分区结合使用

而无论是数据分区还是数据镜像, 在新的环境下, 会产生新的一致性问题

还是以A向B转账为例.

对于数据分区来说, 如果A, B的数据放在两台不同服务器上, 即一个事务操作涉及多台服务器的修改, 这时就需要有一种算法来保证要不两台服务器上的数据都正确修改了, 要不都没有修改.

对于数据镜像来说, 如果一台服务器发生了修改, 这种修改也要想办法同步到其它镜像上, 否则镜像上的数据就不一致了.

上面提出了三种思想, 而基于这三种思想可以衍生出很多很多的具体的实施方案, 由以上讨论可知, 不同的实施方案都要去解决一致性问题. 只是不同方案的难度不一样(这里忽略了性能问题, 性能也是一个很重要的权衡因素), 而以下文章中讨论了几种方案, 以及这几种方案是如何解决一致性问题的.

分布式系统的事务处理

以上面讨论知道, 单机情况下可以分为原子一致性并发一致性, 原子一致性由原子性来解决, 并发一致性由隔离性来解决. 那么文章中解决的一致性又是哪一种一致性呢?

其实, 文章中讨论一致性时只是假设只有一个事务, 比如对于Master-slave来说, 对Master的修改如何保证其它slave上的修改与回滚, 对于2PC来说, 如何保证在多个服务器上执行的Global Transaction要么全部执行, 要么全部不执行. 这其实类似于实现多机情况下的原子一致性. 而对于分布式存储下的并发事务可能导致的一致性问题并没有涉及.(TODO)

至此也可以回答开头的那么问题了

2PC这种算法有没有保证数据的一致性呢? 如果保证了保证的是什么样的一致性呢?

2PC算法只是保证了分布式事务的原子性, 可以说是保证了原子一致性, 和并发一致性无关, 所以算是部分保证了, 当然它和一致性也是有关系了.

4 分布式数据库的方案设计

自己感觉当要使用分布式数据库时, 到底使用哪一种方案, 需要结合具体的业务要求, 考虑如下几点

  1. 对性能的要求
  2. 对可用度的要求
  3. 对一致性的要求

如银行系统可能对一致性要求很高,性能要求不是那么高, 而对于互联网业务, 可能对一致性要求低, 但性能要求比较高.

如果现有的方案无法满足, 就需要自己去创造新方案了.

5 CAP原理与分布式存储的关系

CAP原理是说明了分布式存储的一个客观性质. 这里的C指的是强一致性, 对于分布式存储P是一定有的, 所以就在CA之间二选一, 而为了可用性, 一般选择A, 但这里并不是放弃了强一致性, 可以选择最终一致性, 使得经过一个时间窗口后, 数据回到正确的状态.

参考

  1. 数据库事务原子性、一致性是怎样实现的?
  2. 分布式系统的事务处理
  3. 谈谈对CAP定理的理解