贫瘠之地

华北无浪漫,死海扬起帆
多少个夜晚,独自望着天

0%

分片不等于分布式

分片(sharding)是一种将数据和负载分布在几个独立数据库实例中的技术

该方法通过将原始数据集拆分为碎片(shards)来利用水平可伸缩性,然后将其分布在多个数据库实例中

但是,即使动词 distributes 出现在分片的定义中,分片数据库也不是分布式数据库

分片解决方案

每个分片解决方案在其架构中都有一个至关重要的组件

该组件被定义为各种各样的名字,例如:协调者(coordinator)、路由器(router)、代理人(director)

协调者是唯一知道数据分布的组件,它映射客户端的请求到特殊的分片上,接着映射到对应的数据库实例

这就是为什么客户端必须通过协调者路由它们的请求

举一个例子:如果一个客户端希望插入一条数据到 Car 这张表,该请求首先会提交到协调者;协调者会映射该记录的主键(原文中是 primary key,这里应该主要指分表键)到其中一个分片,然后将请求转发给负责该分片的数据库实例

在上述示意图中,首先协调者映射键 121 到分片 10,接着插入数据到持有分片 10,即表 car_10 的数据库实例上

可是产生了一个问题:为什么在分片解决方案中需要一个协调者的角色?答案是显而易见的:分片存储在为单服务器部署设计的数据库实例上

These database instances do not communicate with each other, nor do they support any protocols that would facilitate such communication. Unaware of each other, they exist in their own isolated environments, oblivious to the fact that they are part of a larger system.

这些数据库实例不相互通信,也不支持任何有助于这种通信的协议。它们彼此不知情,存在于自己孤立的环境中,忽略了它们是一个更大系统的一部分这一事实

因此在分片解决方案中协调者是不可或缺的角色;如果你有兴趣深入研究碎片数据库架构,可以考虑探索 CitusData 或 Azure CosmosDB for PostgreSQL、Vitess for MySQL、Oracle 分布式自治数据库和 MongoDB sharded Cluster

分布式数据库

与分片数据库解决方案非常相似,分布式数据库也使用类似的分片技术在数据库节点集群中存储和读取数据

不同的是分布式数据库不依靠协调者组件

分布式数据库建立在一个无共享的体系结构上,该体系结构没有像协调者这样的单一组件,承担着许多决策的负担:

集群中的所有节点都知道彼此,从而知道数据分布;通过直接通信,每个节点都可以将客户端请求路由到适当的分片所有者;此外它们还可以执行和协调多节点事务,当缩放到更多节点时,集群会自动重新平衡和拆分分片;节点维护数据的冗余副本(基于配置的复制因子),即使某些节点出现故障,也可以在不停机的情况下继续操作

所有这些对客户端来说都是透明的,客户端只需与任何节点建立连接,并允许该节点管理分布式方面

举个例子:一个客户端可能连接到 node1 然后插入了一条 Car 的新数据,id 为 121;如果 node1 是分片的所有者,那么它将在本地存储记录,并且采用一致性算法(consensus algorithm)将变更复制到其他节点的子集;如果不是所有者,node1 会将请求转发给分片的持有者,比如 node4

如果你有兴趣探索真正的分布式数据库的体系结构,可以考虑研究 Google Spanner、YugabyteDB、CockratchDB、Apache Cassandra 或 Apache Ignite

总结

在数据库领域,分片和分发经常被混为一谈,但它们有不同的用途

虽然分片涉及在多个独立实例之间拆分数据,但这并不意味着系统是分布式的;在分片解决方案中存在一个协调者,它将客户端请求引导到适当的分片,这是两者之间显著的区别

另一方面,建立在无共享体系结构上的分布式数据库缺少这种集中式协调者,这些系统中的节点相互了解,管理数据分发,并无缝处理客户端请求

这两种体系结构都有各自的优点,了解它们的细微差别对于明智的数据库设计和选择至关重要

参考

Sharded Does Not Imply Distributed | by Denis Magda | Sep, 2023 | Medium