20. 分片或数据分块

数据分块(也称分区)是一种将大数据库拆分成多个较小部分的技术。数据分块的过程将数据库/表格拆分到多台机器中,以提升应用的可管理型、性能、可用性和负载均衡。数据分片的正当理由是,在某个特定尺度点,通过增加更多机器的水平扩展的成本低于通过增加更庞大的服务器的垂直扩展。

1. 分块方法

有多种不同的方案可以用于决定如何将一个应用数据库拆分进多个较小的数据库中。以下是最流行的方案中的三种方案,被很多大型应用使用。

a. 水平分块:该方案中,我们将不同行存入不同表格中。例如,如果我们将不同的地点存入一张表格,我们可以决定邮政编码小于 10000 的地点存入一张表格,邮政编码大于 10000 的地点存入另一张单独的表格。这也称为基于范围的分片,因为我们将不同范围的数据存入单独的表格。

该方案的主要问题是,如果用于分片的值选取不合适,划分方案将导致服务器不均衡。在上一个例子中,将地点基于邮政编码分片假设地点在不同邮政编码中均匀分布。这个假设不成立,因为像曼哈顿这样人口密集的区域比其郊区城市会有更多的地点。

b. 垂直分块:该方案中,我们将数据根据特定方面的特征存入各台服务器的表格中。例如,如果我们创建类 Instagram 应用,我们需要存储关于用户的数据、用户上传的照片以及关注的用户,我们可以决定将用户档案信息存入一台数据库服务器,朋友列表存入第二台服务器,照片存入第三台服务器。

垂直分块的实现简单,对应用的影响很小。该方案的主要问题是如果我们的应用有增长,则可能有必要进一步将一个特定特征的数据库在不同服务器中分块(例如,单台服务器处理 1.4 亿用户的 100 亿张照片的所有元数据查询是不可能的)。

c. 基于目录分块:为了应对上述方案中的问题,一个松耦合的方案是创建一个查询服务,该服务知道当前的分块方案并将其从数据库访问码抽象出来。因此,为了找到特定数据记录的存放地点,我们查询存储元组关键字和数据库服务器映射关系的目录服务器。这个松耦合的方案意味着我们可以执行像在数据库池中增加服务器的任务或者在不影响应用的情况下改变分块方案。

2. 分块标准

a. 基于关键字或哈希的分块:该方案中,我们将存储的实体的一些关键属性传入哈希函数计算哈希值,得到分块编号。例如,假设我们有 100 台数据库服务器,我们的 ID 是数值,每次插入新记录时 ID 加一。在这个例子中,哈希函数可以是 ID % 100,该哈希函数将提供存储/读取记录的服务器编号。该方法应该确保服务器之间的数据均匀分布。这个方法的根本问题在于它固定了数据库服务器的总数,因为添加新的服务器意味着修改哈希函数,这要求数据重新分布和服务的停机。这个问题的一个应变方法是使用一致性哈希。

b. 列表分块:该方案中,每个分块被赋予一个值的列表,因此任何时候当我们像插入新记录时,我们将看到每个分块包含我们的关键字,然后将记录存入该分块中。例如,我们可以决定所有住在挪威、瑞典、芬兰和丹麦的用户将被存入北欧国家的分块。

c. 轮询调度分块:这是一个非常简单的策略,可以确保数据的均匀分布。当有 n 个分块时,第 i 个元组被分到的分块编号是 i mod n。

d. 复合分块:该方案中,我们将上述任意分块方案组合以发明一个新的方案。例如,首先应用列表分块方案,然后应用基于哈希的分块。一致性哈希可以被认为是哈希和列表分块的复合,哈希将关键字空间减少到可以存入列表的大小。

3. 分片的常见问题

分片的数据库中有一些关于可以执行的不同操作的额外约束。大多数约束的产生是因为跨越多张表格或同一张表格中的多行的操作不再是在同一台服务器上运行。以下是分片引入的一些约束和额外的复杂性:

a. 合并和反规范化:对于在一台服务器上运行的数据库执行合并操作是直接的,但是一旦数据库被分块并分散到多台机器上,对跨越数据库分片的各部分执行合并操作通常是不可行的。这样的合并性能不会高,因为数据必须从多台服务器上编译。这个问题的一个常见应变方法是将数据库反规范化,使得之前要求联合才能执行的查询语句可以在单独的表格中执行。当然,现在服务必须处理反规范化造成的一切危险,例如数据不一致。

b. 引用完整性:如我们看到的,对分块的数据库执行跨片区的查询是不可行的。类似地,试图在分片数据库中强迫满足数据完整性约束,例如外键,是非常困难的。

大多数关系型数据库管理系统不支持跨越不同数据库服务器的数据库中的外键约束。这意味着如果应用要求分片数据库的引用完整性,则必须在应用代码中强迫满足这一点。通常,在这种情况下,应用必须定期运行 SQL 任务,清理悬挂引用。

c. 重新平衡:可能有很多原因导致我们必须改变分片方案:

  1. 数据分布是不均匀的,例如特定邮政编码有大量地点,无法存入一个数据库分块。

  2. 一个分片中有大量负载,例如负责用户照片的数据库分片需要处理过多的请求。

这样的情况下,我们或者必须创建更多的数据库分片,或者对已有的分片重新平衡,这意味着分块方案改变,所有存在的数据移动到新地点。在不导致停机的情况下做这件事情是极其困难的。使用一个像基于目录分块的方案确实可以使重新平衡的体验更可接收,其代价是增加系统的复杂度并创建新的单点故障(即查询服务/数据库)。

Last updated