数据库——NewSQL
NewSQL数据库并非凭空创造,它们建立在过去几十年分布式系统研究的坚实理论基础之上,并通过巧妙的工程实践将其变为现实。与传统数据库的共享存储架构不同,几乎所有NewSQL数据库都采用了架构。在Shared-Nothing架构下,数据被水平切分(分片)并分布到集群的多个节点上。这个数据分片在TiDB/CockroachDB中通常被称为,在YugabyteDB中被称为,在Spanner中被称为。其本
NewSQL核心架构解析
NewSQL数据库并非凭空创造,它们建立在过去几十年分布式系统研究的坚实理论基础之上,并通过巧妙的工程实践将其变为现实。
共享Nothing架构与分布式存储
与传统数据库的共享存储架构不同,几乎所有NewSQL数据库都采用了共享Nothing(Shared-Nothing) 架构。
- 核心思想: 每个节点(服务器)都拥有自己的独立CPU、内存和磁盘。节点之间不共享任何硬件资源,通过网络进行通信和协作。
- 优势:
- 极致的可扩展性: 要增加系统的整体处理能力、内存或存储容量,只需简单地添加新的节点即可。理论上可以实现近乎线性的扩展。
- 高性价比: 可以使用廉价的商用硬件来构建大规模集群,无需昂贵的高端专用存储设备。
- 高可用性: 没有单点的共享存储,单个节点的故障不会导致整个系统瘫痪。
在Shared-Nothing架构下,数据被水平切分(分片)并分布到集群的多个节点上。这个数据分片在TiDB/CockroachDB中通常被称为 Region,在YugabyteDB中被称为 Tablet,在Spanner中被称为 Split。其本质都是将一个大的表数据分成一系列连续的数据范围。
** 如何实现分布式事务?—— 两阶段提交(2PC)与Percolator模型**
这是NewSQL的核心难题之一:如何在多个可能位于不同物理节点上的数据分片上,保证一个事务的ACID特性? industry的标准答案是 两阶段提交(Two-Phase Commit, 2PC)。
2PC引入了一个新的角色——事务协调者(Transaction Coordinator, TC)。其流程如下:
-
第一阶段:提交请求阶段(Prepare Phase)
- 协调者向事务涉及的所有参与者(数据分片节点)发送
Prepare消息,并附上事务内容。 - 每个参与者执行事务操作(写入WAL日志),并锁定相关数据资源。如果成功,则回复
Yes;如果失败(如发生冲突),则回复No。
- 协调者向事务涉及的所有参与者(数据分片节点)发送
-
第二阶段:提交执行阶段(Commit Phase)
- Case 1: 如果所有参与者都回复
Yes,协调者则向所有参与者发送Commit消息。 - Case 2: 如果有任何一个参与者回复
No,协调者则向所有参与者发送Rollback消息。 - 参与者收到
Commit后,正式提交事务,释放锁;收到Rollback后,回滚事务,释放锁。
- Case 1: 如果所有参与者都回复
2PC的缺点:
- 同步阻塞: 在参与者收到
Prepare消息后,必须持有锁并等待协调者的最终指令。在此期间,相关数据被锁定,其他事务会被阻塞。 - 协调者单点问题: 如果协调者在发送
Commit之前宕机,参与者将永远处于“不确定”状态,需要人工干预。
Google Percolator模型的优化:
为了构建网页索引系统而设计的Percolator模型,在2PC基础上进行了巧妙优化,被TiDB等系统采用。其核心是通过一个全局授时服务器(TSO)和数据的多版本来减少协调者的状态管理。
- 包含一个时间戳Oracle (TSO): 为所有事务分配全局唯一且递增的时间戳。
- 在数据行中增加两列隐藏元数据:
Lock: 指向一个初始为空的锁信息(如主键),标识该行是否被锁定。Write: 记录提交时间戳,用于指示哪个版本的数据是已提交的。
- 异步的提交与清理: 即使协调者(在Percolator中某个参与者会扮演类似角色)在Commit阶段宕机,其他事务或后台线程可以通过检查这些元数据来发现并清理悬挂的锁(这个过程称为“锁清理”),从而解决阻塞问题。
Percolator模型将2PC的“状态”存储在了数据本身中,使得系统变得更加鲁棒。
** 如何实现分布式一致性?—— Raft共识算法深度解析**
Shared-Nothing架构通过多副本来保证高可用性:同一份数据(一个Region)会有多个副本(通常为3个),存储在不同的节点上。那么,如何保证这些副本之间的数据一致性呢?答案就是共识算法(Consensus Algorithm)。
Raft 算法因其易于理解和实现的特性,已成为NewSQL领域(TiDB, YugabyteDB, 早期CockroachDB)事实上的标准,取代了更为复杂难懂的Paxos算法。
Raft的核心思想是将一致性问题分解为三个相对独立的子问题:
- Leader选举: 任何一个副本集(Replica Set)中,只能有一个Leader(主节点)负责接收客户端的读写请求。其他节点作为Follower(从节点)同步Leader的数据。如果Leader宕机,Follower们能自动选举出新的Leader。
- 日志复制: Leader将客户端的写操作(如SQL语句)封装成日志条目(Log Entry),并并行地复制到所有Follower节点。只有当超过半数的节点(包括Leader自己)成功持久化该日志后,Leader才认为这个条目是已提交(Committed) 的,并将其应用(apply)到本地的状态机(即实际的存储引擎)中,并回复客户端成功。随后通知Follower应用该日志。
- 安全性: 确保任何任期(Term)内只有一台机器能成为Leader,并且Leader的日志条目不会被覆盖。
Raft的优势与在NewSQL中的应用:
- 强一致性保证: 所有已提交的写操作在多数派节点上都有持久化日志,即使Leader立刻宕机,新选举出的Leader也一定拥有所有已提交的日志,保证了数据不丢失。
- 高可用性: 只要超过半数的节点存活且能相互通信,集群就能正常提供服务。对于3副本的配置,可以容忍1个节点故障。
- Multi-Raft: 一个NewSQL集群中有成千上万个Region,每个Region都有自己的一个Raft组(通常3副本)。整个集群的数据一致性通过成千上万个独立的Raft组来共同维护,这使得大规模水平扩展成为可能。
与Paxos的对比:
Paxos更通用,但协议复杂,工程实现难度大。Raft设计了明确的Leader角色和清晰的逻辑分解,大大降低了工程实现的复杂度,同时提供了与Paxos等效的一致性保证。Google Spanner使用的是其改进的Paxos版本。
** 高可用与容灾机制:多副本、自动故障转移、Region与Zone的设计**
基于Raft,NewSQL的高可用机制变得非常自动化:
-
多副本: 数据默认多副本(通常为3)存储在不同节点、机架甚至机房,防止单点硬件故障导致数据丢失。
-
自动故障转移(Failover):
- Follower故障: Leader和健康的Follower会继续维持日志复制,只是副本数暂时减少。故障节点恢复后会自动从Leader同步数据,追赶进度。
- Leader故障: 剩余的Follower会检测到心跳超时,随即发起新一轮Leader选举。选举成功后,新Leader开始提供服务。整个过程对应用完全透明,应用端驱动可能会遇到短暂的连接错误或超时,但重试后会自动连接到新的Leader。
-
Region与Zone(可用区)的设计:
- 为了应对更高级别的故障(如整个机房断电),NewSQL引入了Zone或Availability Zone (AZ) 的概念。
- 管理员可以配置数据的放置策略(Placement Policy),例如:“将一个Raft组的3个副本分别部署在Zone A, Zone B, Zone C三个不同的可用区”。
- 这样,即使整个Zone A宕机,位于Zone B和Zone C的副本仍然能形成多数派(2/3),选举出新的Leader并继续提供服务,实现机房级容灾。
SQL层与存储层的分离与协作
现代NewSQL数据库普遍采用计算与存储分离(Compute-Storage Separation) 的架构,这使其更具弹性和云原生特性。
-
SQL层(计算层, TiDB-Server/CRDB-SQL-Gateway):
- 无状态: 负责接收客户端连接、解析SQL、优化查询、生成分布式执行计划。
- 弹性伸缩: 由于无状态,可以轻易地根据业务负载动态增加或减少SQL层的实例数量,专门应对复杂的计算型查询或高并发连接。
-
存储层(TiKV/CRDB-Store):
- 有状态: 负责数据的持久化存储、Raft复制、事务处理。
- 弹性伸缩: 存储节点可以根据数据容量和IOPS需求独立进行扩容。
-
协作方式:
- 客户端连接至任意一个SQL层节点。
- SQL层节点解析SQL,将查询转换为一个分布式的执行计划(例如,需要从哪些Region获取数据)。
- SQL层与存储层交互,通过RPC(远程过程调用) 从各个存储节点获取所需数据。
- SQL层在内存中对数据进行聚合、排序、Join等最终计算,将结果返回给客户端。
这种分离架构使得计算资源和存储资源可以独立扩展,资源利用率更高,是云数据库的理想架构。
小结:
NewSQL并非魔法,而是建立在坚实的分布式系统理论(2PC, Raft)和精巧的工程实践(Shared-Nothing, 计算存储分离)之上。它通过将分布式数据管理的复杂性封装在数据库内核中,对外隐藏了分片、副本同步、故障转移等细节,从而为我们提供了一个既具备SQL易用性和强一致性,又拥有NoSQL水平扩展能力的统一数据平台。
更多推荐
所有评论(0)