Skip to content

NewSQL 数据库

NewSQL 是一类新型的分布式关系数据库,旨在同时提供 SQL 的易用性、ACID 的事务保证和 NoSQL 的可扩展性。代表性产品包括 Google Spanner、TiDB、CockroachDB。

Spanner

全球分布式数据库

Spanner 是 Google 开发的全球分布式数据库,部署在 Google 的全球基础设施上。它提供了外部一致性,这是比 Serializable 更强的一致性保证,保证事务的时间戳顺序与实际发生顺序一致。

Spanner 的核心创新是 TrueTime API,它通过原子钟和 GPS 提供时间戳的误差界限。TrueTime 返回的是一个时间区间 [earliest, latest],而不是精确的时间点。事务提交时等待时间区间的左边界前进到提交时间戳之后,从而保证外部一致性。

数据模型

Spanner 的数据模型是层次化的,由数据库、实例、表组成。表支持主键和二级索引,数据按主键范围自动分片。分片称为"目录",目录是连续的键范围,是数据移动和复制的单位。

Spanner 支持父子表关系,父表和子表交错存储,即子表的数据与其父表的数据存储在同一分片。这种设计保证了父子表的关联查询不需要跨分片,提高了查询性能。例如用户和用户的订单,可以作为父子表交错存储。

复制与一致性

Spanner 使用 Paxos 协议实现数据复制,每个数据分片有多副本,分布在不同的数据中心甚至不同的地区。副本分为leader 和 follower,leader 处理读写请求,follower 只处理读请求。如果 leader 故障,通过 Paxos 选举新 leader。

Spanner 支持两种读一致性:强一致性读和弱一致性读。强一致性读由 leader 处理,保证读到最新提交的数据。弱一致性读由 follower 处理,可能读到过期数据,但延迟低。通过配置读选项,业务可以根据需求选择一致性级别。

分布式事务

Spanner 的分布式事务基于两阶段提交和 Paxos。协调者选择一个时间戳,发送 prepare 请求给所有参与分片的 leader。leader 执行事务并写入准备记录,响应准备完成。协调者收集所有分片的准备完成响应,选择一个大于所有准备时间戳且在 TrueTime 误差之外的时间戳作为提交时间戳,发送 commit 请求给所有分片。

这种设计保证了外部一致性:事务的提交时间戳晚于事务中所有读操作的时间戳,早于后续事务的时间戳。外部一致性保证了分布式事务的可串行化,且顺序与实际发生顺序一致。

TiDB

架构设计

TiDB 是 PingCAP 开源的新一代分布式关系数据库,架构分为三层:SQL 层、分布式事务层、分布式存储层。SQL 层由 TiDB 节点组成,负责 SQL 解析、优化、执行,无状态可水平扩展。分布式事务层由 PD(Placement Driver)组成,负责元数据管理、调度、事务协调。分布式存储层由 TiKV 节点组成,负责数据存储,支持事务的 KV 存储。

TiDB 兼容 MySQL 协议,可以使用 MySQL 客户端连接。支持大部分 MySQL 语法,包括 JOIN、子查询、窗口函数。应用从 MySQL 迁移到 TiDB 通常只需要修改连接地址。

TiKV 存储

TiKV 是基于 RocksDB 的分布式 KV 存储,数据按 Key 范围分片,每个分片称为 Region。Region 默认 96MB,由多个副本组成。通过 Raft 协议保证副本一致性,leader 处理读写请求,follower 同步数据。

TiKV 提供两个关键 API:Put(写入 Key-Value)、Get(读取 Key-Value)。支持单键事务和多键事务,事务通过两阶段提交和 Percolator 协议实现。Percolator 协议将事务状态存储在数据中,通过读取事务状态判断事务的提交或回滚,从而实现分布式事务。

PD 调度

PD 是 TiDB 集群的大脑,负责元数据管理、Region 调度、负载均衡。PD 存储 Region 的位置信息,TiDB 节点查询 PD 找到目标 Region 的 leader。PD 监控集群的健康状态,发现热点 Region、空闲节点、副本不足的情况,自动调度 Region 平衡负载。

PD 提供全局时间戳服务,TiDB 事务开始时从 PD 获取一个时间戳作为事务 ID,事务提交时获取一个更大的时间戳作为提交时间戳。这种设计实现了 SI(Snapshot Isolation)隔离级别,保证事务读到的数据是一致的快照。

HTAP 混合负载

TiDB 的特色是 HTAP(Hybrid Transactional/Analytical Processing)能力,同时支持事务处理和分析查询。TiFlash 是 TiDB 的列存引擎,将数据按列存储,适合分析查询。数据通过 Raft Learner 协议从 TiKV 同步到 TiFlash,保证数据一致性。

TiDB 的优化器根据查询特征自动选择行存或列存,事务查询使用 TiKV 的行存,分析查询使用 TiFlash 的列存。这种设计使得 TiDB 可以同时作为 OLTP 和 OLAP 数据库,避免数据同步的复杂性。

CockroachDB

设计理念

CockroachDB 是开源的分布式 SQL 数据库,设计目标是创造一个"生存于软件错误、硬件故障、网络分区"的数据库。名称来自蟑螂,寓意极强的生存能力。CockroachDB 使用 Raft 协议保证数据一致性,支持 ACID 事务、行级锁、外键约束。

CockroachDB 的数据模型与 PostgreSQL 兼容,支持 PostgreSQL 的协议和大部分语法。使用类似 PostgreSQL 的 SQL 语法、数据类型、函数。这使得从 PostgreSQL 迁移到 CockroachDB 相对容易。

时间与事务

CockroachDB 使用 HLC(Hybrid Logical Clock)作为时间戳,HLC 结合了物理时钟和逻辑时钟,保证了分布式环境下的时间顺序。每个节点维护本地的 HLC,节点通信时同步并更新 HLC,保证所有节点的 HLC 单调递增且接近物理时间。

CockroachDB 的默认隔离级别是 Serializable,比大多数数据库的默认级别更高。Serializable 通过" timestamps + 冲突检测"实现:事务开始时获取一个时间戳,读取该时间戳的数据。事务提交时检查是否有并发事务修改了相同数据,如果有则重试事务。这种设计避免了传统数据库使用锁实现 Serializable 的性能问题,但可能导致事务重试。

数据分布

CockroachDB 的数据按主键范围自动分片,每个分片称为 Range。Range 默认 64MB,由 3 或 5 个副本组成。通过 Raft 协议保证副本一致性,Raft 日志存储在 RocksDB 中。Range 的分裂和合并是自动的:Range 超过阈值时分裂为两个 Range,Range 数据迁移后合并到相邻 Range。

CockroachDB 的副本放置策略是分散到不同节点、不同机架、不同地域,保证故障域隔离。默认配置是 3 副本分散到 3 个节点,如果节点分布在不同机架或地域,副本会自动分散到不同故障域。

Schema 变更

CockroachDB 的 Schema 变更是在线的,不阻塞读写。添加列、删除列、修改列类型、创建索引都可以在线执行。CockroachDB 使用" job"系统跟踪 Schema 变更的进度,job 是异步执行的,可以在系统表查看 job 的状态。

索引创建是增量式的,不会一次性锁表,而是分批扫描数据并构建索引。这保证了在创建索引的同时,表可以正常读写。唯一索引的构建会检查已有数据的唯一性,如果发现重复,job 会失败并回滚。

FaunaDB

无服务器数据库

FaunaDB 是无服务器数据库,提供按使用量计费的数据库服务。与传统数据库不同,FaunaDB 不需要规划容量、管理连接、维护备份,这些都是 FaunaDB 平台自动处理的。

FaunaDB 的数据模型是文档导向的,支持关系、索引、用户定义的函数。FaunaDB 的查询语言是 FQL(Fauna Query Language),是一种函数式语言,支持组合和嵌套查询。

一致性与事务

FaunaDB 提供 Calvin 事务协议,这是对传统两阶段提交的改进。Calvin 协议将事务分为确定性排序和执行两个阶段,所有节点对事务的执行顺序达成一致,然后按顺序执行事务。这种设计避免了分布式事务的两阶段阻塞,提高了性能。

FaunaDB 的默认隔离级别是 Serializable,保证事务的可串行化。FaunaDB 支持多区域部署,数据自动复制到多个区域,读写可以路由到就近区域,保证低延迟。

使用场景

OLTP 扩展

NewSQL 的主要场景是 OLTP 系统的水平扩展,当单机数据库无法满足性能或容量需求时,迁移到 NewSQL 可以获得线性扩展能力。典型的应用包括电商、金融、物联网、游戏,这些场景的特点是数据持续增长、并发量高、需要事务保证。

HTAP 混合负载

NewSQL 的 HTAP 能力使得同一数据库可以同时支持事务处理和分析查询,避免了传统架构中需要两套数据库:OLTP 数据库和 OLAP 数据仓。数据从 OLTP 同步到 OLAP 是复杂的,需要处理数据一致性、延迟、Schema 变更。HTAP 简化了架构,数据实时可用,分析查询可以访问最新数据。

多地域部署

NewSQL 的多地域能力使得数据可以自动复制到多个地域,读写就近路由,保证全球用户的低延迟访问。这对于全球化的应用是重要的,例如跨国电商、社交网络、内容分发。传统数据库的多主复制复杂且容易产生冲突,NewSQL 的一致性协议保证了多地域部署的正确性。

迁移考虑

Schema 设计

NewSQL 的 Schema 设计与传统数据库有所不同。首先避免大事务,分布式事务的开销远大于单机事务,应该将大事务拆分为多个小事务。其次避免热点行,分布式数据库的行锁协调成本高,热点行会成为性能瓶颈。最后合理使用索引,NewSQL 的索引维护成本高于单机数据库,应该只创建必要的索引。

数据迁移

数据迁移是迁移到 NewSQL 的重要工作。迁移方式包括全量迁移和增量同步:全量迁移使用工具导出数据,按照新 Schema 转换后导入 NewSQL。增量同步通过 binlog 或 CDC 工具同步迁移过程中的数据变更。数据验证是必要的,迁移后需要对比新旧数据库的数据行数、校验和、采样内容。

应用改造

应用改造是迁移的难点,需要处理以下问题:分布式事务的语义与单机事务不同,需要重试或补偿机制。唯一的约束和索引可能冲突,需要全局唯一 ID 生成策略。查询性能可能不同,需要优化查询和索引。连接池的配置需要调整,NewSQL 的连接管理可能与单机数据库不同。

NewSQL 是数据库发展的重要方向,它提供了 SQL 的易用性和 NoSQL 的可扩展性,同时保持了 ACID 事务。随着技术的成熟和社区的壮大,NewSQL 会成为越来越多应用的默认选择。但 NewSQL 不是万能的,在选择之前需要评估应用的特点、数据规模、团队能力。