【问题标题】:Sharding from application development point of view从应用程序开发的角度分片
【发布时间】:2021-05-04 11:02:00
【问题描述】:

我阅读了很多有关分片的信息,我对此的理解是数据库管理概念。当我了解应用程序端时,让我们举个例子,一个 Spring Boot 微服务,它有巨大的表 orders,它需要在表中使用 shard Key(K1) 进行分片。

假设我决定使用基于范围的分片基于 K1 字段进行分片,并将在我的 MySQL 数据库的多个节点中分片。

现在我有以下问题:

  1. 如何在现有数据中执行此分片。是后台工作吗?
  2. 在我现有的应用程序中需要做哪些更改,因为它当前连接到 MySQL 数据库的第一个实例。在根据我的分片键获取数据时,此应用程序如何确定它需要从哪个实例请求?

【问题讨论】:

  • 我认为这个问题过于宽泛,也有些主观。例如,现有数据的分片是否应该是后台作业取决于您的可用性要求。离线做当然更容易。对于第一个概述,这篇文章似乎是合理的:dzone.com/articles/….

标签: spring-data-jpa spring-data microservices sharding


【解决方案1】:

使用应用程序级分片,您有很多选择,因为您是可以完全控制它的应用程序开发人员/架构师。您可以做很多选择,但例如,这里有一个选项或一个想法可以引导您朝着正确的方向前进:

如何在现有数据中执行此分片。是不是背景 工作?

我猜你的意思是我如何将数据从一个数据库分离或迁移到另一个数据库分片?

  1. 后台工作。是的,有一份后台工作是一种选择。通过此后台作业,您可以将数据从一个 Db-shard 移动到另一个 Db-shard。
  2. 迁移脚本。您还可以在数据库级别(SQL 脚本)编写迁移脚本,将所有数据迁移到其他 Db-shard。

使用这两个选项,您必须考虑系统是否需要一直运行和操作?你能忍受停机时间吗?

  • 如果是,这可能更具挑战性。在迁移过程中,您必须保持正常运行。在非工作时间这样做会有所帮助,逐个键和类似地分块进行。这仍然取决于您的业务。

  • 如果没有,并且您可以有一个停机时间来执行此操作,那么根据密钥将数据分离到适当的分片会容易得多。在这里您不必考虑正在运行的系统和数据中的一些数据不匹配。所以如果你能以某种方式做到这一点,这会容易得多。

在我现有的应用程序中需要做哪些更改 目前它连接到 MySQL db 的第一个实例。取的时候 基于我的分片键的数据这个应用程序如何决定从哪个 instance 需要请求吗?

您必须提供该逻辑。由于它在您的应用程序级别,因此您需要在代码中做出该决定。在您的 DataAccess 级别代码中,您需要知道将查询(或其他 sql 语句)发送到何处:Service-Db-Shard1 或 Service-Db-Shard2。 例如,您可以在 Main Instance1 Db-Shard-1 中创建一个名为 Shards 的表:

分片表

shard_key database_instance
key1 Service-Db-Shard1
key2 Service-Db-Shard2

分片表

此表将包含可以找到每个分片数据的信息。所以根据key2分片的数据可以在Service-Db-Shard2中找到。根据您的架构,您可以将此表放在一个 Main/Master(首选选项,特别是如果您有一些只读副本以支持 Main 实例的停机时间)分片或所有分片(不是首选,因为它会创建重复)。此外,您可以在启动时将此信息缓存在您的微服务缓存中,并重复使用缓存中的值,这样您就不必每次需要在任何其他表上执行 SQL 语句时都读取此表。

这样做的好处是,您可以控制它并随着时间的推移不断发展。例如,在开始时,当您没有太多数据时,将所有密钥分开/传播到 2 个实例(省钱),随着数据的增长,您可以增加实例的数量。示例:

分片表

shard_key database_instance
key1 Service-Db-Shard1
key2 Service-Db-Shard2
key3 Service-Db-Shard1
key4 Service-Db-Shard1
key5 Service-Db-Shard2

一个实例中的多个分片

这样做可以让您选择在同一个实例上拥有多个分片键数据,以节省大量资源的资金。请记住,这不适用于每种键类型。例如,如果您的系统是多客户/租户系统,并且随着租户数量的增长,数据也会增长,那么它可能会很好地工作。通常并非所有租户都有相同数量的数据,因此将它们放在专用实例中并不总是最有效的分片方式。这为您提供了额外的灵活性。

在每个表中保留分片键列

此外,您还想为每个表添加分片键列,以便您可以确定需要将哪些内容移到哪里。当您的数据分布到多个分片(实例)时,您可能仍希望保留此列,因为您可能在同一实例上有多个分片键并且还可以选择进一步迁移(如果需要)。

执行 sql 语句之前

在针对您的数据库的每个 sql 语句之前,您需要从“分片”表中获取实例信息,并且每个 sql 语句到您的“订单”表或任何其他分片表应在其过滤器中包含分片键。

数据访问层

考虑微服务代码中的 DataAccess 层,这是一个很好的例子,为什么 SOLID 原则和 DataAccess 层类/模块的适当松散设计以及适当的设计可以帮助您更轻松地实现类似的东西。如果您的 DataAccess 层代码做得很好,调整几个类以添加额外的步骤以根据键查找实例并在每个查询中包含键会容易得多。

结论

这只是为了给你一个想法,你可以如何解决这个问题。有很多方法可以做到这一点。这在很大程度上取决于您的域、您当前的服务结构、您的数据、它的架构、您的基础架构设置方式以及数据库部署和迁移策略。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多