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 不是万能的,在选择之前需要评估应用的特点、数据规模、团队能力。