Understanding Database Sharding

Understanding Database Sharding

Introduction

任何一个应用程序或网站如果获得了显著的增长,最终都需要进行扩展以适应流量的增加。对于数据驱动的应用程序和网站,保证扩展的方式能够确保数据的安全和完整性至关重要。很难预测一个网站或应用程序会变得多么受欢迎或它会保持多久的受欢迎程度,这就是为什么一些组织选择一种数据库架构,使它们能够动态地扩展其数据库。

在这篇概念性文章中,我们将讨论一种数据库架构:分片数据库。近年来,分片技术受到了很多关注,但是许多人并不清楚它是什么以及在哪些情况下对数据库进行分片是有意义的。我们将介绍什么是分片,它的主要优点和缺点,以及一些常见的分片方法。

What is Sharding?

Sharding(分片)是与horizontal partitioning(水平分区)相关的数据库架构模式,它是将一个表的行分成多个不同的表,称为分区的实践。每个分区具有相同的模式和列,但也有完全不同的行。同样,每个分区中保存的数据是独特且独立于其他分区中保存的数据。

Horizontal partitioning(水平分区)与Vertical partitioning(垂直分区)联系起来思考可能会有所帮助。在垂直分区的表中,整列被分离出来并放入新的、不同的表中。一个垂直分区中保存的数据与所有其他分区中的数据是独立的,每个分区都包含不同的行和列。下面的图示说明了一个表如何同时进行水平和垂直分区:

image-20230510150456520

分片涉及将数据分成两个或更多的较小块,称为logical shards(逻辑分片)。然后将逻辑分片分布在不同的数据库节点上,称为physical shards(物理分片),每个物理分片可以保存多个逻辑分片。尽管如此,所有分片中保存的数据共同代表了整个逻辑数据集。

数据库分片体现了[shared-nothing architecture](Shared-nothing architecture - Wikipedia)。这意味着分片是自治的;它们不共享任何相同的数据或计算资源。然而,在某些情况下,将某些表复制到每个分片中作为参考表可能是有意义的。例如,假设有一个应用程序的数据库依赖于固定的重量测量换算率。通过将包含必要换算率数据的表复制到每个分片中,可以帮助确保每个分片中都保存了查询所需的所有数据。

通常,分片是在应用程序级别实现的,这意味着应用程序包括定义要将读写传输到哪个分片的代码。但是,一些数据库管理系统已经内置了分片功能,允许您直接在数据库级别实现分片。

鉴于这个关于分片的总体概述,让我们来看看与这种数据库架构相关的一些优缺点。

Benefits of Sharding

对数据库进行分片的主要优点是,它可以帮助促进horizontal scaling(水平扩展),也称为横向扩展。水平扩展是向现有堆栈添加更多机器以分散负载、允许更多的流量和更快的处理的实践。这通常与Scaling up(垂直扩展)相对比,垂直扩展也称为纵向扩展,它涉及升级现有服务器的硬件,通常是通过增加更多的RAM或CPU来实现。

在单个机器上运行关系型数据库并根据需要升级其计算资源相对简单。但是,无论如何,任何非分布式数据库在存储和计算能力方面都将受到限制,因此具有横向扩展的自由度使您的设置更加灵活。

选择分片数据库架构的另一个原因是为了加快查询响应时间。当您在未分片的数据库上提交查询时,它可能需要在查询的表中搜索每一行,才能找到您要查找的结果集。对于具有大型单体数据库的应用程序,查询可能会变得非常缓慢。通过将一个表分片成多个部分,查询需要搜索的行数更少,它们的结果集也能更快地返回。因此,查询响应时间可以大大缩短。

分片还可以通过减轻故障对应用程序的影响来帮助使应用程序更加可靠。如果您的应用程序或网站依赖于未分片的数据库,故障可能会使整个应用程序不可用。但是,对于分片的数据库,故障可能只会影响单个分片。尽管这可能会使某些用户无法使用应用程序或网站的某些部分,但总体影响仍将比整个数据库崩溃小。

Drawbacks of Sharding

尽管分片数据库可以使扩展更容易,提高性能,但它也可能会带来某些限制。在这里,我们将讨论其中一些限制及其可能的原因,这些原因可能是避免分片的理由。

人们在分片中遇到的第一个困难是适当地实现分片数据库架构的复杂性。如果实现不正确,分片过程可能会导致数据丢失或表损坏。即使实现正确,分片可能会对团队的工作流程产生重大影响。用户必须跨多个分片位置访问和管理数据,而不是从单个入口点访问和管理数据,这可能会对某些团队产生潜在的破坏性影响。

用户在对数据库进行分片后可能遇到的一个问题是,分片最终会变得不平衡。例如,假设您有一个数据库,其中包含两个分片,一个用于姓氏以字母A到M开头的客户,另一个用于以字母N到Z开头的客户。然而,您的应用程序为以字母G开头的客户提供了过多的服务。因此,A-M分片逐渐积累了比N-Z分片更多的数据,导致应用程序在大部分用户中变得缓慢和停滞。A-M分片变成了所谓的数据库热点。在这种情况下,分片数据库的任何优点都被减速和崩溃所抵消。为了实现更均衡的数据分布,需要对数据库进行修复和重新分片。

另一个主要缺点是,一旦数据库被分片,将其恢复到未分片的架构可能会非常困难。在分片之前备份的数据库不包括分区后写入的数据。因此,重建原始的未分片架构需要将新的分区数据与旧的备份合并,或者将分区的数据库转换回单个数据库,这两种方法都会耗时且成本高昂。

最后一个要考虑的缺点是,并非每个数据库引擎都原生支持分片。例如,PostgreSQL不包括自动分片作为功能,尽管手动分片PostgreSQL数据库是可能的。有许多Postgres分支版本包括自动分片功能,但这些版本通常落后于最新的PostgreSQL发布,并且缺少某些其他功能。一些专业的数据库技术,比如MySQL集群或某些数据库即服务产品,如MongoDB Atlas,都包括自动分片作为功能,但这些数据库管理系统的原始版本并不包括自动分片。因此,分片通常需要“自行实现”的方法。这意味着分片的文档或故障排除问题的提示通常很难找到。

当然,这些只是分片之前需要考虑的一些常见问题。根据数据库的用例,可能还存在许多其他潜在的分片缺点。

既然我们已经讨论了一些分片的缺点和优点,那么现在我们将介绍一些用于分片数据库的不同架构。

Sharding Architectures

一旦决定对数据库进行分片,下一步需要确定的是如何进行分片。当运行查询或将传入数据分布到分片表或数据库时,关键是确保它进入正确的分片。否则,可能会导致数据丢失或查询非常缓慢。在本节中,我们将介绍几种常见的分片架构,每种架构都使用略有不同的过程将数据分布到分片中。

Key Based Sharding

基于键的分片,也称为基于哈希的分片,涉及使用从新写入的数据中获取的值(例如客户的ID号码、客户端应用程序的IP地址、邮政编码等),并将其插入哈希函数中以确定数据应该进入哪个分片。哈希函数是一种将数据(例如客户电子邮件)作为输入并输出离散值(称为哈希值)的函数。在分片的情况下,哈希值是用于确定传入数据将存储在哪个分片上的分片ID。整个过程如下所示:

image-20230510153023207

为了确保条目以正确的方式放置在分片中并保持一致,输入哈希函数的值应该都来自同一列。这一列称为shard key(分片键)。简单来说,分片键类似于[primary key],因为两者都是用于为每行建立唯一标识符的列。广义地说,分片键应该是静态的,也就是说,它不应该包含可能随时间改变的值。否则,它会增加更新操作的工作量,并可能降低性能。

虽然基于键的分片是一种相当常见的分片架构,但在尝试动态添加或删除数据库中的其他服务器时,它可能会让事情变得棘手。当您添加服务器时,每个服务器都需要一个相应的哈希值,您现有的许多条目(如果不是全部)都需要重新映射到其新的正确哈希值,然后迁移到适当的服务器。当您开始重新平衡数据时,新的哈希函数和旧的哈希函数都将无效。因此,在迁移过程中,您的服务器将无法写入任何新数据,您的应用程序可能会出现停机时间。

这种策略的主要吸引力在于它可以用于均匀分布数据以防止热点。此外,由于它以算法方式分布数据,因此无需维护所有数据位置的映射,而这是其他策略(如基于范围或目录的分片)所必需的。

Range Based Sharding

基于范围的分片涉及基于给定值的范围对数据进行分片。例如,假设您有一个数据库,用于存储有关零售商目录中所有产品的信息。您可以创建几个不同的分片,并根据每个产品所处的价格范围将其信息分配,如下所示:

image-20230510153659028

基于范围的分片的主要优点是它相对简单易行。每个分片保存不同的数据集,但它们都具有相同的模式和原始数据库。应用程序代码读取数据所属的范围,并将其写入相应的分片中。

此外,基于范围的分片可以更灵活地添加或删除分片,而无需重新映射数据库中的每个条目。但是,它可能更难在分片之间平衡数据,并且如果某些范围在数据中过度表示(即这块数据被客户端访问的次数太多了),则可能会出现热点问题。

另一方面,基于范围的分片并不能保护数据不被不均匀分布,从而导致上述的数据库热点问题。以示例图表为例,即使每个分片保存相等数量的数据,特定产品仍有可能会比其他产品获得更多的关注。它们各自的分片将因此接收到不成比例的读取请求。

Directory Based Sharding

要实现基于目录的分片,必须创建并维护一个lookup table—查找表,使用分片键来跟踪哪个分片持有哪些数据。查找表是一张表,它保存有关特定数据位置的静态信息。下面的图表显示了基于目录的分片的简单示例:

image-20230510154257629

在这里,Delivery Zone列被定义为分片键。来自分片键的数据与各自行应写入的分片一起写入查找表中。这类似于基于范围的分片,但不同之处在于,每个键都与其自己特定的分片相关联,而不是确定分片键数据所属的范围。在分片键的基数较低(即可能值较少)且不适合分片存储键范围的情况下,基于目录的分片是优于基于范围的分片的选择。请注意,它也与基于键的分片不同,因为它不通过哈希函数处理分片键,它只是检查键是否与查找表中的键匹配,以确定数据需要写入的位置。

基于目录的分片的主要吸引力在于其灵活性。基于范围的分片架构限制您指定值的范围,而基于键的分片则限制您使用固定的哈希函数,如前所述,后期更改可能极为困难。另一方面,基于目录的分片允许您使用任何系统或算法来将数据条目分配给分片,并且使用这种方法相对容易动态添加分片。

虽然基于目录的分片是本文介绍的分片方法中最灵活的方法,但在每次查询或写入之前连接到查找表的需要可能会对应用程序的性能产生不利影响。此外,查找表可能成为单点故障:如果它变得损坏或失效,可能会影响写入新数据或访问现有数据的能力。

Should I Shard?

是否应该实现分片数据库架构几乎总是一个争论的问题。有些人认为,对于达到一定规模的数据库,分片是不可避免的结果,而另一些人则认为,由于分片增加的操作复杂性,除非绝对必要,否则应该避免使用它,否则会带来麻烦。

由于这种增加的复杂性,通常只有在处理大量数据时才会执行分片。以下是一些常见情况,其中分片数据库可能会有益:

  • 应用程序数据量增长超过单个数据库节点的存储容量。
  • 对数据库的写入或读取量超过单个节点或其读取副本的处理能力,导致响应时间缓慢或超时。
  • 应用程序所需的网络带宽超过单个数据库节点和任何读取副本可用的带宽,导致响应时间缓慢或超时。

在进行分片之前,您应该尝试耗尽所有其他优化数据库的选项。您可能希望考虑的一些优化包括:

  • 设置远程数据库。如果您使用的是所有组件都驻留在同一服务器上的单片应用程序,您可以通过将其转移到自己的机器上来提高数据库的性能。这不会像分片那样增加太多复杂性,因为数据库的表保持完整。但是,它仍然允许您在基础架构的其余部分之外垂直缩放数据库。
  • 实现缓存。如果您的应用程序的读取性能是导致问题的原因,缓存是可以帮助改善它的一种策略。缓存涉及在内存中临时存储已经被请求的数据,允许您稍后更快地访问它。
  • 创建一个或多个读取副本。另一种可以帮助提高读取性能的策略是将数据从一个数据库服务器(主服务器)复制到一个或多个辅助服务器。随后,每个新写入都先写入主服务器,然后再复制到辅助服务器,而读取仅在辅助服务器上进行。这样分发读写可以避免任何一个机器承担过多的负载,有助于防止减速和崩溃。请注意,创建读取副本涉及更多的计算资源,因此成本更高,这可能对一些人来说是一个重要的限制。
  • 升级到更大的服务器(垂直扩展某个服务器)。在大多数情况下,将数据库服务器升级到具有更多资源的机器所需的工作量比分片要少(用更好、更大的Cache、SSD等等,升级该服务器的硬件)。与创建读取副本一样,具有更多资源的升级服务器很可能会花费更多的钱。因此,只有在确实成为最佳选择时才应进行这种升级。

请记住,如果您的应用程序或网站增长到一定程度,这些策略单独使用将无法改善性能。在这种情况下,分片确实可能是您的最佳选择。

Conclusion

分片可以是一个很好的解决方案,用于水平扩展数据库。然而,它也增加了很多复杂性,并为应用程序创建了更多的潜在故障点。分片对某些人可能是必要的,但创建和维护分片架构所需的时间和资源可能会超过其他人的收益。

通过阅读本概念性文章,您应该对分片的优缺点有更清晰的理解。从现在开始,您可以利用这些见解,更明智地决定是否为您的应用程序选择分片数据库架构。


原文链接:Understanding Database Sharding | DigitalOcean

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值