使用应用程序级分片,您有很多选择,因为您是可以完全控制它的应用程序开发人员/架构师。您可以做很多选择,但例如,这里有一个选项或一个想法可以引导您朝着正确的方向前进:
如何在现有数据中执行此分片。是不是背景
工作?
我猜你的意思是我如何将数据从一个数据库分离或迁移到另一个数据库分片?
-
后台工作。是的,有一份后台工作是一种选择。通过此后台作业,您可以将数据从一个 Db-shard 移动到另一个 Db-shard。
-
迁移脚本。您还可以在数据库级别(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 层代码做得很好,调整几个类以添加额外的步骤以根据键查找实例并在每个查询中包含键会容易得多。
结论
这只是为了给你一个想法,你可以如何解决这个问题。有很多方法可以做到这一点。这在很大程度上取决于您的域、您当前的服务结构、您的数据、它的架构、您的基础架构设置方式以及数据库部署和迁移策略。