Data Partitioning 资料分区是什么? – 系统设计10

system-design-系统设计10-资料复制-data-partitioning-introductoin-to-database-fundamentals-hogantech

序言

此篇 Data Replication 如何优化资料库? - 系统设计09 讲解了资料库复制的重要性,我们可以透过资料库复制的技巧,优化资料库。资料分区(Data Partitioning)则是另一个优化资料库很重要的概念,这一篇也会深入讲解资料库分区,并且分别讲解不同的分片方式(Database Sharding)。此篇文章的中文名称,包含资料分区、资料库分片,目前都是参照Azure 官方文件的翻译,不过还是建议读者使用原文称呼这些名词。

资料分区(Data Partitioning) 是什么?

资料分区(Data Partitioning) 是将资料库中的资料分割成更小、更易于管理的子区块的过程。这些子区块称为分区(Partition)。资料分割可以根据多种因素进行,例如:时间、客户ID 或产品类别。

为何我们要进行资料分区呢?

对于任何不对扩增的系统,资料量也会持续增长,并且针对资料库的读写流量也会越来越大,给传统资料库带来了可扩展性压力,因此我们可以使用资料分割,使我们能够使用多个节点,每个节点管理整个资料的一部分。

资料分区优点

  • 提高性能:通过将资料分割成较小的部分,可以更轻松查询资料。这对于处理大量资料的系统尤很有帮助。
  • 提高可扩展性:随着资料量的增加,可以轻松地添加更多分区来储存新资料,这可以让资料库可以持续扩展,而无需进行重大更改。
  • 提高可用性:如果一个分区发生故障,则只有该分区中的资料会受到影响。其他分区仍可以继续使用,这有助于降低系统的整体停机时间。
  • 简化管理:资料分区可以简化资料库的管理。例如:可以对每个分区单独备份和恢复,并且可以针对每个分区优化查询。

资料分区缺点

  • 增加复杂性:资料分区会增加资料库的复杂性。需要开发和维护分割策略,并且系统可能需要进行一些更改用来适应分割的资料。
  • 增加成本:资料分区可能需要额外的硬体和软体,并且管理分割的资料库的成本可能更高。

分片(Sharding)

为了在多个节点之间分配流量以及负载,我们需要透过分区(Partitioning)或分片(Sharding)来对资料进行分区。我们会将大型资料集合切分成较小的资料块,储存在不同节点上。

不过既然是要进行分割,就是必要让分区平衡,确保每个分区储存大约相同数量的资料。如果分区不平衡,大多数资料库查询落入少数分区,会造成负载过重的分区会不甘负荷,进而会造成系统瓶颈。另外,我们也会称这些乘载量过高的分区节点为热点(Hotspots)。

一般来说,我们会使用以下两种方式进行分片:垂直分片、水平分片

system-design-系统设计10-资料复制-data-partitioning-introductoin-to-database-fundamentals-hogantech-hoganblab00
Digital Ocean - What is Sharding?

垂直分片(Vertical Sharding)

垂直分片(Vertical Sharding)是将不同的表格放在不同的资料库,这个方法可能运行在不同的伺服器上。这边我先提供其他官方文件的图例,让使用者可以更加明白其中的原理。

通常,垂直分片(Vertical Sharding)用来提高检索速度,例如:Blob 所组成的表(未来也会仔细介绍有关Blob 相关内容)。在这种情况下,具有大型文字资料或是Blob 的列,就会被拆分到不同的表中。

垂直分片(Vertical Sharding)适合手动分区,主要是因为这样的分片方式是相对复杂的,资料库管理者需要透过这些资料关联性,再来决定如何分区资料。相较之下,接下来要介绍的水平分片(Horizontal Sharding),即使在动态条件下也适合自动化。

system-design-系统设计10-资料复制-data-partitioning-introductoin-to-database-fundamentals-hogantech-hoganblab01

水平分片(Horizontal Sharding)

除了前者介绍的垂直分片以外,还有另一种分片方式叫做水平分片(Horizontal Sharding)。如果资料库中,某些表(Table)太庞大并且会影响读取/写入效能的话,水平分片就是一个很好解决此问题的分片方式。

水平分片或分区是透过拆分资料将一张表分成多张表,并且也很好理解,假如有五百行的资料,则可以直接分成两个资料库,并且每一个资料库各有两百五十行。

我也附上图,让读者更了解水平分片的概念,通常我们有以下水平分片的方式,分别是:基于键的分片(Key Based Sharding)、基于范围的分片(Range Based Sharding) 、基于杂凑的分片(Hash Based Sharding),这些中文翻译是我参考腾讯技术文件的翻译,当然正常情况我们都会使用英文作为其称呼。

system-design-系统设计10-资料复制-data-partitioning-introductoin-to-database-fundamentals-hogantech-hoganblab02

基于键的分片(Key Based Sharding)

基于键的分片(Key Based Sharding)是根据资料表中的键栏位将资料分割成多个分区的方法。例如:可以根据客户ID 将客户资料分割成多个分区,这样每个分区都包含特定客户的资料。

优点

使用基于键的分片(Key Based Sharding)方法,好处是查询效率很高,并且很容易实作出来,并且可以精确知道在哪里(哪个节点,哪个分片)寻找特定范围的键。

缺点

如果键的选择不是正确的话,由于流量分布不均匀,某些节点可能必须储存更多资料。简而言之,分片不均匀的可能性较高。

system-design-系统设计10-资料复制-data-partitioning-introductoin-to-database-fundamentals-hogantech-hoganblab03

基于范围的分片(Range Based Sharding)

基于范围的分片(Range Based Sharding)是根据资料表中的某个范围栏位将资料分割成多个分区。例如:可以根据价格将商品资料分割成多个分区,这样每个分区都包含特定商品的资料。

优点

使用基于范围的分片(Range Based Sharding)好处是分片的平衡性较好,我们也可以单纯透过范围来决定要去查找哪一个资料库。

缺点

通常在查询范围较小的资料时,这样的资料分片方式是效率较低的。

system-design-系统设计10-资料复制-data-partitioning-introductoin-to-database-fundamentals-hogantech-hoganblab04

基于杂凑的分片(Hash based sharding)

基于杂凑的分片(Hash based sharding)是根据资料表中的某个栏位的值对其进行杂凑(Hash Function),然后根据杂凑结果将资料分配到不同的分区。

优点

基于杂凑的分片(Hash based sharding)的优点是平衡性非常高,并且查询的效率也相对高。

缺点

可能存在热点问题,也复习一下前面提到的,如果分区不平衡,大多数资料库查询落入少数分区,会造成负载过重的分区会不甘负荷,进而会造成系统瓶颈。另外,我们也会称这些乘载量过高的分区节点为热点(Hotspots)。

system-design-系统设计10-资料复制-data-partitioning-introductoin-to-database-fundamentals-hogantech-hoganblab05

重新平衡分割

当资料库查询负载本身是不平衡的时候,会造成资料库效能不佳,这时候我们需要去深入探究原因才有机会去修正问题,其中这些造成不平衡的原因可能包含:

  1. 资料的分布并不均匀。
  2. 单一分区上的负载过多。
  3. 查询流量增加,我们需要增加更多节点来负担系统流量。

以下是一些可以重新平衡分割的方法:

固定数量分区(Fixed number of partitions)

在这种方法中,一开始我们在设定资料库时,就建立固定的分区数量。正常情况,会建立比节点数量更多的分区,并将这些分区分配给节点。因此,当一个新节点加入系统时,它可以从现有节点中取出一些分区,直到这些分区被均分为止。

当然每个方法都有优、缺点。这种方法的缺点是,当每个分区的大小随着丛集(Cluster)中资料总量增加时,也会随之增长,因为所有分区只包含总资料的一小部分。另外,如果一个分区非常小,就会导致分区的成本过大,因为每个分区都会花费一些成本。如果分区非常大,重新平衡节点以及从节点故障中恢复的成本将会很高。选择正确的分区数量非常重要。

动态分区(Dynamic partitioning)

动态分区(Dynamic partitioning)中,当分区的大小达到设定的值时,原本的分区就会被平均分成两个分区。不同的分区,分配一个节点,最终,负载就会被平均分配。分区的数量会与总资料量动态的去平衡,这是动态分区的优点。

不过,动态分区有一个缺点。在同时进行资料库的读取以及写入时,很难动态重新平衡。读取和写入期间的动态重新平衡是很复杂的,因为读取与写入的资料,在不同节点上移动,如果这时候进行动态平衡,就会导致冲突甚至是延迟。为了确保资料一致性和可用性,就会带来复杂性,从而影响系统效能和可靠性。 MongoDB 就是使用这种动态分区知名的资料库之一。

如果尚不了解一致性、可用性、可靠性的读者,可以参考这一篇文章 软体设计非功能性特性– 系统设计03

请求路由(Request routing)

前面介绍了各种资料分区,不过在资料传进资料库之前,我们需要一个问题:当客户端在发出请求时,系统要如何知道要连接到哪个节点?重新平衡后,分区到节点的分配会改变。如果我们想要读取某个特定的资料库,我们如何知道需要连接哪个IP位址才能读取呢?这个问题也称为服务发现(Service Discovery)。以下是解决此问题的解法:

  1. 允许客户端请求网路中的任何节点。如果该节点不包含所请求的数据,则会将该请求转发到包含相关数据的节点。
  2. 建立一个路由层,将所有请求传送到路由层,再由路由层决定连接哪个节点来满足请求。
  3. 客户端已经拥有与分区相关的资讯以及哪个分区连接到哪个节点。因此,他们可以直接联系包含他们所需资料的节点。

ZooKeeper

如果要追踪分散式系统中,某一些丛集(Cluster)的修改,我们可以使用一些工具,其中一个知名的工具ZooKeeper,就可以做到以上的事情。 ZooKeeper 是Apache 为分散式系统提供的分散式开源协调服务。这个工具也可以,追踪网路中的所有映射(Mapping),每个节点都连接到ZooKeeper 以获取资讯。每当分区发生变化,或新增或删除节点时,ZooKeeper 就会更新并通知路由层有关变更的资讯。 ZooKeeper 被Yelp、RackSpace、Yahoo!、Reddit、Facebook 和Twitter 等公司使用。

结论

资料分区是一种将资料库中的资料分割成更小、更易于管理的子集的技术,可以提高资料库的性能、可扩展性、可用性和可管理性。

当资料库查询负载不平衡时,需要重新平衡分割以提高资料库性能。重新平衡分割的过程通常涉及识别不平衡的分割、制定重新平衡计划和执行重新平衡计划等步骤。

对于目前所有的分散式系统来说,分区已经成为标准,并且也是大部分软体工程师都需要知道的知识之一。也因为系统的资料量不断增加,因此对资料进行分区很有意义,它可以加快写入和读取速度,进一步提高系统的可用性、可扩展性和效能。

相关文章

Data Replication 如何优化资料库? - 系统设计09

资料库基础介绍– 系统设计08

负载平衡器解说– 系统设计07

DNS 是什么?网域名称系统介绍– 系统设计06

系统设计元件介绍Building Block – 系统设计05

Back-of-the-envelope 封底计算– 系统设计04

软体设计非功能性特性– 系统设计03

抽象在系统设计中的应用– 系统设计02

现代系统设计介绍– 系统设计01

引用

MongoDB – Hashed Sharding

DigitalOcean – Understanding Database Sharding

腾讯云– 数据库分片(Database Sharding)详解

zh_CN简体中文