---
menu: 第三代分布式：NewSQL
title: 第三代分布式数据库：NewSQL
taxonomy:
    category: docs
---

从 2005 年开始，Google Adwords 开始基于 MySQL 搭建系统，这也推动了 MySQL 在 Google 内部的大规模使用。随着业务的发展，MySQL 集群越来越庞大，其中最痛苦的就是“数据再分片”，据说有一次谷歌对数据库的重新分片持续了 2 年才完成。于是谷歌痛定思痛，搞出了一个支持分布式事务和数据强一致性的分布式关系型数据库：Google Spanner。

2012 年，谷歌发布了 [Spanner 论文](https://ying-zhang.github.io/time/2013-Spanner-cn.pdf)，拉开了分布式强一致性关系型数据库的大幕。这个数据库过于厉害，以至于笔者第一次看到它机柜照片（图 9-6）的时候直接震惊了。

![](https://qn.lvwenhan.com/2023-01-29-16749898163761.jpg)
<center>图 9-6 Google Spanner 的机柜照片</center>

这套系统采用了 GPS 授时 + 2 台原子钟 + 4 台时间服务器，让分布在全球多个数据中心的 Spanner 集群进行相当精确的时间同步：基于 TrueTime 服务，时间差可以控制在 10ms 之内。这种真正的全球数据库可以做到即使单个数据中心完全失效，应用也完全无感知。

当然，如此规模的全球数据库全世界也没有几家公司有需求，如果我们只在一个数据中心内署数据库集群，时间同步可以很容易地做到 1ms 之内，原子钟这种高端货还用不到。

### 数据持久性的关键步骤——redo log

上一章我们说过，写入型 SQL 会在写入缓存页 + 写入磁盘 redo log 之后返回成功，此时，真正的 ibd 磁盘文件并未更新。所以，Spanner 使用 Paxos 协议在多个副本之间同步 redo log，只要 redo log 没问题，多副本数据的最终一致性就没有问题。

### 事务的两阶段提交

由于分布式场景下写请求需要所有节点都完成才算完成，所以两阶段提交是必须存在的。单机架构下的事务，也是某一旦一条 SQL 执行出错，整个事务都是要回滚的嘛。多机架构下这个需求所需要的成本又大幅增加了，两阶段提交的流程是这样的：

1. 告诉所有节点更新数据
2. 收集所有节点的执行结果，如果有一台返回了失败，则再通知所有节点，取消执行该事务

这个简单模型拥有非常恐怖的理论故障概率：一旦在第一步执行成功后某台机器宕机，则集群直接卡死：大量节点会被锁住。

Spanner 使用 Paxos 化解了这个问题：只要 leader 节点的事务执行成功了，即向客户端返回成功，而后续数据的一致性则会基于`prepare timestamp`（启动时间）和`commit timestamp`（提交时间）加上 Paxos 算法来保证。

#### 多版本并发控制（MVCC）

Spanner 使用时间戳来进行事务之间的 MVCC：为每一次数据的变化分配一个全球统一的时间戳。这么做的本质依然是“空间+时间”换时间，而且是拿过去的时间换现在的时间，特别像支持事后对焦的光场相机。

1. 传统的单机 MVCC 是基于单机的原子性实现的事务顺序，再实现的事务隔离，属于即时判断。
2. Spanner 基于 TrueTime 记录下了每行数据的更新时间，增加了每次写入的时间成本，同时也增加了存储空间。
3. 在进行多节点事务同步时，就不需要再和拥有此行数据的所有节点进行网络通信，只依靠 TrueTime 就可以用 Paxos 算法直接进行数据合并——基于时间戳判断谁前谁后，属于事后判断。

### Spanner 放弃了什么

Spanner 是一个强一致的全球数据库，那他放弃了什么呢？这个时候就需要 CAP 理论登场了。

> 一个分布式系统最多只能同时满足一致性（Consistency）、可用性（Availability）和分区容错性（Partition tolerance）这三项中的两项。

Google Spanner 数据库首先要保证的其实是分区容错性，这是“全球数据库”的基本要求，也最影响他们赚钱；然后是一致性，“强一致”是核心设计目标，也是 Spanner 的核心价值；谷歌放弃的是可用性(A)，只有 majority available。

除此之外，为了“外部一致性”，即客户端看到的全局强一致性，谷歌为每一个事务增加了 2 倍的时钟延迟，换句话说就是增加了写操作的返回时间，这就是分布式系统的代价：目前平均 TrueTime 的延迟为 3.5ms，所以对 Spanner 的每一次写操作都需要增加 7ms 的等待时间。

#### Spanner 一致性的根本来源

大家应该都发现了，其实 Spanner 是通过给 Paxos 分布式共识算法加了一个“本地外挂” TrueTime 实现的海量数据的分布式管理，它实现全局强一致性的根本来源是`Paxos`和`TrueTime`。而在普通单机房部署的分布式系统中，不需要 GPS 授时和原子钟，直接搞一个时间同步服务就行。

### NewSQL 时代

Google Spanner 的推出代表着一个新时代到来了：基于分布式技术的 SQL 兼容数据库（NewSQL），而兼容到什么地步就看各家的水平了。

NewSQL 最大的特点就是使用非 B 树磁盘存储结构（一般为 LSM-Tree），在上面构筑一个兼容 SQL 常用语句和事务的兼容层，这样既可以享受大规模 LSM-Tree 集群带来的扩展性和高性能，也可以尽量少改动现有应用代码和开发习惯，把悲伤留给自己了属于是。

目前比较常见的 NewSQL 有 ClustrixDB、NuoDB、VoltDB，国内的 TiDB 和 OceanBase 也属于 NewSQL，但它们俩有本质区别，下一章我们会详细讨论。

在 NewSQL 时代之后，随着云计算的兴起，云上数据库突然成为了市场的宠儿，市场占有率迅速上涨。它们其实都是对 MySQL 的改造，并不属于 NewSQL 范畴，下面我们认识一下它们。
